Revocation & Consistency
Granting access late is an inconvenience. Removing it late is a security incident. When an employee is offboarded, a key leaks, or a role is downgraded, the change must reach every session, token, cache, and service that holds a copy of the old state, within a known and acceptable time.
Where Stale Access Hides
Rendering diagram…
Diagram source
flowchart LR change[Access removed] --> dir[(Directory)] dir -.->|until expiry| tokens[Issued access tokens] dir -.->|until refresh| sessions[Server sessions] dir -.->|until TTL| cache[Decision caches] dir -.->|until sync| replicas[Engine replicas and access sets] dir -.->|until next check| jobs[Queued jobs]
Each copy has its own propagation delay. The effective revocation time is the slowest of them.
Propagation Design
Rendering diagram…
Diagram source
sequenceDiagram autonumber participant D as Directory participant O as Outbox relay participant C as Decision caches participant R as Revocation list participant S as Services D->>D: Remove membership, revoke sessions and refresh tokens D->>O: membership.removed event, same transaction O->>C: Invalidate decisions for the user O->>R: Add active token IDs for the user O->>S: Event delivered at least once Note over S: Tokens still valid by expiry are rejected via the revocation list
Token Verification and Revocation
How services verify credentials decides how quickly revocation can take effect. Verifying every request against a central service makes revocation immediate but puts a network call on the hottest path in the system; verifying signed tokens locally is fast but trusts each token until it expires.
| Verification | Latency | Revocation | Fits when |
|---|---|---|---|
| Signed tokens, verified locally | Microseconds, no network | Takes effect at token expiry | High request volume, many services. |
| Opaque tokens, introspected | A network call per request, unless cached | Immediate | Lower volume, or immediate revocation is mandatory. |
| Signed tokens plus revocation list | Local check plus a small, replicated list | Near immediate for listed tokens | Most products: the common case is fast, critical revocations are prompt. |
Keep access tokens small, carrying identity and organization rather than every permission: large tokens slow every request, and the permissions they carry go stale.
Bounding the Window
| Mechanism | Bounds staleness of |
|---|---|
| Short access token lifetimes (minutes) | Tokens verified locally |
| Refresh token revocation | Continued access after the current token expires |
| Revocation list for critical cases | Tokens that must stop immediately, such as leaked keys or terminated employees |
| Event-driven cache invalidation, with short TTLs as a backstop | Decision caches |
| Consistency tokens from the engine | Replica lag immediately after a change |
The New Enemy Problem
Ordering matters. If Alice removes Bob from a folder and then adds a confidential document to it, a stale replica could evaluate Bob's access against the new document with the old membership. Engines such as SpiceDB and OpenFGA address this with consistency tokens: the write returns a token, and later checks for that resource require state at least that recent.
Watch For
- An unstated window. Agree the maximum revocation delay as an acceptance criterion and test it end to end.
- Revocation without events. Changes made directly in a database or an admin console bypass invalidation. All changes go through the subsystem's interfaces.