Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
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
Expand All @@ -16,17 +15,15 @@ grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&audience=https://example.okta.com/oauth2/default
&scope=chat.read+chat.history
```

| 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. |
| requested_token_type | The value must be `urn:ietf:params:oauth:token-type:id-jag` |
| requested_token_type | The value must be `urn:ietf:params:oauth:token-type:id-jag`. |
| scope | A list of scopes at the resource app being requested. This defines the permissions for the final access token. |
| audience | The issuer URL of the resource app’s authorization server. |

| audience | The issuer URL of the resource app's authorization server. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div class="full wireframe-border">

![Flow diagram illustrating the process of AI agent token exchange](/img/auth/ai-agent-token-exchange/token_exchange_flow_for_ID-JAG.png)

</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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> **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.
> **Note:** This flow assumes that user authentication and authorization are complete and the authorization server issued an access token and ID token associated with the user successfully signing in 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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
1. Because 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 to request access to the resource.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
Learn how to configure token exchange for AI agents so that 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.


> **Note:** <ApiLifecycle access="ea" /> Okta for AI Agents is in Early Access.
---

#### Learning outcomes
Expand All @@ -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 its 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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- 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 Universal Directory. This resource is vaulted in Okta Privileged Access.


- 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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Once the resource type is configured and the AI agent has the token or credentials, it can then perform tasks on the connected app.
Ater the resource type is configured and the AI agent has the token or credentials, it can then perform tasks on the connected app.


## Token Exchange flow

<div class="full wireframe-border">

![Flow diagram illustrating the process of AI agent token exchange](/img/auth/ai-agent-token-exchange.png)

</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>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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>
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 that you want from the **Instructions for** dropdown list on the right.<br>


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

Expand All @@ -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.

Expand Down
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:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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:
If the AI agent needs to retrieve an access token through brokered consent using the STS service, token exchange requests must also contain the following parameters:


| 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">

![Flow diagram illustrating the process of AI agent token exchange](/img/auth/ai-agent-token-exchange/token_exchange_flow_for_OAuth_STS.png)

</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
Expand Up @@ -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. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| subject_token | A valid ID token issued to the resource app associated with the AI agent. |
| subject_token | A valid ID token issued to the resource app associated with the AI agent |

| 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">

![Flow diagram illustrating the process of AI agent token exchange](/img/auth/ai-agent-token-exchange/token_exchange_flow_for_secret.png)

</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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> **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.
> **Note:** This flow assumes that user authentication and authorization are complete and the authorization server issued an access token and ID token associated with the user successfully signing in 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 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
Expand Up @@ -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. |
| requested_token_type | The value must be `urn:okta:params:oauth:token-type:service-account` |
| requested_token_type | The value must be `urn:okta:params:oauth:token-type:service-account`. |
| resource | A resource identifier for the service account. 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">

![Flow diagram illustrating the process of AI agent token exchange](/img/auth/ai-agent-token-exchange/token_exchange_flow_for_service_account.png)

</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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> **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.
> **Note:** This flow assumes that user authentication and authorization are complete and the authorization server issued an access token and ID token associated with the user successfully signing in 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 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.
3 changes: 2 additions & 1 deletion packages/@okta/vuepress-theme-prose/util/frameworks.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ const COMMON_NAME_TO_FANCY_NAME = {
oktasaml: 'Okta SAML 2.0 IdP',
thirdpartyoidc: 'Third-party OIDC IdP',
thirdpartysaml: 'Third-party SAML 2.0 IdP',
authserver: 'Authorization server',
authserver: 'Authorization server (ID-JAG)',
secret: 'Secret',
'service-account': 'Service account',
resourceserver: 'Resource server',
};

const COMMON_NAME_TO_ICON_NAME = {
Expand Down