Okta Cross App Access: XAA Token Exchange Guide
On this page
Quick answer
Okta documents a two-step XAA flow for a third-party AI agent acting on behalf of an authenticated user:
user signs in through OIDC app
-> user ID token
-> org authorization server token exchange
-> ID-JAG for the agent/resource path
-> custom authorization server JWT-bearer exchange
-> scoped access token
-> protected resource call
The OIDC app and AI Agent are distinct identities. The agent authenticates the two exchange requests, while the user’s ID token supplies the delegated user context.
Configuration prerequisites
| Object | Required decision |
|---|---|
| OIDC web app | User sign-in, redirect URIs, PKCE, session, issuer, and ID-token validation |
| AI Agent identity | Owner, client authentication, secret rotation, environment, and lifecycle |
| User access | Which users can authorize this agent to act on their behalf |
| Resource connection | Which custom authorization server and custom scopes the agent can request |
| Custom scope | Smallest resource permission, such as an explicit read-only operation |
| Access policy | Agent client, grant types, users, context, and denial behavior |
| Resource API | Audience, issuer, signature, expiry, scope, subject, and agent enforcement |
Okta’s current guide includes subscription and administrator prerequisites. Verify them in the live tenant before implementation.
Step 1: ID token to ID-JAG
The trusted exchange component sends the user’s valid ID token as the subject token to the Okta org authorization server. The AI Agent authenticates the request and asks for an ID-JAG, a custom resource scope, and the intended authorization-server audience.
Validate the user’s ID token before exchange: issuer, audience, signature, expiry, nonce or session binding, authentication time, and required claims. Do not accept a token minted for another client or environment.
Okta says system scopes such as openid, profile, and email are not valid resource scopes in this exchange. Use an explicit custom scope tied to the resource connection.
Step 2: ID-JAG to access token
The agent submits the ID-JAG as a JWT-bearer assertion to the custom authorization server and authenticates again. The result is the scoped access token used at the resource API.
The resource must validate the final token rather than trusting the calling agent’s description. Check issuer, audience, signature, expiry, scope, delegated subject, agent identity, and any policy claims required by the operation.
Production separation
Okta notes that a demo may perform user sign-in and both exchanges in one script, while production usually separates the components. Keep the browser or user-facing app away from the agent credential. Put token exchange in a trusted service with secret management, egress controls, rate limits, audit, and redaction.
Never log the full user ID token, ID-JAG, access token, or client secret. Log safe hashes or identifiers, issuer, audience, scopes, policy result, request ID, timing, and outcome.
Denial tests
- Missing or expired user token.
- Wrong issuer, audience, signature, or environment.
- User outside the agent’s access policy.
- Unregistered or disabled agent.
- System scope instead of the required custom scope.
- Missing JWT-bearer grant in custom authorization-server policy.
- Wrong resource audience or resource connection.
- Reused, revoked, or expired assertion and access token.
- Valid read token used for a write operation.
- Secret rotation during an active deployment.
For architecture tradeoffs, read Agent SSO vs API keys and OAuth consent.
Frequently asked questions
What are the two steps in Okta’s third-party XAA token exchange?
Okta documents exchanging the signed-in user’s ID token for an ID-JAG at the org authorization server, then exchanging that ID-JAG for a scoped access token at the custom authorization server.
Are the OIDC web app and AI agent the same Okta identity?
No. Okta’s guide says the OIDC app signs the user in and obtains the ID token, while a distinct AI Agent identity authenticates both token-exchange requests.
Can the XAA flow request openid, profile, or email scopes?
Okta’s third-party guide says system scopes are stripped during the ID-JAG exchange and cause invalid_scope. Configure a custom resource scope such as a bounded read scope.
Should an AI agent client secret appear in a prompt or log?
No. Keep it in an approved secret manager, expose it only to the trusted exchange component, rotate it, redact requests and errors, and never place it in model context or source code.
Official sources
- Okta Developer: Third-party AI Agent token exchange
- Okta Developer: AI agent token exchange
- Okta: Agent SSO general availability
Source check: August 27, 2026. Recheck prerequisites, endpoints, grant and token types, identity separation, scope rules, policy, errors, client authentication, and production guidance.