Working with Token Revocation

1. Understanding Token Revocation Need

TriggerRequired Action
LogoutInvalidate current token(s)
Password changeAll tokens for user
Account compromiseAll tokens + force re-auth
Permission downgradeAll tokens (claims stale)
Client app removalAll tokens for that client

2. Implementing Token Blacklist

Example: JWT jti blacklist

// On revoke
async function revoke(jwt) {
  const { jti, exp } = decode(jwt);
  const ttl = exp - Math.floor(Date.now()/1000);
  if (ttl > 0) await redis.set(`bl:${jti}`, "1", "EX", ttl);
}

// On every request
async function isRevoked(jti) {
  return Boolean(await redis.exists(`bl:${jti}`));
}

3. Using Redis for Revocation Storage

PatternKeyValue / TTL
Single tokenbl:<jti>1 / token exp
All user tokensuser:<id>:logout_aftertimestamp / max token TTL
Family rotationfam:<id>revoked flag / 30d
Note: The "logout after" pattern checks iat < logout_after — avoids storing every jti.

4. Implementing Token Introspection Endpoint

Example: RFC 7662 introspection response

POST /oauth/introspect
token=eyJhbGc...&token_type_hint=access_token

{
  "active": true,
  "scope": "read write",
  "client_id": "app_123",
  "username": "alice",
  "exp": 1715000000,
  "iat": 1714999100,
  "sub": "user_42",
  "aud": "api://orders",
  "iss": "https://auth.example.com",
  "jti": "abc-123"
}
FieldMeaning
activeOnly required field — false if revoked/expired
AuthEndpoint requires resource server credentials
CachingCache active=true for short window (e.g., 30 sec)

5. Revoking All User Tokens

Example: User-level revocation timestamp

// Bump user's revocation timestamp
user.setTokenRevokedAfter(Instant.now());
userRepo.save(user);

// Validator
if (jwt.getIssuedAt().isBefore(user.getTokenRevokedAfter()))
  throw new InvalidTokenException();

6. Implementing OAuth Token Revocation

AspectRFC 7009
EndpointPOST /oauth/revoke
Bodytoken=...&token_type_hint=refresh_token
AuthClient credentials
Response200 OK (even for unknown tokens — prevents enumeration)
Refresh revokeSHOULD also invalidate associated access tokens

7. Handling Revoked Token Requests

ResponseDetail
Status401 Unauthorized
HeaderWWW-Authenticate: Bearer error="invalid_token", error_description="Token revoked"
BodyMinimal — no leakage of why
ClientTrigger refresh; on refresh failure → re-auth

8. Setting Token Expiration vs Revocation

StrategyProsCons
Short exp onlyStateless, simpleWindow of validity post-revoke
Long exp + blacklistInstant revokeStateful, extra lookup
Hybrid (recommended)Short access + revocable refreshBest of both

9. Implementing Token Status Checking

MethodLatencyFreshness
Local JWT verifyμsStale (until exp)
IntrospectionmsReal-time
Introspection + cacheμs–msConfigurable window
JWT + blacklist checkμs (Redis)Real-time

10. Managing Revocation List Performance

TechniqueBenefit
Bloom filterMemory-efficient probabilistic check
Per-user timestampO(1) check vs scanning jti list
Redis TTLAuto-expiry of revocations
ShardingPartition by user/token hash
Edge cachingPush revocation list to CDN/edge