Skip to content

Token Refresh

Dick Davis edited this page Jan 23, 2026 · 3 revisions

Token Refresh

Token refresh is the process by which a client provides a valid refresh token in exchange for new access and refresh tokens.

Process

---
title: Token Refresh
---
sequenceDiagram
autonumber

actor Client
participant Authorization Service
participant Data Layer

Client-->>Authorization Service: Calls the token endpoint with grant_type and refresh_token params
Note right of Client: POST /oauth/token
Authorization Service-->Authorization Service: Decodes refresh token
Authorization Service-->>Data Layer: Retrieves OAuth session via refresh token JTI
Authorization Service-->Authorization Service: Validates refresh token and OAuth session status
Authorization Service-->Authorization Service: Generates new access and refresh tokens
Authorization Service-->>Data Layer: Creates new OAuth Session record with token JTI's
Authorization Service-->>Data Layer: Marks previous OAuth session as refreshed
Authorization Service-->>Client: Returns access and refresh tokens to client
Loading

Client

The Client entity represents a client application registered with the OAuth provider.

Authorization Service

The Authorization Service entity represents the component of the application which is responsible for validating the provided refresh token and issuing new access and refresh tokens. This is provided by TokenAuthority.

Data Layer

The Data Layer entity is a relational database used for storing data related to OAuth sessions.

Endpoints

POST /oauth/token

The client calls the POST /oauth/token endpoint to exchange a refresh token for new access and refresh tokens. The endpoint responds with either an error code conforming to RFC-6749 or a JSON object containing the access and refresh tokens.

HTTP Method: POST

URL: /oauth/token

Content-Type: application/x-www-form-urlencoded

Params:

Param Required? Description
grant_type yes The authorization grant type for the token refresh process. Must be refresh_token.
refresh_token yes The valid refresh token corresponding to the OAuth session to be refreshed.
client_id no The client identifier. If not provided, will be resolved from the session.
scope no Space-separated list of scope tokens. Must be a subset of scopes from the original authorization.
resource no Target resource URI(s) for the new access token (RFC 8707). Must be a subset of resources from the original authorization. Can be repeated for multiple resources.

Example Request:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token=eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAvYXBpLyIsImlhdCI6MTY5NTE0MDY1NiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImp0aSI6IjUxMGJhNTdiLTgwNTQtNGQxYi1iYWQ1LTVmZmZjOWE0NzA4ZCIsImV4cCI6MTY5NjM1MDI1Nn0.6-7DgP4UFcA7hEkK7XRob_sRNEGH1QlvalysDJjBrko

Example Request with Scope Downscoping:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token=eyJhbGciOiJIUzI1NiJ9...&
scope=read

Example Request with Resource Indicators (RFC 8707):

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token=eyJhbGciOiJIUzI1NiJ9...&
resource=https://api.example.com/

Example Response:

{
    "access_token": "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAvYXBpLyIsImlhdCI6MTY5NTE0MDY1NiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImp0aSI6Ijc0YjVkZTlkLTQ4YmQtNDFjNC1hMGNiLWZjYzM0OWU3MTY2NyIsInVzZXJfaWQiOjMsImV4cCI6MTY5NTE0MDk1Nn0.aUhztv6x2-foSfp17W_7-mMC-w3HKUx25pMSWHYjzqY",
    "refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAvYXBpLyIsImlhdCI6MTY5NTE0MDY1NiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwLyIsImp0aSI6IjUxMGJhNTdiLTgwNTQtNGQxYi1iYWQ1LTVmZmZjOWE0NzA4ZCIsImV4cCI6MTY5NjM1MDI1Nn0.6-7DgP4UFcA7hEkK7XRob_sRNEGH1QlvalysDJjBrko",
    "token_type": "bearer",
    "expires_in": 300
}

Response Fields:

Field Description
access_token A new JWT access token for authenticating API requests.
refresh_token A new JWT refresh token for obtaining future access tokens.
token_type The token type. Always bearer.
expires_in The number of seconds until the access token expires.
scope Space-separated list of scopes granted (only included if scopes were requested).

Error Response:

{
    "error": "invalid_request"
}

Common error codes:

  • invalid_request - The refresh token is invalid, expired, or the session has been revoked.
  • invalid_scope - The requested scope is invalid or was not granted during the original authorization.
  • invalid_target - The requested resource is invalid or was not granted during the original authorization (RFC 8707).

Scope Downscoping

When refreshing tokens, clients can request a subset of the scopes that were originally granted. This allows obtaining tokens with minimal necessary permissions for each operation:

# Original authorization granted read and write scopes
# At refresh, client only needs read access

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token=eyJhbGciOiJIUzI1NiJ9...&
scope=read

If no scope parameter is provided, the new access token is issued with all scopes from the original authorization.

Note: Clients cannot request scopes that were not included in the original authorization. Attempting to do so returns an invalid_scope error.

Resource Downscoping (RFC 8707)

When refreshing tokens, clients can request a subset of the resources that were originally granted. This allows obtaining tokens with minimal necessary permissions for each operation:

# Original authorization granted access to both APIs
# At refresh, client only needs access to the billing API

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token=eyJhbGciOiJIUzI1NiJ9...&
resource=https://billing.example.com/

If no resource parameter is provided, the new access token is issued for all resources from the original authorization.

Note: Clients cannot request resources that were not included in the original authorization. Attempting to do so returns an invalid_target error.

Session Status

When a refresh token is used, the previous OAuth session is marked as "refreshed" and a new session is created. This ensures that each refresh token can only be used once (refresh token rotation).

If a client attempts to use a refresh token from an already-refreshed or revoked session, the request will be rejected with an invalid_request error.

References

Clone this wiki locally