Post

Authorization Caches Need a Revocation Budget

Make stale permission decisions measurable with bounded cache lifetimes, policy versions, and explicit outage behavior.

Authorization Caches Need a Revocation Budget

An authorization cache changes the meaning of revocation. Removing a user from a group does not necessarily remove access at that moment; it starts a propagation process. I would make that delay an explicit product and security decision before optimizing policy evaluation.

Imagine a document service that caches an allow decision for five minutes. The membership service has another cache, replicas lag, and a queued export may run later. Saying “access is revoked immediately” is inaccurate unless every path enforces the same boundary.

Define the stale-access envelope

For a proposed design, model a conservative bound as:

1
2
3
stale-access window <= identity propagation bound
                     + decision-cache lifetime
                     + execution recheck interval

This is a design model, not a universal distributed-systems guarantee. It only holds when each term has an enforced upper bound. A cache refreshed from another stale cache can violate the model indefinitely if freshness is reset at every layer.

Carry the original observation time and policy version with the decision. Do not manufacture new freshness when copying it. A cache key might contain:

1
2
(subject_id, tenant_id, action, resource_id,
 membership_version, resource_acl_version, policy_version)

Those versions help only if the evaluator obtains trustworthy current versions. Looking up stale versions from the same unbounded cache does not solve revocation. Use invalidation events to accelerate convergence, with expiration as the backstop; dropped events must not produce permanent grants.

Separate reads from irreversible actions

I would permit a documented short stale interval for a low-sensitivity read only where the business owner accepts it. A privileged export or administrative change should re-evaluate authority at execution time. A queued request is evidence of intent, not a durable permission grant.

Token validation and authorization are separate operations. Correct issuer, audience, and signature checks establish whether a token is acceptable; they do not prove that its subject still has access to a particular document. RFC 8725 supplies the JWT validation baseline; the cache and revocation contract remains an application design decision.

Make outage behavior a reviewed decision

A policy service outage should not silently extend cached grants. Define the maximum age accepted for each action class. When that age expires, reject or defer protected work. A customer-facing error that explains a temporary inability to authorize is preferable to an undocumented expansion of privilege.

Test revocation while a cache node is disconnected, while invalidation messages are duplicated, and while an export waits in a queue. Measure the time of the last successful protected operation after revocation, not merely the time the invalidation event was emitted.

As a technical leader, I would ask product, identity, and service owners to sign off on the same revocation budget. That creates a concrete negotiation: lower latency, greater availability, and faster revocation cannot be traded independently. The team should know which consequence it is accepting and have evidence that the implemented system stays within that agreement.

This post is licensed under CC BY 4.0 by the author.