Table of Contents

What is Token Exchange, and Why Does AI Need it?

TL;DR: OAuth token exchange gives AI agents a way to obtain short-lived, purpose-specific access without carrying broad permissions or long-lived credentials. This guide walks through the mechanics with actual token requests, JWT claims, delegation flows, policy checks, human approval, and a cross-cloud federation example.

Víctor Jiménez
Víctor Jiménez

Technical Writer at RootNode

Summarize:

Read
0%
Hands exchanging keys beneath the text “Understanding Token Exchange for AI Agents."

Table of Contents

Read
0%

Token exchange is a protocol extension for OAuth 2.0 in which an authorization server can act as a security token service (STS) that provides security tokens, defined in RFC 8693.

As the adoption of automation grows, so do machine-to-machine connections, and AI agents take this model to the extreme. To keep all these interactions under control, you need a model that is based on global access policies rather than individual permissions for each agent.

Token exchange is one piece of this puzzle, allowing OAuth clients to obtain broader access on demand, lasting only as long as they need it.

In this article, we’ll explore token exchange in OAuth 2.0 for scenarios such as delegation and identity federation.

How Does OAuth Token Exchange Work?

Token exchange has been designed as a simple flow to add minimal workload overhead:

  1. An OAuth client needs access to a new resource.
  2. The client requests an access token for the new resource, providing an existing token.
  3. The authorization server evaluates its access policies.
  4. If the request aligns with the policies, the authorization server returns a new access token.

The OAuth client that the user is interacting with is not necessarily the one requesting the exchange. It’s more frequent in Resource Servers accessing other resources, and acting as OAuth clients.

The three main use cases for token exchange are:

  • Policy-driven access: Provision clients with minimal access, and provide broader access via token exchanges.
  • Delegation: An agent serving multiple users, obtaining access tokens to act on behalf of each user.
  • Federation: Agents requesting access to external resources.

Let’s see them in action with some examples.

Delegation and Impersonation With OAuth Token Exchange

If you have an AI agent that serves multiple users and need to access external resources, you have three choices:

1. You grant the agent access to all resources: But then the agent is overprivileged, being able to access resources at any time. If the agent is compromised, a malicious actor could exploit all this access.

2. The user shares their access tokens with the agent: The agent can act as the user, but then the user has no guarantee that the agent won’t store its credentials for longer than needed. Also, there is no transparency on who is accessing the resources. Finally, if the agent is compromised, the malicious actors can acquire a wide array of credentials.

3. The agent obtains access on demand: The agent exchanges the user’s access token for one to access a resource with a short expiration date. The new token declares the delegation chain, so resources can know that an agent is accessing on behalf of a user, and adapt accordingly. And finally, if an agent gets compromised, the malicious actors will only gather short-lived access tokens, which will limit the damage they can cause.

The first two options are considered too risky and are discouraged. The third option, the token exchange one, follows security best practices and is recommended. The flow would be something like this:

We explored a similar scenario in Impersonation vs. Delegation: Getting On-Behalf-Of Tokens Right. That article covers a delegation scenario between a frontend and a backend that uses plain OAuth access tokens.

Step 1: In this scenario, the user uses a client to send a request to the agent. Notice how the client uses a JWT to authenticate against the agent.

GET /resource HTTP/1.1
Host: agent.example.com
Authorization: Bearer eyJhbGciOiJFZERTQSIsImtpZCI6IjIwMjYtMDctMjJfYjc0In0.eyJhdWQiOiJodHRwczovL2FnZW50LmV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImV4cCI6MTQ0MTkxMDA2MCwic2NvcGUiOiJhZ2VudCIsInN1YiI6InVzZXJAZXhhbXBsZS5uZXQifQ.OKaGU1r-dQktiPP75u65nanyuthauzS2gz8iIjwRmSCYLyDObGojAxbb7hrzJqfFv0a2lELaNsLEnNGWProzDg

You can explore the JWT’s payload in jwt.io. There, you can observe that the user is identified as user@example.net in the sub claim.

{
  "aud": "https://agent.example.com",
  "iss": "https://as.example.com",
  "exp": 1441910060,
  "scope": "agent",
  "sub": "user@example.net"
}

