Why this matters
APIs rely on tokens to decide who can do what. Poor token handling leads to account takeovers, data leaks, and service abuse. As an API Engineer, you will design how tokens are created, validated, rotated, and revoked. Real tasks include setting access token lifetimes, implementing refresh token rotation, rotating signing keys without downtime, and building revocation flows when a token is stolen.
Who this is for
- API/backend engineers implementing authentication and authorization
- Developers integrating OAuth2/OIDC flows and securing microservices
- Security-minded engineers reviewing token lifecycles and incident response
Prerequisites
- Basic HTTP knowledge (headers, status codes, TLS)
- Familiarity with bearer tokens and JWT basics (claims like iss, aud, exp)
- Understanding of API gateways or service-to-service authentication
Concept explained simply
Tokens are temporary passes. An access token gets you into an API for a short time. A refresh token lets you renew your access token. Rotation means replacing a token with a new one regularly or on each use, so stolen tokens expire quickly and misuse is detectable.
Mental model
Imagine a building with turnstiles. Your short-lived ticket opens gates for a few minutes (access token). If you stay longer, you swap for a fresh ticket at a kiosk (refresh token). Each time you swap, the kiosk invalidates the old ticket. If someone tries to use an old ticket after it was swapped, alarms trigger and security revokes the whole pass.
Core patterns and timelines
- Choose token type: JWT (self-contained) or opaque (lookup on server). JWTs verify quickly; opaque tokens enable easy server-side revocation checks.
- Set lifetimes: Access tokens short (5–15 minutes). Refresh tokens longer (days) with rotation on every use.
- Refresh rotation: On token refresh, issue a new refresh token, invalidate the previous, track a token family, and revoke the family on reuse detection.
- Signing key rotation: Use a key ID (kid). Serve overlapping keys for a safe window. Retire old keys after all issued tokens expire.
- Revocation: Maintain server-side state to revoke by user, device, or token family. For JWTs, track jti and/or token families. For opaque tokens, mark the server record revoked.
- Storage & transport: For browsers, keep access tokens in memory and refresh tokens in httpOnly, Secure, SameSite cookies. Never log raw tokens. Transmit via Authorization header.
Key glossary
- jti: unique token identifier
- kid: key identifier used to pick the correct signing key
- aud: intended audience (service) for the token
- nbf: not-before claim (token becomes valid at this time)
- Token family: lineage of a refresh token and its descendants
Worked examples
Example 1: Verifying a JWT access token with key rotation
// Input: Authorization: Bearer <jwt>
// 1) Parse header, read kid
// 2) Fetch public key with same kid from your key set (old and new keys available)
// 3) Verify signature and standard claims (iss, aud, exp, nbf)
// 4) Enforce scopes & roles
// 5) Proceed if valid; else 401 with WWW-Authenticate: error="invalid_token"
Safety: Keep both old and new verification keys available during rotation. Retire the old key after all tokens signed with it have expired.
Example 2: Refresh token rotation with reuse detection
On RefreshRequest(old_refresh_token):
// Look up by hashed token (never store raw)
record = findByHash(hash(old_refresh_token))
if !record or record.revoked: deny and flag risk
if record.used: // indicates reuse
revokeFamily(record.family_id)
deny and notify security
else:
// Single-use semantics
mark record.used = true
issue new_access_token (exp in ~10m)
issue new_refresh_token (new jti, same family_id)
save hash(new_refresh_token), family_id, used=false, parent_jti=record.jti
return new tokens
Outcome: If an attacker tries to reuse an already-used refresh token, the entire family is revoked.
Example 3: Opaque access tokens with introspection
// Gateway or API receives opaque token
lookup = tokenStore.find(hash(token))
if !lookup or lookup.revoked or lookup.expired: 401 invalid_token
else: attach subject, scopes, and proceed
// Revocation sets lookup.revoked = true and takes effect immediately
Opaque tokens are easy to revoke centrally but require a fast token store and caching.
Implementation checklist
- Access tokens expire within 5–15 minutes; include jti, iss, aud, iat, exp
- Refresh tokens rotate on every use; mark old as used
- Token families tracked; reuse triggers family-wide revoke
- Signing keys include kid; overlap keys during rotation
- Do not log raw tokens; log jti or token hash only
- Revocation endpoint supports user, device/session, and family scopes
- For browsers: store refresh in httpOnly, Secure, SameSite cookies; access token in memory
- Return 401 with clear error codes; never leak sensitive details
Exercises
Try these hands-on tasks. Compare your work with the provided solutions in each exercise block.
- Exercise ex1: Design refresh token rotation with reuse detection. Include data model, flow, and error responses.
- Exercise ex2: Draft a signing key rotation plan with zero downtime and an overlap window.
Common mistakes and self-check
- Mistake: Long-lived access tokens. Fix: Keep them short; rely on refresh rotation.
- Mistake: Storing refresh tokens in localStorage. Fix: Use httpOnly, Secure, SameSite cookies for browsers.
- Mistake: No reuse detection. Fix: Mark refresh tokens single-use and track families.
- Mistake: Logging raw tokens. Fix: Log only jti or hashes.
- Mistake: Hard key swaps. Fix: Use kid and overlapping verification keys.
Self-check:
- I can explain the difference between access and refresh tokens in one sentence.
- I know the exact TTLs we will use in our system.
- My refresh flow invalidates the previous token and detects reuse.
- We can revoke by user, device/session, or token family.
- We have a documented key rotation procedure with an overlap window.
Practical projects
- Build a refresh endpoint that rotates tokens and revokes on reuse.
- Add a revocation service that can revoke by jti, family_id, or subject.
- Implement a key rotation job and serve multiple verification keys concurrently.
- Create dashboards for token issuance, refresh success/fail, and reuse alerts.
Learning path
- Start: Token lifecycles and rotation (this lesson)
- Next: Scopes, roles, and authorization decisions
- Then: Secrets and key management (HSM/KMS concepts)
- Advanced: Proof-of-possession tokens and mTLS between services
Next steps
- Finish the exercises and compare with the solutions.
- Run a tabletop incident: simulate a stolen refresh token and walk through detection and revocation.
- Integrate rotation metrics and alerts into your monitoring.
Mini challenge
Your system uses 10-minute access tokens and 14-day refresh tokens. A user reports suspicious activity. Design the exact steps to invalidate existing sessions while minimizing disruption for other users. Include how you will handle token families, user-initiated logout-all, and key rotation if you suspect signing key exposure.
Before you take the Quick Test
The Quick Test is available to everyone for free. Log in to save your progress and see it on your dashboard.