> ## Documentation Index
> Fetch the complete documentation index at: https://www.truefoundry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TrueFoundry with Okta AI Agent

> Register agents as first-class Okta AI Agent identities and let the TrueFoundry gateway broker ID-JAG token exchange across every hop of the agentic call path.

<Info>
  **Coming Soon** — this page is a work in progress. It will document how
  TrueFoundry integrates with [Okta for AI
  Agents](https://www.okta.com/products/govern-ai-agent-identity/) so that
  agents carry first-class Okta identities and the gateway performs ID-JAG
  exchange at every hop.
</Info>

## Overview

When an agent calls another agent, which calls an MCP server, the request that started as "summarize my open tickets" becomes a chain of calls made by software, not by the user. If each hop simply forwards the user's token, the resource at the end sees only the user — it cannot tell which agent acted, under whose authority, or whether that agent was allowed to. Attribution and scoped-down access both disappear at the first hop.

[Okta for AI Agents](https://www.okta.com/products/govern-ai-agent-identity/) closes the identity half of that gap. An agent is registered in Okta's Universal Directory as a **first-class non-human identity** — with a human owner, a managed lifecycle, and the entitlement to perform **agent-to-agent token exchange**. Each hop mints a fresh [ID-JAG](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/) audienced to the next callee's authorization server, keeping the user as `sub` while nesting the acting agent into the `act` chain.

TrueFoundry closes the enforcement half. The **Agent Gateway** and **MCP Gateway** sit on every hop of the call path and perform the exchange on the chain's behalf — so no agent author writes a two-legged token exchange, and policy, scope, and audit stay consistent no matter which framework built the agent.

Together they give you:

| Capability                        | What it means                                                                                                                                     |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Per-agent identity**            | Every agent presents its own Okta identity, distinct from the user's and from any shared service account.                                         |
| **Delegation, not impersonation** | The downstream token keeps the user as `sub` and records each acting agent in a nested `act` claim.                                               |
| **Scope narrowing at each hop**   | Every hop gets a token audienced to exactly one callee, rather than a broad token forwarded unchanged.                                            |
| **Unified enforcement**           | The gateway applies [access control](/docs/ai-gateway/gateway-access-control) and [guardrails](/docs/ai-gateway/guardrails-overview) at each hop. |
| **End-to-end audit**              | Each call is attributable to both the user and the specific agent that made it.                                                                   |

<Note>
  Okta AI Agents is a **separate, paid Okta product**, distinct from Cross App
  Access (XAA). If you are not licensed for it, the single-hop XAA and OBO
  patterns still work on base Okta with a custom authorization server — see
  [Limitations](#limitations) and the [agent governance
  blog](/docs/blog/end-to-end-agent-governance-part-1) for the fallback
  patterns.
</Note>

## Okta application vs Okta AI Agent

The rest of this guide leans on two Okta terms that are easy to conflate. They are **different kinds of principal**, and which one you register determines what a hop can do.

**Okta application** — a client or resource that Okta knows about, registered as an OIDC/OAuth client. In an exchange it plays the **requesting app** (the thing acting for a signed-in user) or the **resource app** (the protected target). Registering an application is base Workforce Identity functionality — **no AI-agent product required**.

**Okta AI Agent** — an autonomous actor registered as a **first-class non-human identity** in Okta's Universal Directory through [Okta for AI Agents](https://www.okta.com/products/govern-ai-agent-identity/). It is still an OAuth client underneath, but registering it *as an agent* adds an **owner** (a human accountable for it) and — the part this guide depends on — the entitlement to perform **[agent-to-agent token exchange](https://developer.okta.com/docs/guides/ai-agent-to-agent-token-exchange/agent-to-agent/main/)**, the onward per-hop ID-JAG minting a multi-agent chain needs.

|                           | Okta application                                         | Okta AI Agent                                                     |
| ------------------------- | -------------------------------------------------------- | ----------------------------------------------------------------- |
| **Registered as**         | OIDC/OAuth client                                        | Non-human identity in Universal Directory                         |
| **Has a human owner**     | No                                                       | Yes                                                               |
| **Role in an exchange**   | Requesting app or resource app                           | Acting agent — an actor in the `act` chain                        |
| **Can seed the next hop** | No — a single requesting-app → resource-app relationship | Yes — mints an onward ID-JAG from the previous hop's access token |
| **Licensing**             | Base Workforce Identity                                  | Paid **Okta for AI Agents**                                       |

The short version: an Okta application is any client or resource Okta knows about; an Okta AI Agent is that **plus** first-class agent identity, ownership, and onward token exchange.

### Which one to register for each hop

In a chain like `client app → Agent A → Agent B → MCP server`:

* The **client app** is an Okta **application** (the requesting app) — the user signs into it and it obtains the Okta ID token that seeds the chain.
* **Agent A** and **Agent B** are Okta **AI Agents**, because each one both receives a call and makes the next one. Only an AI Agent can mint the onward ID-JAG.
* The **MCP server** is an Okta **application** in the resource-app role — it is a target, not an actor, so it does not need to be an AI Agent.

<Tip>
  Register as an AI Agent only what genuinely *acts*. A terminal MCP server is a
  resource; making it an AI Agent adds licensing cost and lifecycle overhead
  without adding capability.
</Tip>

### Delegations and resource connections

Once an agent exists in Okta, two settings on its detail page define the edges of the chain it can participate in. They are the **inbound** and **outbound** halves of the same relationship, and both must be in place for a hop to work:

| Setting                  | Direction | What it answers                                                                                                      |
| ------------------------ | --------- | -------------------------------------------------------------------------------------------------------------------- |
| **Delegations**          | Inbound   | Who or what can call this agent — the users, apps, and other AI agents that may authorize it to act on their behalf. |
| **Resource connections** | Outbound  | Which resources this agent is configured to access — the next agent, an MCP server, or another protected API.        |

For the hop `Agent A → Agent B`, that means a **delegation on Agent B** naming Agent A, and a **resource connection on Agent A** pointing at Agent B. Okta collapses this for you in one case:

<Info>
  When you delegate an AI agent to **another AI agent**, Okta **automatically
  creates the matching resource connection** between them. For every other
  delegation type — a user signed into an app, or a non-human identity such as a
  service — you configure the resource connection separately.
</Info>

A resource connection also carries a **type**, and the type decides which token the agent ends up presenting downstream:

| Resource type            | What it does                                                                                                                                                                    | Where it fits here                                                               |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| **Authorization server** | Grants access to resources protected by an Okta **custom authorization server**.                                                                                                | The main path for this guide — agent-to-agent hops and Okta-fronted MCP servers. |
| **Resource server**      | Uses a **third-party access token** issued by the third party's own authorization server and **brokered by Okta**. Requires user consent before the agent can act for the user. | A terminal third-party MCP server that is not fronted by an Okta custom AS.      |
| **Application**          | An [OIN](https://developer.okta.com/blog/2026/07/06/submit-oin-xaa) app instance or a custom resource server.                                                                   | Targets Okta already knows about as applications.                                |

<Note>
  The **Authorization server** and **Resource server** types are the two that
  change the shape of the flow. With **Authorization server**, Okta mints an
  ID-JAG audienced to that server and the gateway redeems it for a scoped token.
  With **Resource server**, Okta does **not** mint an ID-JAG — it brokers a
  token issued by the third party instead. That distinction is why the terminal
  hop differs between an Okta-fronted and a third-party MCP server.
</Note>

<Warning>
  Configuring delegations for **non-human identities** requires a **custom
  authorization server** — that is what registers the AI agent as a protected
  resource other agents and services can call. An agent without one can make
  outbound calls but cannot be the target of an agent-to-agent hop.
</Warning>

## Prerequisites

**In Okta**, you need:

* An **[Okta for AI Agents](https://www.okta.com/products/govern-ai-agent-identity/)** subscription — the separate paid product that provides agent registration and the agent-to-agent token exchange this flow depends on.
* **Admin access** to register AI agents and create custom authorization servers.

**In TrueFoundry**, you need permission to register an [agent](/docs/agent-platform/agent-governance/agent-registry#registering-an-agent), an [identity provider](/docs/platform/identity-providers), and an [MCP server](/docs/ai-gateway/mcp/mcp-server-getting-started).

## How it works

*Sequence: user ID token → ID-JAG audienced to the callee's custom authorization server → redeemed access token → next hop seeded by the previous hop's access token, with `act` nesting at each step.*

```mermaid theme={"dark"}
sequenceDiagram
    participant C as Client App
    participant AGW as TFY Agent Gateway
    participant A1 as Agent A
    participant A2 as Agent B
    participant MGW as TFY MCP Gateway
    participant Okta as Okta
    participant MCP as MCP Server
    C->>AGW: Invoke Agent A with Okta ID token
    AGW->>Okta: token-exchange, subject=ID token, requested=ID-JAG, aud=Agent A custom AS
    Okta-->>AGW: Fresh ID-JAG, redeemed to access token
    AGW->>A1: Forward, sub=user
    A1->>AGW: Invoke Agent B
    AGW->>Okta: token-exchange, subject=prev access token, requested=ID-JAG, aud=Agent B custom AS
    Okta-->>AGW: Fresh ID-JAG, act chain nests Agent A
    AGW->>A2: Forward, sub=user act=Agent A
    A2->>MGW: Call MCP tool
    MGW->>Okta: token-exchange, requested=ID-JAG, aud=MCP custom AS
    Okta-->>MGW: Fresh ID-JAG, redeemed to scoped token
    MGW->>MCP: Call tool with scoped token
    MCP-->>MGW: Result
    MGW-->>A2: Result
    A2-->>AGW: Result
    AGW-->>C: Result
```

## Okta setup

<Steps>
  <Step title="Register each agent as an Okta AI Agent">
    *Universal Directory registration, assigning a human owner, and the OAuth
    client that backs the agent identity.*
  </Step>

  <Step title="Give each agent a custom authorization server">
    *Why the AS issuer becomes the `audience` of the ID-JAG minted for calls
    into that agent; when to share one AS versus one per agent.*
  </Step>

  <Step title="Register the terminal MCP server as a resource">
    *Connected-resource types and which one applies to an Okta-fronted MCP
    server versus a third-party one.*
  </Step>

  <Step title="Authorize the connections along the chain">
    *client → Agent A, Agent A → Agent B, Agent B → MCP. Each connection is what
    lets Okta mint a fresh ID-JAG for that hop.*
  </Step>
</Steps>

## TrueFoundry setup

<Steps>
  <Step title="Configure ID-JAG Auth Data on each agent">
    *Auth Type, Grant Type = ID-JAG (Okta AI Agent), Resource Token URL,
    Resource Client ID, Private Key, Issuer URI.*
  </Step>

  <Step title="Configure ID-JAG Auth Data on the MCP server">
    *Same grant type, pointed at the MCP's custom authorization server for the
    final hop.*
  </Step>

  <Step title="Grant access along the chain">
    *Collaborators / virtual accounts that authorize each caller to invoke the
    next agent or MCP server.*
  </Step>
</Steps>

### Configuration reference

*Field-by-field table for the ID-JAG (Okta AI Agent) Auth Data form.*

## Verifying the setup

*How to confirm the exchange is happening: what to look for in the gateway logs, the claims to expect on the downstream token (`sub`, nested `act`), and common failure modes.*

## Limitations

*What requires the paid Okta AI Agents product, what falls back to OBO or plain OAuth, and where the actor chain breaks.*

## FAQ

<AccordionGroup>
  <Accordion title="Does the terminal MCP server need to be registered as an Okta AI Agent?">
    *TODO*
  </Accordion>

  <Accordion title="Can the chain start from an access token instead of an ID token?">
    *TODO*
  </Accordion>

  <Accordion title="What happens at a hop that is not registered in Okta?">
    *TODO*
  </Accordion>
</AccordionGroup>

<Note>
  Related reading: [Agent Identity &
  OBO](/docs/ai-gateway/agents/agent-identity-obo), [Agent
  Identity](/docs/ai-gateway/agents/agent-identity), and the [Agent
  Governance](/docs/agent-platform/agent-governance/overview) section.
</Note>