Step 2: The agent needs to call a resource to fulfill this request. It will request an access token from the authorization server:

/codePOST /token HTTP/1.1

Host: as.example.com

…

Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange

&resource=https%3A%2F%2Fbackend.example.com
&scope=”profile”

&subject_token=eyJhbGciOiJFZERTQSIsImtpZCI6IjIwMjYtMDctMjJfYjc0In0.eyJhdWQiOiJodHRwczovL2FnZW50LmV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImV4cCI6MTQ0MTkxMDA2MCwic2NvcGUiOiJhZ2VudCIsInN1YiI6InVzZXJAZXhhbXBsZS5uZXQifQ.OKaGU1r-dQktiPP75u65nanyuthauzS2gz8iIjwRmSCYLyDObGojAxbb7hrzJqfFv0a2lELaNsLEnNGWProzDg

&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt

&actor_token=eyJhbGciOiJFZERTQSIsImtpZCI6IjIwMjYtMDctMjJfYjc0In0.eyJhdWQiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9hcy5leGFtcGxlLmNvbSIsImV4cCI6MTQ0MTkxMDA2MCwic2NvcGUiOiJ0b2tlbiIsInN1YiI6Imh0dHBzOi8vYWdlbnQuZXhhbXBsZS5jb20ifQ.EU5ypJHTH19eO2tI9M5vcpcQzMOmuK6qwWgoUp2MigKUMx4DWiNZH0j1hCLyqiF8LJrn2y5KG8aJZfgCZvPiCw

&actor_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt

Note how the agent uses its own JWT to authenticate against the access token in the Authorization header. The request body includes three key parameters:

  • resource: The backend service the agent needs to access.
  • scope: The scope the agent will access in the resource. Notice how it is different from the original user’s JWT.
  • subject_token: Is the JWT the user sent in step 1.
  • actor_token: The agent’s credentials (a JWT) to access the token API in the authorization server.

If the actor_token parameter is missing, the exchanged token won’t contain the delegation chain. It will be a case of impersonation, as the resource won’t be able to tell that there’s an AI agent acting as an intermediary.

Step 3: The authorization server will check the access policies. If this request aligns with the policies, it will return a new token that the agent will be able to use against the resource.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store

{
 "access_token":
"eyJhbGciOiJFZERTQSIsImtpZCI6IjIwMjYtMDctMjJfYjc0In0.eyJhdWQiOiJodHRwczovL2JhY2tlbmQuZXhhbXBsZS5jb20iLCJpc3MiOiJodHRwczovL2FzLmV4YW1wbGUuY29tIiwiZXhwIjoxNDQxOTEzNjEwLCJzY29wZSI6InByb2ZpbGUiLCJzdWIiOiJ1c2VyQGV4YW1wbGUubmV0IiwiYWN0Ijp7InN1YiI6Imh0dHBzOi8vYWdlbnQuZXhhbXBsZS5jb20ifX0.cnXn7IlEcDUARZljUzGEs_8zVdRJDYUapTC8sxoVWXzotJNH9jy2YOa0SXu167jMsRnld4QiliJsXdLkPCZ2BQ",
 "issued_token_type":"urn:ietf:params:oauth:token-type:jwt",
 "token_type":"Bearer",
 "expires_in":3600
}

The payload of the token is:

{
  "aud":"https://backend.example.com",
  "iss":"https://as.example.com",
  "exp":1441913610,
  "scope":"profile",
  "sub":"user@example.net",
  "act":
  {
    "sub":"https://agent.example.com"
  }
}

Observe how the user is still the sub. However, the delegation chain in the act claim brings transparency into who is really acting on behalf of the user.

Also note how the audience (aud) of this new token is limited to the backend resource.

What we just described is the core flow for token exchange, and it is the basis for the next examples in this article.

Learn more about the differences between impersonation and delegation in Impersonation vs. Delegation: Getting On-Behalf-Of Tokens Right.

Access Policies With OAuth Token Exchange

A key moment in the token exchange flow is the step when the authorization server validates the exchange request against the authorization policies (step 3).

However, the token exchange RFC only provides general security guidelines on how authorization servers should perform this verification. Each server is free to implement this step as they see fit, which opens the door to some creative applications.

