OAuth tokens are a security boundary.
Once an attacker has a valid access token or refresh token, they often don’t need the user’s password, and they can frequently bypass MFA because the token was issued after the sign-in ceremony.
This topic focuses on practical controls: make tokens short-lived, context-aware, and revocable, and have a playbook for when they’re stolen.
Key concepts
- Access token: short-lived credential presented to a resource server (API).
- Refresh token: longer-lived credential used to obtain new access tokens.
- Bearer token risk: if someone possesses it, they can use it (replay).
- Sender-constrained tokens: tokens bound to a client key or channel (DPoP, mTLS), reducing replay.
- Revocation vs expiration: expiration is automatic; revocation is a deliberate “kill switch.”
Core best practices
1) Prefer short-lived access tokens
Short lifetimes reduce the blast radius of theft.
- Typical patterns: 5–15 minutes for browser-based clients; 5–60 minutes for server-to-server.
- The shorter the access token, the more important your refresh strategy becomes.
2) Treat refresh tokens like high-value secrets
From Google’s guidance on compromised OAuth tokens (gcloud), the major risk is persistence: attackers can keep minting new access tokens as long as they have a refresh token (or equivalent long-lived credential).
Practical controls:
- Refresh token rotation (new refresh token each use; revoke the old one).
- Reuse detection (if an old refresh token is used again → revoke the entire token family).
- Store refresh tokens server-side when possible.
- Encrypt at rest and restrict access (logs, debugging tools, support workflows).
3) Make tokens context-aware
Tokens stolen from one environment should be less useful elsewhere.
Examples:
- IP / network controls (enterprise access proxy, service perimeters).
- Device posture and conditional access.
- Sender-constrained tokens (DPoP / mTLS).
4) Use least privilege scopes and narrow audiences
- Keep scopes small.
- Use different OAuth clients for different apps/automation.
- Prefer audience-restricted access tokens (only valid for the intended API).
5) Monitor token usage like you monitor logins
A token is a session.
You should alert on:
- token use from a new geography/IP for a given identity
- unusual API query patterns
- abnormal volume/velocity
- high-risk scopes being exercised
Revocation strategies (what you can actually revoke)
Access tokens
- If access tokens are very short-lived, you often rely on expiration.
- For immediate invalidation, you need either:
- token introspection (API checks token status online), or
- a revocation list / “deny list” checked by your API gateway / auth layer, or
- an ecosystem feature like continuous access evaluation (CAE) (vendor-specific).
Refresh tokens
Refresh tokens are your main “kill switch.”
If you revoke refresh tokens:
- new access tokens stop being issued
- the attacker’s window collapses to the remaining lifetime of any access token they already stole
Connected apps / SaaS-to-SaaS integrations
A real-world example: the Salesforce “Drift” incident involved stolen OAuth tokens issued to a trusted third-party app, letting attackers access Salesforce without triggering MFA.
Implication:
- your attack surface includes every connected app, integration, and non-human identity
- you need governance around who can approve apps, what scopes they can request, and how quickly you can revoke them
Incident response playbook (token theft)
When you suspect OAuth token compromise:
-
Contain
- disable/remove the compromised integration if applicable
- block suspicious IPs / tighten conditional access
-
Revoke
- revoke refresh tokens (or the entire token family)
- revoke sessions where your IdP supports it
-
Rotate / reset
- rotate client secrets / keys (for confidential clients)
- rotate any downstream credentials found in the compromised SaaS (AWS keys, Snowflake creds, etc.)
-
Hunt
- review audit logs for unusual API queries and data exports
- look for evidence of “living off the land” actions using the token
-
Fix the root cause
- reduce token lifetime
- enable rotation/reuse detection
- enforce least privilege scopes
- remove embedded secrets from SaaS records; move to a secrets manager
Common pitfalls
- Thinking “reset password” fixes token theft (it often doesn’t).
- Not having an inventory of connected apps.
- Over-scoped integrations ("read everything") that create huge blast radius.
Where to go next
- JWT validation: /topic/specifications/jwt-and-jose-jws-jwe-jwk-the-token-toolbox
- DPoP / sender-constrained tokens: /topic/specifications/dpop-and-sender-constrained-tokens
- Token exchange (OBO): /topic/specifications/token-exchange-and-on-behalf-of-oauth
