Rotation, revocation and introspection

OAuth, OIDC & JWT · Advanced · 12 min

Long-lived credentials need a way to be killed quickly when something goes wrong.

Refresh token rotation: each time a refresh token is used, the AS issues a new one and invalidates the old. If an old refresh token is ever presented again, someone has a copy, so the AS revokes the whole token family and forces re-login. RFC 9700 requires public clients' refresh tokens to be either rotated or sender-constrained.

Handle rotation carefully in clients: two tabs or parallel requests refreshing at once can trip reuse detection. Serialize refreshes (one in-flight refresh promise) and many ASes allow a short grace period.

Revocation (RFC 7009): POST /revoke with token=... and token_type_hint=refresh_token. Call it on logout. Revoking a refresh token usually also revokes the access tokens derived from it, but self-contained JWT access tokens remain usable by APIs until exp, which is why access tokens should live minutes, not days.

Introspection (RFC 7662): the API POSTs a token to the AS's introspection endpoint and gets {"active": true, "sub": ..., "scope": ..., "exp": ...}. It gives live revocation status at the cost of a network call per request (cache results for a few seconds). Use it with opaque tokens or for high-risk operations.

Other kill switches: short session lifetimes at the AS, step-up authentication for sensitive actions, and the Shared Signals framework (CAEP) for real-time session revocation events.

Example

# Revoke a refresh token at logout (RFC 7009)
curl -s https://auth.example.com/oauth/revoke \
  -u "web-app:$CLIENT_SECRET" \
  -d token="$REFRESH_TOKEN" \
  -d token_type_hint=refresh_token
# HTTP 200 (also for tokens that were already invalid)

# Introspect an opaque access token from the API (RFC 7662)
curl -s https://auth.example.com/oauth/introspect \
  -u "orders-api:$API_SECRET" \
  -d token="$ACCESS_TOKEN"
# {"active":true,"sub":"user-42","client_id":"web-app",
#  "scope":"orders.read","exp":1760003600}
# revoked or expired -> {"active":false}

Remember

  • Rotation + reuse detection turns a stolen refresh token into a forced logout
  • Revoke refresh tokens at logout; JWT access tokens live until exp
  • Introspection gives live status for opaque tokens

Watch out for

  • Parallel refresh calls in a client triggering reuse detection and logging the user out.

Check yourself

  1. An old, already-rotated refresh token is presented to the AS. What should a rotating AS do?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.rfc-editor.org/rfc/rfc7009