For example, an authorization server from a cloud provider will delegate this validation to the cloud’s IAM service.

Let’s see some options for this validation step.

The may_act Claim

The simplest way of validation is for the client’s token to explicitly grant the agent permission to to act on their behalf. This is done by including the may_act claim (in step 1).

In the following example, the token explicitly declares that the agent can act on their behalf:

{
  "aud": "https://agent.example.com",
  "iss": "https://ass.example.com",
  "exp": 1441910060,
  "scope": "agent",
  "sub": "user@example.net"
  "may_act": {
    "sub": "https://agent.example.com"
  }
}

As this token was issued and signed by the authorization server, the authorization server can trust this claim and skip further validation steps.

IAM Tools

IAM tools can act as authorization servers, or integrate with them, to apply access policies that can be enforced across all the organization’s infrastructure.

IAM tools can provide a single pane of glass to enforce policies like:

  • Restrict scopes.
  • Limit access depending on time of day.
  • Throttle number of accesses.
  • Provide one-time access.

As centralized tools, they also provide visibility into who is accessing what. This allows administrators to detect abnormal behavior and respond by blocking access.

Human Approval for AI Workloads

At the beginning, we mentioned that AI agents push identity infrastructures to the limit. Think about it, compared to traditional workloads:

  • Agents perform general tasks that require access to a wider range of resources.
  • Access to resources is not predictable, but rather intermittent and random. 

This non-deterministic nature means that an AI agent might analyze a codebase and decide that the best way to optimize it is to destroy a database.

So, sometimes agentic workloads require a human-in-the-loop to validate access manually. Especially for risky operations or while tuning a new agent. Read more about human approval for agentic workloads in How AAuth Brings Human Approval Into AI Agent Authorization.

Token exchange is ideal in these scenarios, as the agent will receive the access token after human approval.

Using OAuth Token Exchange to Bridge Between Infrastructures – Workload Identity Federation

By creating a system of trust between two identity providers (IdPs), accounts on one side can access services on the other.

Think of a multi-cloud scenario where an agent on an EC2 instance wants to access a protected resource in Google Cloud. It’s possible to set up Workload Identity Federation so that: 

  • Identities in AWS map to identities on Google Cloud.
  • An AI agent running on EC2 can use token exchange against Google Cloud to access a resource there.

Once everything is set up, the preferred method to obtain these cross-cloud credentials is via the cloud provider’s API.

However, it’s also possible to use OAuth token exchange. In summary, the flow is as follows:

First, the workload must obtain credentials from the external IdP.  This step is usually performed using the GetCallerIdentity method in AWS’s API. From a Python client, this would look like:

request = AWSRequest(
    method="POST",
    url="https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15",
    headers={
        "Host": "sts.amazonaws.com",
        "x-goog-cloud-target-resource": f"//iam.googleapis.com/projects/{project_number}/locations/global/workloadIdentityPools/{pool_id}/providers/{provider_id}",
    },
)

SigV4Auth(boto3.Session().get_credentials(), "sts", "us-east-1").add_auth(request)

# Create token from signed request.
token = {"url": request.url, "method": request.method, "headers": []}
for key, value in request.headers.items():
    token["headers"].append({"key": key, "value": value})

print("Token:\n%s" % json.dumps(token, indent=2, sort_keys=True))
print("URL encoded token:\n%s" % urllib.parse.quote(json.dumps(token)))

See how the x-goog-cloud-target-resource ties this token to the identity provider on the Google Cloud side.

The client can use this TOKEN in OAuth token exchange requests to obtain short-lived access tokens. A request to Google Cloud’s IdP would look like:

POST /v1/token HTTP/1.1
Host: sts.googleapis.com
Content-Type: application/json
…

{
  "audience": "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID",
  "grantType": "urn:ietf:params:oauth:grant-type:token-exchange",
  "requestedTokenType": "urn:ietf:params:oauth:token-type:access_token",
  "scope": "https://www.googleapis.com/auth/cloud-platform",
  "subjectTokenType": "urn:ietf:params:aws:token-type:aws4_request",
  "subjectToken": TOKEN
}

