Post

Session Revocation Is a Distributed Containment System

Map access tokens, refresh tokens, application sessions, and queued work into one testable compromise-response boundary.

Session Revocation Is a Distributed Containment System

“Log out every session” sounds like one action. In a modern application it may involve browser cookies, refresh-token families, API access tokens, mobile clients, websocket connections, and queued jobs. An incident runbook that names only the identity provider leaves important paths unexplained.

I would model the compromised identity as a graph of credentials and derived authority. Containment succeeds when the graph can no longer produce protected effects, not merely when one credential disappears from a console.

Separate the revocation mechanisms

An opaque session identifier can be checked against server-side state on every request. A self-contained access token may be accepted until expiration unless resource servers consult an additional revocation boundary. A refresh token can mint new access tokens, so stopping renewal is necessary even when existing access tokens have short lifetimes.

RFC 7009 defines an OAuth token revocation endpoint and discusses propagation considerations. RFC 9700 describes refresh-token protections, including replay detection through rotation or sender constraints in the relevant client context. Neither removes the application’s responsibility to handle its own session and execution state.

For a proposed internal application, I would maintain a user security epoch. Sessions record the epoch at issuance; high-consequence requests compare it with authoritative current state. Incrementing the epoch invalidates older sessions at that enforcement point.

1
2
3
4
5
accept session only if:
  credential validation succeeds
  session is not expired
  issued_security_epoch == current_security_epoch
  current authorization permits the requested action

This is a design sketch, not a token-validation implementation. Caching the current epoch introduces a revocation delay that must be bounded and measured.

Follow authority beyond HTTP requests

A websocket authenticated once can remain active after the browser session is revoked. Decide whether to disconnect it on a revocation event, periodically revalidate it, or authorize each sensitive message. Event delivery alone needs a fallback for missed notifications.

A queued export should recheck whether its requesting identity remains authorized before execution. A previously generated download link may need separate invalidation or a short lifetime enforced at access. Revoking a login does not necessarily revoke a bearer link.

Service credentials and delegated integrations need their own containment paths. Do not assume that changing a human password rotates every API key the user created.

Rehearse the user-visible consequences

I would test containment using synthetic identities across browser, mobile, API, and background paths. The evidence should include the last successful protected action for each path and any authority that remains intentionally valid.

Identity engineering owns credential issuance and renewal. Application teams own session checks and long-lived connections. Incident leadership coordinates the sequence, while support prepares for legitimate users being asked to authenticate again.

The leadership decision is the acceptable residual window for each action class. A public profile read and a privileged data export need not have the same availability tradeoff. Document those distinctions before compromise forces the team to discover them under pressure.

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