---
title: Transaction Tokens in the AuthPlayground
description: Explore how transaction tokens preserve trusted context through distributed AI service call chains in the AuthPlayground.
component: identity-for-ai
page_id: identity-for-ai:protocols:authplayground-transaction-tokens
canonical_url: https://developer.pingidentity.com/identity-for-ai/protocols/authplayground-transaction-tokens.html
llms_txt: https://developer.pingidentity.com/identity-for-ai/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
revdate: 2026-08-24T07:38:08Z
keywords: ["Identity for AI", "OAuth 2.0 protocols", "transaction tokens", "TTS", "trust domain", "call chain", "distributed AI workflows", "AuthPlayground"]
section_ids:
  the-transaction-token-model: The transaction token model
  whats-a-trust-domain: What's a trust domain?
  a-human-isnt-required: A human isn't required
  the-authplayground-implementation: The AuthPlayground implementation
  step-1-obtain-the-subject-token: "Step 1: Obtain the subject token"
  step-2-request-the-transaction-token: "Step 2: Request the transaction token"
  step-3-propagate-the-transaction-token: "Step 3: Propagate the transaction token"
  how-transaction-tokens-relate-to-other-concepts: How transaction tokens relate to other concepts
  the-difference-between-principals-and-requesting-workloads: The difference between principals and requesting workloads
  transaction-tokens-versus-workload-identity: Transaction tokens versus workload identity
  transaction-tokens-and-token-exchange-solve-different-problems: Transaction tokens and token exchange solve different problems
  transaction-tokens-differ-from-id-jag: Transaction tokens differ from ID-JAG
  key-takeaways: Key takeaways
  short-lifetimes-matter: Short lifetimes matter
  keeping-the-call-chain-understandable: Keeping the call chain understandable
---

# Transaction Tokens in the AuthPlayground

Preserving trusted context through a chain of microservices.

Enterprise AI workflows often involve multiple services. Consider a planner agent that needs customer information to complete a task. It asks a retrieval agent to gather the information, and the retrieval agent calls account context and customer intelligence services.

As the request moves through the call chain, each service can usually identify its direct caller. Preserving the trusted context behind the overall transaction is more difficult. Several hops later, a service might know that it was called by the customer intelligence service. The enterprise needs to know:

* Which transaction does this call belong to?

* Which principal is associated with the transaction?

* Which workload originally requested the transaction token?

* What's the purpose or authorization scope of this transaction?

* Is this context valid inside this trust domain?

* Is the token still current?

