Skip to main content

Refresh Token

The Refresh Token grant (RFC 6749 §6) lets a client obtain a new access token without prompting the user to sign in again. The client sends its refresh token to the token endpoint and receives a new access token (and optionally a new refresh token) in return.

Refresh tokens are long-lived credentials and must be treated as such: they replace the user's session. ThunderID supports rotation so refresh tokens themselves can be short-lived in practice.

How It Works

The refresh request goes directly to the token endpoint and returns a new token bundle.

POST /oauth2/token HTTP/1.1
Host: thunderid.example.com
Authorization: Basic <client_id:client_secret>
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=<refresh_token>
&scope=openid%20profile # optional, narrow only
&resource=https://api.example.com # optional, must match the existing audience

Response (rotation enabled):

{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "eyJhbGciOi...",
"scope": "openid profile"
}
How ThunderID Implements It
AspectBehavior
EndpointPOST /oauth2/token with grant_type=refresh_token
Client authenticationSame methods as the original grant, see Client Authentication Methods
RotationControlled globally by oauth.refresh_token.renew_on_grant in deployment.yaml. When enabled, every refresh issues a new refresh_token; when disabled, the existing one is reused
Old token after rotationWhen oauth.refresh_token.revoke_previous_on_renew is enabled, the consumed refresh token is revoked after renewal. A revocation failure stops the rotation
Audience preservationThe new access token keeps the refresh token's single audience when resource is omitted
Resource validationWhen supplied, resource must match the refresh token's audience. A mismatch returns invalid_target
Scope narrowingThe scope parameter may request a subset of the originally granted scopes. Asking for a wider scope returns invalid_scope
DPoP bindingA DPoP-bound refresh token continues to require a DPoP proof on refresh; the new access token inherits the cnf.jkt binding

What Changes Between the Original and Refreshed Token

ClaimBehavior on refresh
subUnchanged
issUnchanged
audPreserved. A supplied resource must match this value
scopePreserved by default; narrowed when scope is supplied
exp / iatNew values
cnf.jkt (DPoP)Preserved
auth_timeNot carried into refreshed tokens

Try It in ThunderID

  1. Open Applications or Agents in the ThunderID Console and select your client.
  2. Open the Advanced Settings tab.
  3. Under Grant Types, add refresh_token alongside a token-issuing grant (authorization_code or urn:openid:params:grant-type:ciba).
  4. Save.

Refresh token rotation is a deployment-wide setting, not per client. Enable it by setting oauth.refresh_token.renew_on_grant: true in deployment.yaml. By default, oauth.refresh_token.revoke_previous_on_renew is true, so a successful rotation revokes the consumed refresh token.

  • Authorization Code, the most common source of refresh tokens
  • Resource Indicators, preserve and validate the resource binding during refresh
  • DPoP, refresh tokens issued under DPoP remain sender-constrained
  • Token Formats, token lifetimes, signing and encryption settings

Explore with AI

ThunderID LogoThunderID Logo

Product

DocsAPIsSDKs
© Copyright Linux Foundation Europe.For web site terms of use, trademark policy and other project policies please see https://linuxfoundation.eu/en/policies.