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 mode | Configured with | User identity in the downstream token | User identity in audit |
|---|---|---|---|
| Catalyst-hosted using SPIFFE JWT | (default) | Yes — SPIFFE JWT with sub set to the user | Yes |
| External, machine-to-machine | client_credentials_ref | No — the server sees a shared M2M client | Yes |
| External, static bearer | secret_ref | No — the server sees a static bearer token | Yes |
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
- Troubleshooting — resolve
obo.exchange_failedandobo.token_identity_absent. - Control tool access — set the auth mode that shapes what the downstream server sees.