Skip to main content

On behalf of

On-behalf-of (OBO) carries the user identity from the caller all the way to the downstream MCP tools your agent invokes. Catalyst handles this automatically — your agent writes no OBO code. For where this fits, see the Enterprise identity overview and the trust model in Security.

How it works

When your agent calls an MCP tool, the request passes through the Catalyst MCP proxy. For an agent running under enterprise identity, the proxy mints a delegated token that asserts the original user's identity, using Catalyst's delegation grant (the RFC 8693 token-exchange standard). It attaches that token to the forwarded call.

Your agent calls the MCP tool exactly as it would without enterprise identity — the same code that connects an MCP client to the proxy endpoint. The identity propagation is transparent:

# The agent makes an ordinary MCP tool call.
# Catalyst mints and attaches the delegated user token — no OBO code here.
result = await mcp_client.call_tool("search_orders", {"customer": "acme"})

What the downstream server sees

Whether the user's identity reaches the MCP server — or is preserved only in the audit trail — depends on the auth mode configured on the MCPServerAccessPolicy for that server:

Auth modeConfigured withUser identity in the downstream tokenUser identity in audit
Catalyst-hosted using SPIFFE JWT(default)Yes — SPIFFE JWT with sub set to the userYes
External, machine-to-machineclient_credentials_refNo — the server sees a shared M2M clientYes
External, static bearersecret_refNo — the server sees a static bearer tokenYes

Only Catalyst-hosted mode puts the user identity into the token the server verifies. The two external modes authenticate Catalyst to the server with a shared credential; the user identity is recorded in the audit trail but is not present in the token the server sees. See Authentication for MCP servers for how each credential is configured.

Inspect an OBO call

The Catalyst console does not surface an OBO audit view at this time. To observe an OBO exchange, read the API logs and route them to your own observability backend. Each exchange emits one of:

  • mcp_obo.exchange_started — the proxy began minting a delegated token.
  • mcp_obo.exchange_completed — the token was minted and attached to the forwarded call.
  • mcp_obo.exchange_failed — the exchange failed; the downstream call did not carry a user token.

For a failed exchange, see the obo.* codes in Troubleshooting.

What's next