OAuth Token Rotation Workflow: Secure Refresh, Rotation, and Reuse Detection
By Chris Moen • Published 2026-03-03
A practical guide to designing an OAuth token rotation workflow: short‑lived access tokens, single‑use refresh tokens, reuse detection, atomic updates, safe retries, logging, testing, and rollout. Includes where Breyta fits as the workflow layer around your coding agent.
Quick answer: OAuth token rotation workflow
An OAuth token rotation workflow keeps sessions stable while limiting token risk. Use short-lived access tokens and rotate refresh tokens on every use with single-use semantics and reuse detection.
- Issue short-lived access tokens; treat refresh tokens as single-use.
- Store refresh tokens securely; never log raw tokens.
- Before each API call, check access token expiry; refresh if expired or near expiry.
- Call the token endpoint with grant_type=refresh_token; server returns a new access token and a rotated refresh token.
- Atomically replace stored tokens; immediately invalidate the previous refresh token.
- Track a token family ID and detect reuse; if an old refresh token is used, revoke the family and require re-auth.
- Retry the original request once after a successful refresh; otherwise fall back to re-authorization.
- Log issued/refreshed/revoked events and monitor anomalies.
Refresh vs. rotation: what’s the difference?
Token refresh exchanges a valid refresh token for a new access token without re-prompting credentials. Token rotation issues a new refresh token on each successful refresh and invalidates the previous one. Rotation reduces the blast radius of theft and enables reuse detection.
Designing the OAuth token rotation workflow
Implement a clear sequence and make state changes atomic to avoid race conditions.
- Check access token expiration before protected calls; use a small early-refresh window to prevent concurrent refresh storms.
- Queue or gate concurrent API calls while a refresh is in progress to avoid multiple refreshes.
- POST to the authorization server’s token endpoint with grant_type=refresh_token and the current refresh token.
- On success, the server returns a new access token and a rotated refresh token; store both in one transaction.
- Invalidate or mark the previous refresh token as used; associate tokens with a token family identifier.
- Retry the original API request once with the new access token; if it still fails due to invalid tokens, re-authenticate.
Secure storage and transport
- Encrypt tokens at rest. Use a secure server-side store or device keychain/secure enclave where applicable.
- Use HTTPS/TLS for all token transport; require PKCE for public clients.
- For SPAs, prefer httpOnly, secure cookies or a backend-for-frontend to avoid exposing tokens to front-end JavaScript.
Server-side safeguards
- Return a new refresh token on each refresh; invalidate used refresh tokens immediately.
- Enforce scope constraints, audience checks, and short access token TTLs.
- Support introspection and revocation endpoints to enable quick invalidation.
- Maintain a token family concept and detect reuse to revoke the entire family on anomalies.
Client-side safeguards
- Centralize refresh logic; avoid sprinkling token logic across the app.
- Never embed client secrets in public clients.
- Check expiration early to avoid last-millisecond refresh races.
- Serialize refresh operations so concurrent calls don’t trigger multiple refreshes.
- Update tokens atomically and persist safely; avoid partial writes.
Failure handling and retries
- On invalid_grant or reuse detection: revoke session and require re-auth.
- On invalid_client: halt and alert; investigate configuration/secrets.
- On network errors or token endpoint downtime: exponential backoff with limits and user-friendly errors.
- Retry the original request only once after a successful refresh; do not loop indefinitely on refresh failure.
Scopes and expirations
- Use least-privilege scopes sized to features; avoid broad wildcards.
- Short access token lifetimes (often minutes) balance security and UX.
- Longer-lived refresh tokens with rotation and revocation support reduce re-auth prompts while constraining risk.
- Consider separate OAuth clients per platform or trust boundary.
Logging and monitoring
Log non-sensitive events to detect suspicious activity and aid incident response.
- Issued, refreshed, revoked, and expired events; never log token values.
- Client ID, user ID, token family ID, IP, and coarse-grained user agent.
- Reason for revocation and error codes (e.g., reuse detected, invalid_grant).
- Alerts on unusual refresh rates, reuse attempts, or geography changes.
Testing the workflow end-to-end
- Access token expiry: refresh succeeds; one retry of the original call.
- Rotation: old refresh token fails on next use.
- Reuse detection: using an old refresh token revokes the family and forces re-auth.
- Network failures: token endpoint timeouts/backoff and clear UI messaging.
- Clock skew: early refresh window covers minor discrepancies.
Rolling out rotation safely
- Start with a small cohort; enable refresh token rotation server-side first.
- Track refresh success rate, reuse detection, and re-auth rate.
- Keep a rollback plan and clear support documentation for common errors.
- Train on revocation procedures to accelerate incident response.
Where Breyta fits
Breyta is a workflow and agent orchestration platform for coding agents. It is the workflow layer around the coding agent you already use, built for multi-step automations, long-running jobs, approval-heavy flows, and agent orchestration.
- Deterministic execution with clear run history and versioned flow definitions.
- Explicit approvals and waits where human review is required (for example, before revoking a token family after suspected reuse).
- Reusable templates and an agent-first CLI to build, run, and publish reliable workflows.
- Orchestrate local agents and VM-backed agents over SSH to run rotation jobs where your code and secrets live.
Breyta does not issue or store your OAuth tokens; it orchestrates the code and steps you define for refresh, rotation, logging, approvals, and rollouts, with traceable runs and controlled releases.
FAQ
How short should an access token’s lifetime be?
Keep it short enough to limit risk while maintaining usability. Many teams choose minutes; select a value that fits your API latency, concurrency, and user experience.
Should I store refresh tokens in the browser’s localStorage?
Prefer httpOnly, secure cookies or a backend-for-frontend pattern. Avoid exposing tokens to front-end JavaScript when possible.
Do I need to rotate refresh tokens on mobile apps?
Yes. Rotation helps detect theft and reduces risk on any platform. Use the device keychain or secure storage.
What if my provider does not support refresh token rotation?
Use short refresh token TTLs, frequent re-authorization, and close monitoring. If risk is high, consider a provider that supports rotation and reuse detection.
How do I revoke tokens after suspected compromise?
Call the revocation endpoint for both access and refresh tokens. If you track token families, invalidate the family and force a fresh login.