Token exchange
Strivacity’s Token exchange application client enables clients to, subject to policy restrictions, exchange a valid access token for a new one without requiring the customer to re-authenticate. This functionality is particularly useful in modern identity and API architectures where different services or components require tokens with modified scopes, audiences, or claims.
Capabilities
Token exchange supports the following scenarios:
- Scope changes: Request a new token with a reduced or modified set of scopes.
- Audience changes: Obtain a token targeted at a different resource server.
- Claim mapping: Modify or enrich token claims during exchange.
- Delegation: Use the
act_as
claim to act on behalf of another customer or entity. - Impersonation: Use the
may_act
claim to impersonate another customer, with the appropriate authorization.
The Token Exchange client allows administrators to configure token exchange policies on a per-client basis, enabling precise control over who can exchange tokens, under what conditions, and with what output token characteristics.
This documentation explains how to configure token exchange clients, define policies, and integrate token exchange flows into your applications securely and effectively.
Use cases
- Scope reduction for downstream services: An application receives an access token with broad scopes from Strivacity during customer login. When calling a downstream microservice, it only needs read-only access. Token exchange allows you to narrow that scope to only the needed one when the token is exchanged for a new one. This improves security by minimizing over-scoped tokens shared across internal services.
- Token for audience change between APIs: A frontend app authenticates a customer and receives a token with an audience of api.frontend.strivacity.com. To call a partner API (api.partner.com), it needs a token scoped for that audience. Token exchange enables secure multi-audience access while preventing token misuse across unintended APIs.
- Delegated access with act-as claim: A customer support portal allows support agents to act on behalf of end-users to troubleshoot issues. Token Exchange supports secure delegation patterns with full auditability and separation of roles.
Configuration
-
Start by creating a new application or selecting an existing one under Admin console > Applications > Create application.
-
Create an admin API security policy under Admin console > Policies > API security.
-
Under the application's settings, add a new OIDC client that will use the token exchange mechanism.
-
Assign the admin API security policy to the application.
-
Configure the settings under the OAuth2/OIDC tab.
-
Configure the settings under the Token exchange tab.
-
Save the client.
Configuring the exchange policy
Strivacity allows fine-grained control over token exchange behavior via per-client Token Exchange Policies. Each policy defines what types of exchanges are permitted, what attributes can be modified, and how output tokens are constructed.
Allowed exchange types
This setting determines whether a client is allowed to perform delegation or impersonation exchanges:
- Delegation (
act_as
claim) – The caller acts on behalf of another customer but retains their own identity in the token chain. - Impersonation (
may_act
claim) – The caller fully impersonates another customer, effectively making requests as that customer.
Use case example: Enable only delegation for a customer support app, but restrict impersonation to internal automation tools.
Allowed authorization servers for subject and actor tokens
This policy controls which authorization servers' access tokens will be accepted from and validated against:
- Subject tokens (the original token to be exchanged)
- Actor tokens (used in delegation chains)
For each Authorization Server, the following must be specified:
- Token type: determines what token type is accepted in the request
- Currently, only JWT access token is supported:
urn:ietf:params:oauth:token-type:access\_token
- Currently, only JWT access token is supported:
- Issuer: Authorization server URI.
- JWKS URI: URI used to validate the JWT token against the authorization server.
This ensures that only tokens issued by trusted identity providers (IdPs) are eligible for exchange, and that actor identities are authenticated through approved channels.
Use case example: Accept subject tokens from foo.strivacity.com, but only accept actor tokens from bar.strivacity.com.
Allowed audiences
Defines which aud (audience) values are allowed in the exchanged token. This is critical in audience change scenarios, where tokens are reissued for use with different downstream APIs or services.
Use case example: A frontend app can exchange a token for one with an audience of orders-api.strivacity.com, but not admin-api.strivacity.com.
Allowed resources
Specifies which resource identifiers (resource parameter) are valid targets for exchanged tokens.
This setting acts as an additional constraint for resource-specific access and complements the audience setting. Useful when APIs support multiple logical resource partitions under the same audience.
Use case example: Allow tokens to be scoped only to orders and inventory resources, not billing.
Scope handling
Controls how scopes are applied in the exchanged token:
- Pass through: The scopes from the subject token are reused as is.
- Restricted list: Only a predefined list of scopes is allowed, regardless of what’s in the subject token.
Use case example: A service exchanges a token but is only allowed to request read:users
, even if the original token has broader scopes like write:users
.
Claim mapping – subject token account ID mapping
A dedicated input field allows administrators to specify how to map the subject token to a customer account within Strivacity (or an external identity source).
This is particularly useful in impersonation or delegation scenarios where the customer’s identity must be resolved based on a specific claim or identifier.
Use case example: Map the sub claim from the subject token to a customer’s external ID in Strivacity’s directory.
Claim mapping – custom code block
An advanced field that allows custom logic to map or transform claims in the exchanged token.
This code block can:
- Copy claims from the subject token
- Modify or rename claims
- Fetch additional data from a customer record
- Enrich tokens with values from external APIs or third-party data sources
Example use case:
Use the sub claim from the input token to:
- Look up the customer’s department in your HR system.
- Add department and
manager_id
claims to the output token. - Rename
email_verified
tois_email_verified
.
This capability enables deep integration and tailored token construction for complex enterprise scenarios.
Token Exchange example calls and responses
Scope reduction for downstream services
An application receives a broadly scoped access token from the login flow. Before calling a downstream microservice, it exchanges the token for one with a reduced set of scopes, following the principle of least privilege.
Configuration:
- Allowed exchange: Delegation or impersonation.
- Scopes: Restrict to
read:orders
.
Token exchange request
Original token with read:orders
and read:profile
scopes:
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <client_credentials>
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=eyJhbGciOi...originalToken...
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&scope=read:read:orders read:profile
Response
New token with only read:orders
scope:
{
"access_token": "eyJhbGciOi...reducedScopeToken...",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read:orders"
}
Audience change
A frontend application receives a token scoped for its own API (api.frontend.com). Before calling a partner service (api.partner.com), it exchanges the token for one with a new aud value.
Configuration
- Allowed audiences: api.partner.com
Token exchange request
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <client_credentials>
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=eyJhbGciOi...originalToken...
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&audience=api.partner.com
Response
{
"access_token": "eyJhbGciOi...newAudienceToken...",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": 3600,
}
Decoded JWT payload
{
"sub": "user_123",
"aud": "api.partner.com",
"scope": "",
"iss": "{issuer}",
"iat": 1724487400,
"exp": 1724491000
}
Delegation (act-as)
A support dashboard application allows agents to act on behalf of customers to perform troubleshooting. The agent’s client uses token exchange to produce a delegated token with an act_as
claim representing the customer.
Policy settings
- Allowed exchange type: Delegation.
- Allowed authorization servers: Must accept both subject and actor tokens from trusted issuers.
- Scope handling: May be restricted to limited scopes (e.g.,
support:read
). - Claim mapping: Optional, policies can forward or transform claims from either token.
Token inputs
Subject token (Decoded JWT Payload)
Represents the end user (customer):
{
"sub": "user_123",
"email": "[email protected]",
"tenant_id": "acme",
"iss": "https://login.strivacity.com",
"iat": 1724487600,
"exp": 1724491200
}
Actor Token (Decoded JWT payload)
Represents the support agent:
{
"sub": "support_agent_456",
"email": "[email protected]",
"role": "support",
"iss": "https://login.strivacity.com",
"iat": 1724487650,
"exp": 1724491250
}
Token exchange request
Request includes the JWT subject token and actor token to use in the resulting delegated token.
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <client_credentials>
grant_type=urn:ietf:params:oauth:grant-type:token-exchange&
subject_token=eyJhbGciOi...subjectToken...&
subject_token_type=urn:ietf:params:oauth:token-type:access_token&
actor_token=eyJhbGciOi...actorToken...&
actor_token_type=urn:ietf:params:oauth:token-type:access_token
Response (token exchange output)
Response is a bearer token with an access token in the JWT payload:
{
"access_token": "eyJhbGciOi...delegatedAccessToken...",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": 3600
}
Resulting access token (decoded JWT payload)
The resulting access token includes the support agent’s identifier as the root “sub” claim and the customer's identifier in the “sub” claim under the “act” claim.
{
"sub": "support_agent_456",
"scope": "support:read user:read",
"tenant_id": "acme",
"act": {
"sub": "user_123"
},
"iss": "https://login.strivacity.com",
"iat": 1724487700,
"exp": 1724491300
}
Claim mapping
Claim mapping allows you to modify or enrich the token claims in the resulting token during exchange. The claim mapping code block allows for mapping data into the new token from:
- The original token
- From an identity store
- From a 3rd party data source
Response 200 from claim mapping
Claim mapping code
module.exports = async function ({ request_body, account }) {
return { statusCode: 200, responseBody: {'claims': {
custom: "data"
} } };
};
Content of the token in response
"custom": "data" appears at top level
{
"aud": [
"hodor"
],
"client_id": "d3b7292ee8594f97a255d7c7c0221071",
"custom": "data",
"exp": 1753346210,
"ext": {
"given_name": "2188e297-780e-4ed4-b342-706378def084"
},
"given_name": "2188e297-780e-4ed4-b342-706378def084",
"iat": 1753342610,
"iss": "https://demo.strivacity.cloud/",
"jti": "74873dfa-5c20-4d43-b64e-3e0c9d0117b2",
"may_act": {
"sub": "d3b7292ee8594f97a255d7c7c0221071"
},
"nbf": 1753342610,
"scp": [
"joska"
],
"sub": "2188e297-780e-4ed4-b342-706378def084"
}
Updated about 21 hours ago