Skip to main content

Token Exchange

The OAuth 2.0 Token Exchange (RFC 8693) is a standardized flow that allows a client to exchange one token for another. This is distinct from the standard OAuth authorization code or client credentials flows and is particularly useful in microservices architectures, token delegation scenarios, and when you need to transform tokens for different contexts.

Token-exchange.svg

Token Exchange enables various token transformation scenarios:

  • Access Token → Access Token: Exchange an access token for another access token with different scopes (downscoping or upscoping)
  • ID Token → Access Token: Exchange an ID token for an access token to access protected resources
  • User Token → Service Token: Transform a user's access token into a service token for backend-to-backend communication
  • Cross-Domain Token Exchange: Exchange tokens between different authorization servers or domains

Understanding Token Exchange vs. Other Flows

It's important to understand that Token Exchange is not a standard OAuth authorization flow like Authorization Code or Client Credentials. Instead, it's a mechanism for transforming existing tokens. Here's how it compares:

FlowPurpose
Authorization CodeEnd-user sign-in + token creation
Client CredentialsService authentication without user
Refresh TokenGet a new access token (same type/scope)
🔄 Token ExchangeConvert existing tokens into new ones

Key Difference: While other flows create tokens from credentials or authorization codes, Token Exchange transforms tokens you already have into different tokens with potentially different scopes, audiences, or types.

When to Use Token Exchange

Token Exchange is ideal for:

  • Microservices Architecture: Services need to exchange tokens to communicate with each other while maintaining user context
  • Token Delegation: Delegating access from one service to another with appropriate scopes
  • Scope Transformation: Downscoping (reducing permissions) or upscoping (requesting additional permissions) tokens
  • Backend-for-Frontend (BFF) Pattern: Exchanging user tokens for service tokens in backend services
  • Cross-Domain Scenarios: Exchanging tokens between different authorization servers or domains
  • Token Refresh Alternatives: When you need a different token type rather than just refreshing the same token

Key Advantages

  • Token Transformation: Convert tokens between different types (access token, ID token, etc.)
  • Scope Management: Adjust token scopes to match specific service requirements
  • Delegation Support: Enable secure token delegation in distributed systems
  • User Context Preservation: Maintain user context when exchanging tokens
  • Flexible Architecture: Support complex microservices and multi-tenant scenarios

How it Works

Before we step into how it works, let's understand some useful parameters.

Parameter NameDescription
grant_typeMust be urn:ietf:params:oauth:grant-type:token-exchange
subject_tokenThe token you want to exchange (e.g., an access token, ID token)
subject_token_typeSpecifies the type of the token being exchanged. Common values: urn:ietf:params:oauth:token-type:access_token, urn:ietf:params:oauth:token-type:id_token
scopeOptional. Defines the desired scopes for the new token. Used for downscoping or upscoping
client_idClient identifier (required in Authorization header or request body)
client_secretClient secret (required in Authorization header or request body)
audienceOptional. Specifies the intended audience for the new token

Step 1: The client application makes a POST request to the token endpoint with the subject_token (the token to be exchanged), subject_token_type, grant_type=urn:ietf:params:oauth:grant-type:token-exchange, and optionally scope and audience.

Step 2: The authorization server validates:

  • The subject_token is valid and active
  • The client credentials (from Authorization header) are valid
  • The requested scopes are allowed for the subject token
  • The client has permission to perform token exchange

Step 3: If validation succeeds, the authorization server issues a new token (typically an access token) with the requested scopes and audience.

Step 4: The client uses the new token to access protected resources with the transformed permissions.

Technical Integration

APIDescriptionLink to API
Token ExchangeExchange one token for another with potentially different scopes or audienceView API

Example Implementation

Here are examples of common Token Exchange scenarios:

Example 1: Access Token → Access Token (Downscoping)

Exchange a user's access token for a new access token with reduced scopes:

POST https://{{base_url}}/token-srv/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {{base64_encoded_client_credentials}}

grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token={{user_access_token}}
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&scope=read:data
&audience=api-backend-service

Response:

{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read:data",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
}

Example 2: ID Token → Access Token

Exchange an ID token for an access token:

POST https://{{base_url}}/token-srv/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {{base64_encoded_client_credentials}}

grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token={{id_token}}
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
&scope=api:read api:write

Example 3: User Token → Service Token

Transform a user's access token into a service token for backend communication:

POST https://{{base_url}}/token-srv/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {{base64_encoded_service_client_credentials}}

grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token={{user_access_token}}
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&scope=service:internal
&audience=internal-api-service

Base64 Encoding Example

To create the Authorization header, Base64-encode client_id:client_secret:

# Example: client_id="my-client-id", client_secret="my-client-secret"
# Encoded: bXktY2xpZW50LWlkOm15LWNsaWVudC1zZWNyZXQ=

Authorization: Basic bXktY2xpZW50LWlkOm15LWNsaWVudC1zZWNyZXQ=

JavaScript Example:

const credentials = btoa(`${client_id}:${client_secret}`);
const authHeader = `Basic ${credentials}`;

Security Considerations

Security Note

Important: Token Exchange should only be performed by confidential clients (server-side applications) that can securely store the client_secret. Never perform token exchange from client-side code.

1. Confidential Client Requirement

  • Only confidential clients (server-side applications) should perform token exchanges
  • Ensure the client_secret is securely stored and never exposed
  • Use environment variables or secret management systems

2. Authorization Header Security

  • The Authorization header must include valid credentials (Base64-encoded client ID and secret)
  • If credentials are compromised, attackers can perform malicious token exchanges, leading to privilege escalation
  • Always use HTTPS/TLS for all token exchange requests

3. Scope Restriction (Principle of Least Privilege)

  • Minimize the scope of the newly issued token to the least privilege required
  • Use downscoping to reduce permissions when possible
  • Avoid upscoping unless absolutely necessary and authorized

4. Subject Token Validation

  • The Authorization Server validates the subject_token to ensure it is still active
  • The server verifies the token was issued to the correct client
  • Expired or revoked tokens cannot be exchanged

5. Token Lifetime Management

  • Use short lifetimes for exchanged tokens to limit exposure
  • Ensure exchanged tokens are only active for the required backend service "session"
  • Implement proper token caching and expiration handling

6. Audit and Monitoring

  • Log all token exchange requests for security auditing
  • Monitor for unusual patterns (e.g., frequent exchanges, unexpected scope requests)
  • Alert on failed exchange attempts or privilege escalation attempts

Common Use Cases

Use Case 1: Microservices Token Delegation

A frontend service receives a user's access token and needs to call a backend microservice. The frontend exchanges the user token for a service token with appropriate scopes for the microservice.

Use Case 2: Scope Downscoping

A user grants broad permissions to an application, but the application needs to call a third-party API with limited permissions. The application exchanges the broad-scope token for a narrow-scope token.

Use Case 3: Backend-for-Frontend (BFF) Pattern

A BFF service receives user tokens from the frontend and exchanges them for service tokens to communicate with backend APIs, keeping the user context while using service credentials.

Use Case 4: Cross-Domain Token Exchange

An application needs to access resources in a different domain. It exchanges its current token for a token valid in the target domain.

Comparison with Other Flows

AspectToken ExchangeClient CredentialsAuthorization Code
User Interaction❌ No❌ No✅ Yes
Client Secret✅ Required✅ Required✅ Required
Use CaseToken transformation, delegationM2M, BackendUser authentication
InputExisting tokenClient credentialsUser credentials
OutputNew token (different type/scope)Access tokenAccess token
Best ForMicroservices, token delegationServer-to-serverUser-facing apps

References

Need Support?

Please contact us directly on our support page.