CYART // SCHEMA · TOKEN-FLOW6 NODES · 6 LINKSVISIT1AUTH CODE + PKCE2CODE → TOKENS3BEARER ACCESS TOKEN4VERIFY SIGREFRESHACTOR · User — browserACTOR01UserbrowserSERVICE · Web app — BFF, httpOnly cookieSERVICE02Web appBFF, httpOnly cookieEDGE · Identity provider — login, MFA, consentEDGE03Identity providerlogin, MFA, consentSERVICE · Resource API — validates JWTSERVICE04Resource APIvalidates JWTDATA · JWKS — public keys, kid rotationDATA05JWKSpublic keys, kid rotationDATA · Refresh store — rotation + reuse detectionDATA06Refresh storerotation + reuse detection

Design a token revocation list

Design revocation for stateless JWTs: when short lifetimes are enough, a deny-list keyed by jti that expires with the token, subject-wide cutoffs for log out everywhere, a Bloom filter front for memory-poor edges with false positives confirmed, versioned snapshots and deltas pushed to edge nodes, and an explicit staleness bound.

● Hard🔒 PRODesign problem·24 min read·Advanced → Staff
JWT revocationjti deny listBloom filtertoken revocationedge distributioneventual consistency

01Understand the problem

✓What you will learn
  • Decide between short-lived tokens and an explicit revocation list, and combine them
  • Keep the deny-list bounded: entries expire with the token's `exp`
  • Revoke a whole subject with an `iat` cutoff instead of listing every token
  • Size a Bloom filter (m = -n ln p / (ln 2)^2, k = (m/n) ln 2) and handle its false positives
  • Distribute with versioned snapshots and deltas, detect gaps and bound staleness
◎Interview radar

What they probe: whether you know a JWT cannot be un-issued, why the list stays small, what a Bloom filter's false positive costs and how you confirm it, how edges learn about revocations and what they do when they stop hearing. Where candidates slip: a deny-list that grows forever, a Bloom filter treated as authoritative, deltas applied out of order, edges that keep accepting silently when updates stop.

A signed JWT (JSON Web Token) is validated locally from its signature and claims, which is why it scales: no database call per request. The cost is that a stolen or logged-out token stays valid until exp. Revocation puts a small amount of state back. The jti claim (RFC 7519) is a unique token id, so the list can name individual tokens.

ApproachRevocation delayPer-request costUse when
Short lifetime only (5 to 15 min) plus refresh tokensUp to the lifetimeNoneRevoking at the next refresh is acceptable
Deny-list by jtiPropagation delay, secondsMap lookupLogout, a stolen token, an admin kill switch
Subject cutoff (iat <= T)Propagation delayMap lookupPassword change, account compromise
Introspection on every request (RFC 7662)ImmediateNetwork callHigh-value operations only
  1. check(token) runs after normal JWT validation and returns ok, revoked or stale.
  2. Entries are dropped once the token's own exp has passed.
  3. Edges apply updates in version order, detect gaps and resync from a snapshot.
  4. An edge that has not heard from the service within maxStaleSec reports stale, and sensitive routes refuse.

This is an advanced module

Problems: replay & revocation components is part of the Pro pass. 4 more sections — the deep dives, the final design, follow-ups and the test — unlock with it.

Already a cyart.io or studio.cyart.io member? Your pass code is in your Studio account.