TokenExchangePolicy
TokenExchangePolicy predates the OAuthServer configuration, and is documented for trust domains that already use it. Use OAuthServer for all new configurations. When a trust domain has both, OAuthServer takes precedence, and TokenExchangePolicy is ignored.
The TokenExchangePolicy Managed Configuration section lets workloads exchange users' ID tokens for on-behalf-of tokens. It lists the identity providers whose ID tokens are accepted, and optionally adds claims from those ID tokens to the on-behalf-of tokens it issues. Workloads request on-behalf-of tokens the same way under either configuration.
Example
section: TokenExchangePolicy
schema: v1
spec:
allowlist:
- issuer: https://idp.example.com
audiences:
- web-app
additionalClaims:
email: "{{jwt.claim.email}}"
department: "{{jwt.claim.department}}"
TokenExchangePolicy is a trust domain section. You can apply Managed Configuration through the Defakto API, Terraform, or the Defakto CLI. See applying configuration. For example, with the CLI:
defakto config set trust-domain --id <trust-domain-id> token-exchange-policy.yaml
Without a TokenExchangePolicy or an OAuthServer configuration that accepts users' tokens, every on-behalf-of token request is refused.
allowlist
The identity providers whose ID tokens workloads may exchange. A presented ID token is accepted only when its issuer matches an entry's issuer, and one of its audiences is in the entry's audiences, both compared exactly. A token from an issuer that isn't listed is rejected before its keys are fetched.
| Field | Required | Description | Example |
|---|---|---|---|
issuer | Yes | The identity provider's issuer URL | https://idp.example.com |
audiences | Yes | The audiences that accepted ID tokens may carry, usually your application's client ID | [web-app] |
The token's JWT typ header must be JWT, or absent. A token whose typ names another kind of token, such as an access token (at+jwt), is rejected.
additionalClaims
Claims to add to the on-behalf-of tokens the policy allows, copied from the user's ID token. Each key is the name of the claim to add, and each value is a single reference of the form {{jwt.claim.<name>}}, written with no spaces inside the braces.
- Only string-valued claims can be referenced.
- An added claim's name must match
[a-zA-Z_][a-zA-Z0-9_]*. A referenced claim's name can contain letters, digits, underscores, and hyphens. - An added claim can't use a name that Defakto sets itself:
iss,sub,aud,exp,nbf,iat,jti,obo,txn,auth_time, ornonce. - If the ID token doesn't have a referenced claim, the exchange is refused with
invalid_request, rather than issuing a token without it.
When an on-behalf-of token is re-exchanged, its additional claims are carried forward with the values from the first exchange. Adding an entry to additionalClaims therefore makes on-behalf-of tokens issued before the change fail to re-exchange, because they don't carry the new claim. Expect chains in progress to restart after the change.
Re-exchange
A workload that received an on-behalf-of token can exchange it for a new one whose audience is the next service, as described in Propagate a user's identity. Re-exchange is available whenever a TokenExchangePolicy is configured, and needs no allowlist entry, because the presented token is one your trust domain issued.