Token Exchange

OAuth 2.0 Token Exchange (available in Enterprise) allows a client to exchange a token it already has for another token that can be used to access other resources. This allows you to create tokens with narrower scope, since it enables to get another token with changed scope, different audience and it could also include a record of who is acting on whoose behalf. Important capabilites in many scenarios, for example in a micro service architecture, but almost a must have for AI Agents.

Impersonation or delegation (in the context of Token Exchange)

Impersonation is when the identity A is given all the rights that identity B has and is indistinguishable from B from the perspective of the target resource. In typical scenario where token exchange is used to get an access token, the resulting token would have the exact same content as if B got it directly in the purpose of accessing the target resource.

Delegation is when identity A still has its own identity seperate from B, but B has delegated some of its rights to A, so that actions taken by A is done representing B. This allows an audit log to prove what parties were involved in the taken action.

Here is a table showing the differences in token exchange for Impersonation and Delegation:

Impersonation Delegation
Request only subject_token subject_token and actor_token
Issued sub The user The user
Issued act None Present, identifing the client that did the exchange
The (API) resource sees The user The user and the client
Auditing Only the user The client on behalf of the user

Scenario: AI Agent consuming a MCP Server that uses downstream API:s

In this scenario the user has identified itself to an AI Agent through Authway. The agent has recieved both an identity token and an access token. The access token is very narrow and does not include any scopes other than needed for the AI Agent itself. This is how Token Exchange with delegation is used in this scenario:

  1. The agent uses the OAuth client credentials flow to get an access token representing the Agent.

  2. The agent calls the Token endpoint to exchange the access token for a new access token that can be used to call the MCP Server.

POST /connect/token HTTP/1.1
Host: YOURINSTANCE.irmciam.se
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
    
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
     &subject_token_type=urn:ietf:params:oauth:token-type:access_token
     &subject_token=eyJhbGciOiJSU....88HgibHg
     &actor_token_type=urn:ietf:params:oauth:token-type:access_token
     &actor_token=eyJhbGciOiJSU...v6xZLycw
     &scope=mcp_server
  1. Authway will respond with an access token like this (decoded and shorted for readability):
{
  "iss": "https://YOURINSTANCE.irmciam.se",
  "aud": "mcp_server",
  "scope": [
    "mcp_server"
  ],
  "amr": [
    "urn:ietf:params:oauth:grant-type:token-exchange"
  ],
  "sub": "d5542f98-8a6f-6d2a-cda0-39fc52ae2b58",
  "act": {
    "client_id": "AI-Agent"
  }
}

Notice that there is an act claim identifying that it is the AI Agent that makes the call on behalf of the user identified by the sub claim.

  1. The AI Agent sends the exchanged token to the MCP Server.

  2. The MCP Server validates the access token as usual, making sure that it is the targeted audience for the token.

  3. When the MCP Server needs to invoke the downstream API, it will start by also making a OAuth client credential request to get an access token representing the MCP Server.

  4. The MCP Server calls the Token endpoint to exchange the access token for a new access token that can be used to call the downstream API.

POST /connect/token HTTP/1.1
Host: YOURINSTANCE.irmciam.se
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
    
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
     &subject_token_type=urn:ietf:params:oauth:token-type:access_token
     &subject_token=eyJhbGciOiJSU....2T2O3n7w
     &actor_token_type=urn:ietf:params:oauth:token-type:access_token
     &actor_token=eyJhbGciOiJSU...v6xZLycw
     &scope=api
  1. Authway will respond with an access token like this (decoded and shorted for readability):
{
  "iss": "https://YOURINSTANCE.irmciam.se",
  "aud": "api",
  "scope": [
    "api"
  ],
  "amr": [
    "urn:ietf:params:oauth:grant-type:token-exchange"
  ],
  "sub": "d5542f98-8a6f-6d2a-cda0-39fc52ae2b58",
  "act": {
    "client_id": "MCP-Server",
    "act": {
        "client_id": "AI Agent",
    }
  }
}

Notice that there is a nestled act claim identifying that it is the MCP Server that makes the call on behalf of the user identified by the sub claim, but also information that the originating caller is the AI Agent.

  1. The downstream API validates the access token as usual, making sure that it is the targeted audicens for the token. It is possible for the API to log the complete chain of involved clients that have been acting on behalf of the user.

Scenario: Teams plug-in needs to consume an API protected by Authway

The user is identified by Entra ID in Teams and do not require an extra authentication by the user, this scenario retrieves an Authway access token by passing a login hint token as subject token in the token exchange (impersonation).

  1. The plugin creates a login hint token.
  2. The plugin calls the Token endpoint to exchange the access token for a new access token that can be used to call the API.
POST /connect/token HTTP/1.1
Host: YOURINSTANCE.irmciam.se
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
    
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
     &subject_token_type=urn:authway:params:oauth:token-type:login_hint_token
     &subject_token=eyJhbGciOiJSU....UzKU5MGk
     &scope=api
  1. Authway will respond with an access token like this (decoded and shorted for readability):
{
  "iss": "https://YOURINSTANCE.irmciam.se",
  "aud": "api",
  "scope": [
    "api"
  ],
  "amr": [
    "urn:ietf:params:oauth:grant-type:token-exchange"
  ],
  "sub": "d5542f98-8a6f-6d2a-cda0-39fc52ae2b58"
}
  1. The downstream API validates the access token as usual, making sure that it is the targeted audicens for the token.