-
Notifications
You must be signed in to change notification settings - Fork 661
Updates for Token Exchange #6047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
3064a35
12f13eb
465d08d
7b84006
049ba15
78c7b88
1f5aa79
1c6f1d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||
| <div class="full wireframe-border"> | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| </div> | ||||||
|
|
||||||
| <!-- Image source: https://oktainc.atlassian.net/browse/OKTA-1137019 --> | ||||||
|
|
||||||
| > **Note:** This flow assumes that user authentication and authorization are complete and the authorization server issued an access token and ID token associated with a successful login to the linked OIDC app. | ||||||
|
|
||||||
| The token exchange flow for an AI agent involves the following steps: | ||||||
|
|
||||||
| 1. The user authenticates with the [Okta org authorization server](/docs/concepts/auth-servers/#org-authorization-server) using a web app. The server returns an ID token to the web app. | ||||||
| 1. The web app passes the ID token to the AI agent so that it can perform actions on the user's behalf. | ||||||
| 1. The AI agent sends the ID token to the org authorization server and requests an exchange for an ID-JAG token. The server validates the request based on the configuration in the **Managed Connections** tab and returns the requested ID-JAG. | ||||||
| 1. Since the requested credential was an ID-JAG, the AI agent sends the ID-JAG to the [custom authorization server](/docs/concepts/auth-servers/#custom-authorization-server) to exchange it for a usable access token. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| 1. The AI agent uses the access token to request access to the resource. | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,9 +5,8 @@ layout: Guides | |||||
| --- | ||||||
| <ApiLifecycle access="ie" /> | ||||||
|
|
||||||
| Learn how to configure token exchange for AI agents so you can securely request and use credentials (ID-JAG, secrets, or service accounts) to access protected resources on behalf of authenticated users. | ||||||
| Learn how to configure token exchange for AI agents so you can securely request and use credentials (ID-JAG, secrets, service accounts, or third-party accesst okens) to access protected resources on behalf of authenticated users. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| > **Note:** <ApiLifecycle access="ea" /> Okta for AI Agents is in Early Access. | ||||||
| --- | ||||||
|
|
||||||
| #### Learning outcomes | ||||||
|
|
@@ -16,45 +15,35 @@ Learn how to configure token exchange for AI agents so you can securely request | |||||
|
|
||||||
| #### What you need | ||||||
|
|
||||||
| * [Okta Integrator Free Plan org](https://developer.okta.com/signup) | ||||||
| * An Okta user account with the super admin role. | ||||||
| * [Register an AI agent](https://help.okta.com/okta_help.htm?type=oie&id=ai-agent-register) in your Okta org. | ||||||
| * **Managed Connections** is configured for the AI agent, defining which resources it’s allowed to access. See [Secure an AI agent](https://help.okta.com/okta_help.htm?type=oie&id=ai-agent-secure). | ||||||
| * An OIDC web app is configured to authenticate users and obtain an ID token. | ||||||
| - [Okta Integrator Free Plan org](https://developer.okta.com/signup) | ||||||
| - An Okta user account with the super admin role. | ||||||
| - [Register an AI agent](https://help.okta.com/okta_help.htm?type=oie&id=ai-agent-register) in your Okta org. | ||||||
| - **Managed Connections** is configured for the AI agent, defining which resources it's allowed to access. See [Secure an AI agent](https://help.okta.com/okta_help.htm?type=oie&id=ai-agent-secure). | ||||||
| - An OIDC web app is configured to authenticate users and obtain an ID token. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Overview | ||||||
|
|
||||||
| You have [registered an AI agent](https://help.okta.com/okta_help.htm?type=oie&id=ai-agent-register). You have also defined it's access to third-party resources integrated with your Okta org using **Managed Connections**. Now, the agent must obtain the actual tokens or credentials to perform tasks. | ||||||
| You've [registered an AI agent](https://help.okta.com/okta_help.htm?type=oie&id=ai-agent-register). You have also defined its access to third-party resources integrated with your Okta org using **Managed Connections**. Now, the agent must obtain the actual tokens or credentials to perform tasks. | ||||||
|
|
||||||
| You can [connect an AI agent](https://help.okta.com/okta_help.htm?type=oie&id=ai-agent-secure) to the following resource types: | ||||||
|
|
||||||
| * Authorization server: Grants the AI agent access to resources that are protected by an Okta custom authorization server. This resource type is supported by [Cross App Access](https://help.okta.com/okta_help.htm?type=oie&id=apps-cross-app-access) (XAA), which uses ID-JAG (Identity Assertion JWT). | ||||||
| - Authorization server: Grants the AI agent access to resources that are protected by an Okta custom authorization server. This resource type is supported by [Cross App Access](https://help.okta.com/okta_help.htm?type=oie&id=apps-cross-app-access) (XAA), which uses ID-JAG (Identity Assertion JWT). | ||||||
|
|
||||||
| * Secret: Uses a static credential for a downstream resource that has been vaulted in Okta Privileged Access. | ||||||
| - Secret: Uses a static credential for a downstream resource that has been vaulted in Okta Privileged Access. | ||||||
|
|
||||||
| * Service account: Uses a static credential for an app that's specified in the Universal Directory. This resource is vaulted in Okta Privileged Access. | ||||||
| - Service account: Uses a static credential for an app that's specified in the Universal Directory. This resource is vaulted in Okta Privileged Access. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| - Resource server: Uses a third party access token issued by the third-party authorization server and brokered by Okta. This resource type requires user consent before an AI agent can act on behalf of the user. | ||||||
|
|
||||||
| Once the resource type is configured and the AI agent has the token or credentials, it can then perform tasks on the connected app. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| ## Token Exchange flow | ||||||
|
|
||||||
| <div class="full wireframe-border"> | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| </div> | ||||||
|
|
||||||
| > **Note:** This flow assumes that user authentication and authorization are complete and the authorization server issued an access token and ID token associated with a successful login to the linked OIDC app. | ||||||
|
|
||||||
| The token exchange flow for an AI agent involves the following steps: | ||||||
| The following diagram describes the **<StackSnippet snippet="resource-type" inline/>** resource type. If you want to change the resource type on this page, select the resource type you want from the **Instructions for** dropdown list on the right.<br> | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| 1. The user authenticates with the [Okta org authorization server](/docs/concepts/auth-servers/#org-authorization-server) using a web app. The server returns an ID token to the web app. | ||||||
| 1. The web app passes the ID token to the AI agent so that it can perform actions on the user's behalf. | ||||||
| 1. The AI agent sends the ID token to the org authorization server and requests an exchange for the resource token/credentials (ID-JAG, secret, or service account). The server validates the request based on the configuration in the **Managed Connections** tab and returns the requested ID-JAG, secret, or service account. | ||||||
| 1. If the requested credential was an ID-JAG, the AI agent sends the ID-JAG to the [custom authorization server](/docs/concepts/auth-servers/#custom-authorization-server) to exchange it for a usable access token. | ||||||
| 1. The AI agent uses the access token, secret, or service account credentials to request access to the resource. | ||||||
| <StackSnippet snippet="token-exchange-flow" /> | ||||||
|
|
||||||
| ## Flow specifics | ||||||
|
|
||||||
|
|
@@ -75,7 +64,7 @@ Use the Authorization Code with PKCE flow to obtain an authorization code for th | |||||
|
|
||||||
| <StackSnippet snippet="exchange-token-id-request" /> | ||||||
|
|
||||||
| ##### Response | ||||||
| #### Response | ||||||
|
|
||||||
| The response contains the requested resource token. | ||||||
|
|
||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,23 @@ | ||||||
|
|
||||||
| In this step, the AI agent sends a `POST` request to the Okta org authorization server's `/token` endpoint to exchange the ID token for the ID-JAG resource token. | ||||||
|
|
||||||
| ``` http | ||||||
| POST /oauth2/v1/token HTTP/1.1 | ||||||
| Host: example.okta.com | ||||||
| Content-Type: application/x-www-form-urlencoded | ||||||
|
|
||||||
| grant_type=urn:ietf:params:oauth:grant-type:token-exchange | ||||||
| &requested_token_type=urn:okta:params:oauth:token-type:oauth-sts | ||||||
| &subject_token=eyJraWQiOiJz... | ||||||
| &subject_token_type=urn:ietf:params:oauth:token-type:id_token | ||||||
| &client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer | ||||||
| &client_assertion=eyJhbGci... | ||||||
| &resource=https://github.com | ||||||
| ``` | ||||||
|
|
||||||
| If the AI agent needs to retrieve an access token through brokered consent using the STS service, token exchange requests must additionally contain the following parameters: | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| | Parameter | Description and value | | ||||||
| | --- | --- | | ||||||
| | requested_token_type | Standard OAuth 2.0 token exchange grant. The value must be `urn:okta:params:oauthtoken-type:oauth-sts`. | | ||||||
| | resource | A resource identifier for the target app. This must match the resource configured in the Managed Connection. | | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| The response during the token exchange depends on if Okta has a stored token. | ||
|
|
||
| ##### Interaction required response | ||
|
|
||
| ```html | ||
| HTTP/1.1 400 | ||
| Content-Type: application/json | ||
| Cache-Control: no-store | ||
| Pragma: no-cache | ||
|
|
||
| { | ||
| "error": "interaction_required", | ||
| "error_description": "The user must authenticate with the authorization server for the request to proceed", | ||
| "interaction_uri": "https://example.okta.com/some/opaque/path" | ||
| } | ||
| ``` | ||
|
|
||
| If Okta doesn't have a valid token, it returns an HTTP 400 error. Your agent's logic must handle this by initiating the user consent flow. | ||
|
|
||
| To handle this, your app should: | ||
|
|
||
| 1. Parse the `interaction_uri` from the JSON response. | ||
| 1. Redirect the end user's browser to this URL. | ||
| 1. After the user completes the flow and is redirected back to your app, retry the original `/token` request. | ||
|
|
||
| #### Token exists response | ||
|
|
||
| ```html | ||
| { | ||
| "issued_token_type": "urn:okta:params:oauth:token-type:oauth-sts", | ||
| "access_token": "eyJhbGciOiJIUzI1NiIsI...", | ||
| "token_type": "Bearer", | ||
| "expires_in": 3600, | ||
| "scope": "repo profile" | ||
| } | ||
| ``` | ||
|
|
||
| Your agent should use the `access_token` from this response to make authenticated API calls to the target resource, including it in the `Authorization` header as a Bearer token. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Resource server |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <div class="full wireframe-border"> | ||
|
|
||
|  | ||
|
|
||
| </div> | ||
|
|
||
| <!-- Image source: https://oktainc.atlassian.net/browse/OKTA-1137019 --> | ||
|
|
||
| > **Note:** This flow assumes that you've registered a resource server as an OIN app instance, a custom API resource server, or an MCP server, and that you've connected an AI agent to the server as a **Managed Connection**. | ||
|
|
||
| The token exchange flow for an AI agent involves the following steps: | ||
|
|
||
| 1. The user authenticates with the [Okta org authorization server](/docs/concepts/auth-servers/#org-authorization-server) using a web app. The server returns an ID token to the web app. | ||
| 1. The web app passes the ID token to the AI agent so that it can perform actions on the user's behalf. | ||
| 1. The AI agent sends a `POST /token` request to Okta, asking for an access token for a protected resource in the target app. Okta checks to see if it already possesses a valid token for the user and the requested app. | ||
| 1. If no valid token is found, Okta returns an `HTTP 400 Bad Request` response to the AI agent. This response contains an error code of `interaction_required` and a unique `interaction_uri`. | ||
| 1. The AI agent receives the `interaction_required` error and redirects the user's browser to the `interaction_uri` provided by Okta. | ||
| 1. The user is directed to the app's website, where they're prompted to authorize the connection and grant consent for the AI agent to access their data. | ||
| 1. After the user grants consent, the app redirects the user's browser back to an Okta endpoint, including a temporary, single-use `auth_code` in the URL. | ||
| 1. Okta exchanges the `auth_code` with the app. | ||
| 1. Okta receives a new access token and a long-lived refresh token. Okta securely saves these tokens, linking them to the user. | ||
| 1. After Okta successfully stores the tokens, the user asks the agent to retry the connection. This signals that the consent part of the flow is complete. | ||
| 1. The AI agent's code must now retry the original `POST /token` request from step 3. Because Okta now has the necessary tokens stored, this retry attempt succeeds. Okta responds with an `HTTP 200 OK` and provides the short-lived access token that the AI agent can use to make its API calls. | ||
| 1. The AI agent uses the access token to request access to the resource. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -19,10 +19,10 @@ grant_type=urn:ietf:params:oauth:grant-type:token-exchange | |||||
|
|
||||||
| | Parameter | Description and value | | ||||||
| | --- | --- | | ||||||
| | grant_type | Standard OAuth 2.0 token exchange grant. The value must be `urn:ietf:params:oauth:grant-type:token-exchange` | | ||||||
| | client_assertion_type | The value must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer` | | ||||||
| | grant_type | Standard OAuth 2.0 token exchange grant. The value must be `urn:ietf:params:oauth:grant-type:token-exchange`. | | ||||||
| | client_assertion_type | The value must be `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`. | | ||||||
| | client_assertion | A signed JWT used for client authentication. You must sign the JWT using the key created during the AI Agent registration. For more information on building the JWT, see [JWT with private key](https://developer.okta.com/docs/api/openapi/okta-oauth/guides/client-auth/#jwt-with-private-key). | | ||||||
| | subject_token_type | The value must be `urn:ietf:params:oauth:token-type:id_token` | | ||||||
| | subject_token_type | The value must be `urn:ietf:params:oauth:token-type:id_token`. | | ||||||
| | subject_token | A valid ID token issued to the resource app associated with the AI agent. | | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| | requested_token_type | The value must be `urn:okta:params:oauth:token-type:vaulted-secret` | | ||||||
| | requested_token_type | The value must be `urn:okta:params:oauth:token-type:vaulted-secret`. | | ||||||
| | resource | A resource identifier for the secret. This value must match the identifier configured on the **Managed Connection** tab. | | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,16 @@ | ||||||
| <div class="full wireframe-border"> | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| </div> | ||||||
|
|
||||||
| <!-- Image source: https://oktainc.atlassian.net/browse/OKTA-1137019 --> | ||||||
|
|
||||||
| > **Note:** This flow assumes that user authentication and authorization are complete and the authorization server issued an access token and ID token associated with a successful login to the linked OIDC app. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| The token exchange flow for an AI agent involves the following steps: | ||||||
|
|
||||||
| 1. The user authenticates with the [Okta org authorization server](/docs/concepts/auth-servers/#org-authorization-server) using a web app. The server returns an ID token to the web app. | ||||||
| 1. The web app passes the ID token to the AI agent so that it can perform actions on the user's behalf. | ||||||
| 1. The AI agent sends the ID token to the org authorization server and requests an exchange for the resource token. The server validates the request based on the configuration in the **Managed Connections** tab and returns the requested secret or service account. | ||||||
| 1. The AI agent uses the secret or service account credentials to request access to the resource. | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,16 @@ | ||||||
| <div class="full wireframe-border"> | ||||||
|
|
||||||
|  | ||||||
|
|
||||||
| </div> | ||||||
|
|
||||||
| <!-- Image source: https://oktainc.atlassian.net/browse/OKTA-1137019 --> | ||||||
|
|
||||||
| > **Note:** This flow assumes that user authentication and authorization are complete and the authorization server issued an access token and ID token associated with a successful login to the linked OIDC app. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| The token exchange flow for an AI agent involves the following steps: | ||||||
|
|
||||||
| 1. The user authenticates with the [Okta org authorization server](/docs/concepts/auth-servers/#org-authorization-server) using a web app. The server returns an ID token to the web app. | ||||||
| 1. The web app passes the ID token to the AI agent so that it can perform actions on the user's behalf. | ||||||
| 1. The AI agent sends the ID token to the org authorization server and requests an exchange for the resource token. The server validates the request based on the configuration in the **Managed Connections** tab and returns the requested service account or service account. | ||||||
| 1. The AI agent uses the service account or service account credentials to request access to the resource. | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.