Observed
While testing lit-secrets against prod (api.chipotle.litprotocol.com, 2026-08-27):
POST /core/v1/remove_usage_api_key with the master key → 200.
- Immediately after,
POST /core/v1/lit_action with the removed usage key → 200, action executed.
- ~1–2 minutes later the same call → rejected (HTTP 500, unknown key).
Cause (from reading the code)
accounts::remove_usage_api_key correctly calls blockchain_cache::invalidate_for_keys(api_key, usage_api_key) (lit-api-server/src/accounts/mod.rs:424), but blockchain_cache is an in-process moka cache with a per-key generation counter. The bump only happens on the replica that served the management request; every other replica keeps serving the cached can_execute_action / resolve_to_master result until CACHE_TTL_SECS = 300 expires.
Same applies to every mutation that relies on invalidate_for_account (group/action/PKP changes): consistency is per-instance.
Why it matters
For credential-style products (lit-secrets, lit-triggers agent keys) "revoke" is expected to be immediate. A 5-minute window where a leaked/revoked key still executes actions — and can still Decrypt — is a meaningful gap.
Options
- Shorter TTL for positive usage-key → account resolution (e.g. 30s), keep 300s for group/CID permission lookups.
- Cross-replica invalidation: publish bumps via a shared channel (the Apalis/SQLite job queue won't do; needs Redis/NATS or an on-chain event watcher — the contract already emits events for
removeUsageApiKey).
- Cheapest: have the reverse proxy pin management + execution traffic for an API key to one replica (consistent hashing on
X-Api-Key hash). Fixes the common case with no code change.
Also worth noting: the rejection surfaces as HTTP 500 rather than 401/403 (related to #604 structured errors).
Observed
While testing lit-secrets against prod (
api.chipotle.litprotocol.com, 2026-08-27):POST /core/v1/remove_usage_api_keywith the master key → 200.POST /core/v1/lit_actionwith the removed usage key → 200, action executed.Cause (from reading the code)
accounts::remove_usage_api_keycorrectly callsblockchain_cache::invalidate_for_keys(api_key, usage_api_key)(lit-api-server/src/accounts/mod.rs:424), butblockchain_cacheis an in-process moka cache with a per-key generation counter. The bump only happens on the replica that served the management request; every other replica keeps serving the cachedcan_execute_action/resolve_to_masterresult untilCACHE_TTL_SECS = 300expires.Same applies to every mutation that relies on
invalidate_for_account(group/action/PKP changes): consistency is per-instance.Why it matters
For credential-style products (lit-secrets, lit-triggers agent keys) "revoke" is expected to be immediate. A 5-minute window where a leaked/revoked key still executes actions — and can still
Decrypt— is a meaningful gap.Options
removeUsageApiKey).X-Api-Keyhash). Fixes the common case with no code change.Also worth noting: the rejection surfaces as HTTP 500 rather than 401/403 (related to #604 structured errors).