IntegrAuth Academy
Identity, security and practical AI — free, from zero. Byte-sized lessons, real diagrams, hands-on labs, zero fluff. Two programs, each with its own exam and certificate.
English is hard? Your browser can translate this page into Tamil, Telugu, Kannada, Malayalam or Hindi. Tech words stay in English so you learn the real names.
How?
- Chrome on phone: ⋮ menu → Translate
- Chrome on computer: right-click → Translate to …
- Edge: the translate icon in the address bar
Stolen-token defenses I — revoke, expire, step up
You press "sign out everywhere". Your session and refresh tokens die at once. But an access token a thief already copied keeps working until it expires. Your goal: name four server checks that refuse a stolen access token.
- A signed access token works until it expires, even if stolen.
- A revocation marker refuses every token issued before a cut-off time.
- Freshness and method checks refuse old or weak tokens for risky actions.
- The API is the control. The screen is only a convenience.
Why a stolen access token is stubborn
Many access tokens are self-contained JWTs. The API checks the signature and trusts the token without calling the IdP. That is fast. But nobody can take back copies already out there. The thief's copy works until the token's exp (its expiry time). Three credentials matter here. A session cookie lives in the browser. A refresh token makes new access tokens. An access token opens the API on every call. The server can cancel the session and the refresh token at once. It cannot cancel an access token. That one works until exp.
Defense 1: a revocation marker
This is the one defense that truly stops a live stolen token. When you sign out everywhere, the API writes a revocation marker. It is a cut-off time. It means "everything issued before now is dead".
On every call, right after the signature check, the API compares two times. One is the token's iat (issued-at time). The other is the cut-off. If iat is at or before the cut-off, the API refuses the token with token_revoked. A fresh login makes a token after the cut-off. So the gate stays open for the real user and shut for the thief.
A hotel front desk. A guest loses a key card. The desk writes: "Every card made before 9 pm is dead." Every door lock checks this note. A new card made after 9 pm works. The old card does not.
Defenses 2 and 3: shrink the window
⏱️ Freshness gate
A high-value action needs a token made seconds ago. The API checks now − iat. If it is older than the window (say 120 seconds), the API refuses with token_too_old. A copy taken an hour ago fails, even if it has not expired.
🔐 Method check (step-up)
Some actions need a second factor. The API checks that the token shows MFA: the amr claim (the login methods used) includes mfa. This is MFA. If it is missing, the API answers 401 insufficient_user_authentication. The client then asks the user for fresh proof. This is step-up.
Defense 4: "sudo" re-authentication
On a laptop, the command sudo asks for your password again before a risky change. An API can do the same. It refuses tokens that came from a refresh, because no person was there. It also needs auth_time (when the user last signed in) to be recent. This is about when you proved yourself, not how.
"I did MFA earlier" is not the same as "this token shows MFA now". A silent refresh can make a new access token with no new MFA. Never assume. Check the live token. If it is not enough, send the user through a real step-up.
All of these gates live on the server. A thief still holds a working token between calls. The next lesson makes the copy itself useless.
Go deeper: standards behind the gates
The standard way to cancel a token is the revocation endpoint (RFC 7009). It works well for refresh tokens and for opaque tokens. A self-contained JWT needs the extra gates above.
The names token_revoked and token_too_old are examples from this course. They are not standard error codes. A real API picks its own name or answers a plain 401 invalid_token.
The error insufficient_user_authentication comes from RFC 9470. It tells the client that the token does not show the needed method, usually mfa in amr.
🧪 Interactive lab — enable JavaScript to play with this one.
Audit your app's logout and revocation habits with Logout Check.