flip_api.auth.trust_key_cache ============================= .. py:module:: flip_api.auth.trust_key_cache .. autoapi-nested-parse:: In-process TTL cache for trust API-key → trust_id lookups. `authenticate_trust` (auth/access_manager.py) defends against timing oracles by sweeping every hash-bearing trust row with `hmac.compare_digest` on each request. With 30/min `/tasks/pending` plus 30/min `/trust/heartbeat` per trust, that is an O(N) DB walk on every request in steady state — and the sweep duration leaks the trust count to a pre-auth probe. This cache shortens the hot path to a single primary-key fetch + one constant-time compare. Verification still runs against the live row, so a deleted or soft-disabled trust falls through to the full sweep (which filters them out) and returns 401 normally; the cache cannot grant access that the database denies. Invalidation: callers that commit a write to the `trust` table (`register_trust`, soft-disable when wired up, `delete_trust`) should call `invalidate()` after commit. Cross-process eviction is not provided — the 60-second TTL bounds the staleness window across Fargate tasks. The verify-against-the-live-row step is what makes this safe: stale entries cost an extra DB round-trip on the request that races a write, never an authentication bypass. Attributes ---------- .. autoapisummary:: flip_api.auth.trust_key_cache._TTL_SECONDS flip_api.auth.trust_key_cache._lock flip_api.auth.trust_key_cache._cache Functions --------- .. autoapisummary:: flip_api.auth.trust_key_cache.lookup flip_api.auth.trust_key_cache.remember flip_api.auth.trust_key_cache.invalidate Module Contents --------------- .. py:data:: _TTL_SECONDS :value: 60 .. py:data:: _lock .. py:data:: _cache :type: dict[str, tuple[uuid.UUID, float]] .. py:function:: lookup(api_key_hash: str) -> uuid.UUID | None Return the cached trust id for this hash, or None if absent or expired. :param api_key_hash: SHA-256 hex digest of the candidate API key. :type api_key_hash: str :returns: Trust id last seen for this hash, or None. :rtype: UUID | None .. py:function:: remember(api_key_hash: str, trust_id: uuid.UUID) -> None Record that this hash resolved to this trust id; entry lasts for the TTL. :param api_key_hash: SHA-256 hex digest of the API key the request carried. :type api_key_hash: str :param trust_id: Primary key of the matching trust row. :type trust_id: UUID .. py:function:: invalidate() -> None Drop every cache entry. Call after register/disable/delete commits.