Transaction tokens ([IETF draft](https://datatracker.ietf.org/doc/draft-ietf-oauth-transaction-tokens/)) carry trusted context through the call chain.

## The transaction token model

A transaction token is a short-lived, signed JSON Web Token (JWT) associated with a specific transaction and trust domain. It carries information such as:

* `sub`: Who or what is the principal of this transaction?

* `txn`: Which transaction is this?

* `req_wl`: Which workload requested the transaction token?

* `aud`: Which trust domain is this token valid in?

* `scope`: What's the purpose or authorization scope?

* `exp`: How long is this context valid?

* `iat`: When was this token issued?

A simplified example looks like this:

```json
Header {
  "typ": "txntoken+jwt",
  "alg": "RS256",
  "kid": "transaction-token-signing-key"
}

body
{
  "sub": "demo-user@example.com",
  "txn": "txn-48291",
  "req_wl": "meeting-prep-agent.bx.internal",
  "aud": "bx-ai.internal",
  "scope": "customer.meeting-prep",
  "iat": 1786575243,
  "exp": 1786575303
}
```

Actual claims and values depend on the Transaction Token Service (TTS) and deployment requirements. Downstream workloads receive a cryptographically protected representation of the transaction instead of reconstructing the security context from arbitrary headers.

### What's a trust domain?

A trust domain is a group of systems that share a common set of security controls and policies. For example, an enterprise might operate several AI services inside one governed environment.

The transaction token is valid within that trust domain, which is why the `aud` claim is important. It doesn't represent an individual service (such as `aud = Account Context Service`). Instead, it represents the entire domain (such as `aud = AI Trust Domain`). Workloads must not accept a transaction token outside the trust domain identified by its `aud` claim.

### A human isn't required

A transaction token can support a human-initiated workflow, but a human isn't required. For autonomous workloads, the transaction might originate entirely from software. The principal represented by the transaction could be a workload instead of a person.

Consider an autonomous monitoring agent versus a human-initiated meeting preparation request. In the human-initiated request, Sarah is the principal. Transaction tokens preserve trusted authorization and request context through a call chain inside a trust domain for both patterns.

## The AuthPlayground implementation

**Entities involved**: Client application, transaction token service, resource server

The AuthPlayground demonstrates the [Transaction Token](https://www.authplayground.dev/flows/txn-tokens) flow in three steps:

1. Obtain the subject token.

2. Request the transaction token.

3. Propagate the transaction token.

### Step 1: Obtain the subject token

The calling workload obtains an OAuth access token from the authorization server:

```json
POST /idp/token
Content-Type: application/x-www-form-urlencoded

{
  "grant_type": "authorization_code",
  "code": "<authorization_code>",
  "redirect_uri": "<callback>",
  "client_id": "playground-demo-client",
  "code_verifier": "<pkce_verifier>"
}
```

The response contains an access token:

```json
{
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid profile email",
  "access_token": "<access_token>",
  "id_token": "<id_token>"
}
```

The OAuth access token becomes the `subject_token` used when requesting the transaction token. It establishes the subject context from which the TTS can create transaction-scoped context.

|   |                                                                                                                                                                                                                                        |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | The transaction token specification is broader than this example. A Txn-Token can represent externally or internally originated transactions. An OAuth user access token isn't required for every possible transaction token use case. |

### Step 2: Request the transaction token

The calling workload requests a transaction token from the TTS:

```json
POST /tts/token
Content-Type: application/x-www-form-urlencoded

{
  "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
  "subject_token": "<subject_token>",
  "subject_token_type": "urn:ietf:params:oauth:token-type:access_token",
  "requested_token_type": "urn:ietf:params:oauth:token-type:txn_token",
  "audience": "example.org",
  "scope": "read write",
  "request_context": "{\"req_ip\":\"203.0.113.42\",\"authn\":\"urn:mace:incommon:iap:silver\"}",
  "request_details": "{\"action\":\"read\",\"resource\":\"/api/data\"}"
}
```

Notice the following details:

* `subject_token`: Provides the subject context for the transaction.

* `requested_token_type`: Explicitly asks for a transaction token.

* `audience`: Identifies the trust domain, not an individual downstream service.

* `scope`: Expresses the permissions associated with the transaction.

The specification defines `request_context` and `request_details` as recommended parameters. They give the TTS additional context about the transaction and request. In the playground, that information appears in the resulting transaction token as:

```json
{
  "rctx": {
    "req_ip": "203.0.113.42",
    "authn": "urn:mace:incommon:iap:silver"
  },
  "tctx": {
    "action": "read",
    "resource": "/api/data"
  }
}
```

The TTS identifies the calling workload, sets `req_wl`, validates the subject context, creates a unique `txn` identifier, and issues the short-lived transaction token.

### Step 3: Propagate the transaction token

The calling workload invokes a downstream service and sends the transaction token in the dedicated HTTP header:

```json
GET /rs/api/data

Txn-Token: <transaction_token>
```

The use of a separate `Txn-Token` header is deliberate. Workloads mustn't use the standard `Authorization` header to carry the Txn-Token because they might need that header for other purposes.

The receiving workload validates the transaction token before using it for authorization. It verifies:

* **Signature**: Is the token cryptographically valid?

* **aud**: Is it valid in this trust domain?

* **exp**: Is it still current?

* **Transaction context**: Does this context authorize the requested activity?

If the workload makes another downstream call as part of the same call chain, it propagates the transaction token onward unchanged to provide execution continuity.

## How transaction tokens relate to other concepts

### The difference between principals and requesting workloads

The TTS identifies the requesting workload using the `req_wl` claim. This answers which workload requested the transaction token.

This isn't the same thing as the transaction principal. In a human-driven workflow, Sarah might be the `sub`, while the meeting prep agent is the `req_wl`. This separation is useful in AI systems because the workload executing a transaction and the principal associated with that transaction aren't always the same.

### Transaction tokens versus workload identity

A transaction token contains a `req_wl` claim identifying the requesting workload. This shouldn't be confused with a complete workload identity system.

* [Workload identity](authplayground-spiffe.html) defines which running workload this is.

* Transaction tokens define the trusted transaction context the workload participates in.

In a broader architecture, SPIFFE can establish the identity of the workload requesting the transaction token. The TTS can use trusted workload authentication when deciding whether that workload is authorized to obtain one. These layers complement each other.

### Transaction tokens and token exchange solve different problems

Transaction tokens use the [Token Exchange](authplayground-token-exchange.html) protocol when requesting a token from the TTS, but the architectural purpose differs from the cross-domain token exchange pattern.

* Cross-domain token exchange moves trusted identity and authorization into **another** trust domain.

* Transaction tokens preserve trusted transaction context through a call chain **within** a trust domain.

### Transaction tokens differ from ID-JAG

[ID-JAG](authplayground-xaa-id-jag.html) is used when delegated user identity and authorization need to cross into another authorization domain. Transaction tokens are scoped to one trust domain and carry transaction context through a call chain. A single enterprise AI workflow can use both, but at different points and for different reasons.

## Key takeaways

### Short lifetimes matter

Transaction tokens are deliberately short-lived. They aren't intended to become a broadly reusable enterprise credential. The specification notes that transaction tokens aren't inherently replay-resistant. Short lifetimes are therefore important, and the unique `txn` identifier supports auditing and replay detection.

### Keeping the call chain understandable

Without transaction context, logs from a distributed AI workflow only show which services called each other. A shared `txn` identifier gives those calls a common transaction reference. When workloads log that identifier, the enterprise has a way to associate downstream activity with the transaction that caused it. This is valuable for debugging, authorization analysis, security investigation, and auditing.

Transaction tokens give the trust domain a way to keep context intact. The TTS creates a short-lived, signed token for the transaction that identifies the transaction principal, the requesting workload, the trust domain, and the authorized purpose. Workloads have identities and security controls of their own and the transaction token adds a trusted description of the transaction they're currently participating in.
