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

ObjectRequired decision
OIDC web appUser sign-in, redirect URIs, PKCE, session, issuer, and ID-token validation
AI Agent identityOwner, client authentication, secret rotation, environment, and lifecycle
User accessWhich users can authorize this agent to act on their behalf
Resource connectionWhich custom authorization server and custom scopes the agent can request
Custom scopeSmallest resource permission, such as an explicit read-only operation
Access policyAgent client, grant types, users, context, and denial behavior
Resource APIAudience, 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

  1. Missing or expired user token.
  2. Wrong issuer, audience, signature, or environment.
  3. User outside the agent’s access policy.
  4. Unregistered or disabled agent.
  5. System scope instead of the required custom scope.
  6. Missing JWT-bearer grant in custom authorization-server policy.
  7. Wrong resource audience or resource connection.
  8. Reused, revoked, or expired assertion and access token.
  9. Valid read token used for a write operation.
  10. 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

Source check: August 27, 2026. Recheck prerequisites, endpoints, grant and token types, identity separation, scope rules, policy, errors, client authentication, and production guidance.