Note how:

  • GoogleCloud’s IdP supports receiving the request body in JSON format.
  • The audience claim matches the x-goog-cloud-target-resource header from earlier.
  • The requested scope is limited to the auth/cloud-platform API.

Token Exchange Enables Transparency on AI Workloads

As we mentioned earlier, agentic workloads often need to delegate to several agents while performing a task. Those agents may delegate to others, and so on, creating a delegation chain that muddies the flow and complicates troubleshooting.

It’s crucial to have visibility of this delegation chain when investigating security incidents to identify what link in the chain is compromised and properly assess which assets are affected.

Luckily, when using the delegation syntax in OAuth token exchange, the chain of delegation is represented in the generated tokens under the act field:

{
  "aud":"https://service26.example.com",
  "iss":"https://issuer.example.com",
  "exp":1443904100,
  "nbf":1443904000,
  "sub":"user@example.net",
  "act":
  {
    "sub":"https://service16.example.com",
    "act":
    {
      "sub":"https://service77.example.com"
    }
  }
}

This is the payload for an access token. We can see that:

  • This token authorizes against service26.
  • The effective user is user@example.net as per the sub claim.
  • Two token exchanges have taken place, as per the act claim.
    • The first one was by service77.
    • The second one was by service16, which is now using this token.

If service26 were to perform a new token exchange, the authorization server would expand the act claim in the new token:

{
  "aud":"https://service42.example.com",
  "iss":"https://issuer.example.com",
  "exp":1443904100,
  "nbf":1443904000,
  "sub":"user@example.net",
  "act":
  {
    "sub":"https://service26.example.com",
    "act":
    {
      "sub":"https://service16.example.com",
      "act":
      {
        "sub":"https://service77.example.com"
      }
    }
  }
}

Why AI Needs OAuth Token Exchange

Agentic AI changes the scale of workload identity.

OAuth token exchange is designed to help developers navigate this paradigm and follow identity best practices without costly custom implementations.

Frequently Asked Questions About OAuth Token Exchange and AI Agents

What is OAuth token exchange?

OAuth token exchange is an extension to OAuth 2.0 defined in RFC 8693. It allows a client to present an existing security token to an authorization server and request a new token for a different resource, audience, scope, or security context.

Why is token exchange useful for AI agents?

AI agents often need access to different resources as their tasks change. Token exchange allows them to obtain narrowly scoped, short-lived access on demand rather than holding broad permissions or storing a collection of long-lived user credentials.

How does token exchange support AI agent delegation?

An agent can exchange a user’s token for a new access token that represents both the user and the agent acting on the user’s behalf. The resulting token can preserve that delegation relationship, giving downstream services visibility into who initiated the action and which agent performed it.

What is the difference between delegation and impersonation in token exchange?

With delegation, the resulting token preserves information about both the subject and the actor performing the action on the subject’s behalf. With impersonation, the intermediary may not be represented in the resulting token, making it appear that the subject is acting directly.

Can OAuth token exchange enforce access policies?

The token exchange flow gives an authorization server an opportunity to evaluate policy before issuing a new token. Organizations can use that decision point to restrict scopes, limit access conditions, require human approval, or deny the exchange entirely.

Can token exchange be used across cloud environments?

Yes. Workload identity federation can use token exchange to establish trust across identity domains. For example, a workload running in AWS can exchange its existing identity evidence for short-lived credentials that allow it to access authorized resources in Google Cloud.

Related Reading

Víctor Jiménez
Víctor Jiménez

Víctor Jiménez is an engineer and technical writer who specializes in turning complex engineering concepts into clear, practical explanations. He began his career as a full-stack software engineer, while also working as a MySQL database administrator and certified instructor. After moving into technical marketing, Víctor focused increasingly on educational content for technical audiences. His recent work covers cloud infrastructure, containers and cybersecurity. Outside of work, he experiments with 3D printing, builds LEGO sets and hosts Dungeons & Dragons campaigns.

You might also like

Secrets managers still matter. But AI agents and workloads are changing when stored credentials make sense.
Broad credentials made sense when fixed application logic stood between users and actions, but AI agents have changed that equation.
What began as a way for agents to call tools is expanding into infrastructure for longer-running, governed interactions across enterprise systems.