# Refresh token rotation
## How it works
With rotation on, each refresh request returns a new access token AND a new refresh token; the old refresh token is invalidated immediately. If a rotated-out token is ever used again, Auth0 treats it as token theft: the whole grant (all tokens) is revoked. That is automatic reuse detection.
## Setup
1. Application settings > Refresh Token Rotation: on. Set Reuse Interval if you need a small leeway for concurrent requests (a few seconds), but keep it tight.
2. Absolute Lifetime: the hard cap on the session (e.g. 30 days). Inactivity Lifetime: expiry after idle time (e.g. 7 days). Both count from issuance of the first token in the chain.
3. Request the `offline_access` scope at login or no refresh token is issued at all. For SPAs this means adding it to authorizationParams scope.
## SDK behavior
auth0-react with `useRefreshTokens` handles the swap: it stores the new refresh token and uses it next time. Rules for your own code:
- Always persist the newest refresh token before using it; a crash between use and persist strands the user.
- Serialize refresh calls: two tabs refreshing at once can trigger false reuse detection. A single-flight lock (leader tab or mutex) avoids it. The reuse leeway setting covers small races.
- On `invalid_grant` from the token endpoint, assume the grant is revoked: clear stored tokens and send the user to login. Do not retry the same refresh token.
## When rotation is wrong
Regular web apps with server sessions usually do not need rotating refresh tokens; the server session is the session. M2M apps do not get refresh tokens at all (client_credentials only).
## Checklist
- offline_access requested, rotation on, absolute + inactivity lifetimes set deliberately.
- Reuse detection error path logs the user out cleanly instead of looping.