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.

http
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):

json
{
"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.