User.Read permission. The downstream API authorizes the operation using the user’s access and the application’s consented delegated scopes.
In Microsoft Foundry, you can combine a Microsoft Entra on-behalf-of (OBO) token exchange with x-client-* header forwarding to enable this access. Your application backend exchanges the user’s token for a downstream token, then passes that token to your hosted-agent code. It also sends x-ms-user-identity so Foundry associates the request with the represented user.
This is application-managed OBO and token forwarding, not a token exchange performed by Foundry. The following sections explain the flow, the three request headers, and the minimal code your agent needs.
Prerequisites
- A hosted agent that uses container protocol version 2.0.0. The Python example uses the Responses adapter. See Hosted agent runtime contract.
- A trusted application backend that authenticates users and can perform OBO as a confidential client. Its app registration needs the downstream delegated permissions and consent, such as Microsoft Graph
User.Read. See Microsoft identity platform OBO flow. - A backend workload identity, such as a managed identity or service principal, with Foundry Agent Consumer at the agent or project scope.
- The custom data action
Microsoft.CognitiveServices/accounts/AIServices/agents/endpoints/UserIdentityImpersonation/actionassigned to that same workload identity. This permission enablesx-ms-user-identityand isn’t included in built-in roles. An administrator must grant it as described in Delegate the end-user identity.
Understand the delegated access flow
The backend acts as a middle tier: it remains the caller authorized to invoke Foundry, while the agent accesses the downstream API for the user. End users don’t need Foundry role assignments in this pattern.- Authenticate the user. The client sends a user access token whose audience is the middle-tier API. The backend validates the token and authorizes the user’s request.
- Exchange the user token. The backend authenticates to Microsoft Entra ID as a confidential client and submits the user token as the OBO assertion. Entra ID issues a delegated token for the requested downstream API, subject to consent and policy.
- Authenticate to Foundry separately. The backend obtains a workload token with the
https://ai.azure.com/.defaultscope. This token authorizes the backend to invoke the agent; it doesn’t represent the user’s downstream permissions. - Send tokens and user context. The backend invokes the hosted agent with its Foundry token in
Authorization, the downstream token inx-client-graph-access-token, and the user’s object ID inx-ms-user-identity. - Resolve and forward the request. Foundry authenticates the workload, checks its permission to represent the user, and creates trusted per-request user context. The service forwards the
x-client-*header to the container, but not the caller’sAuthorizationheader. - Call the downstream API. Your agent code reads the delegated token (obtained from the
x-client-*header) and uses it inAuthorizationon the downstream request. The API applies the user’s delegated permissions and returns the authorized data.
Distinguish the three request headers
The headers solve different problems and aren’t interchangeable:
Foundry doesn’t exchange or refresh the token in
x-client-*. Microsoft Graph validates it when your agent calls Graph. Treat downstream tokens as opaque; don’t decode or validate tokens for an API you don’t own.
Derive x-ms-user-identity from the validated user context used for the OBO exchange. Both headers must refer to the same user. Don’t copy an object ID or token from untrusted client-supplied headers.
Pass the tokens and user identity
Use your existing backend’s OBO implementation rather than building a separate authentication flow inside the agent.-
Acquire a delegated token for the downstream API. For Microsoft Graph
/me, requesthttps://graph.microsoft.com/User.Read. Use a supported authentication library, such as MSAL, and obtain consent before the OBO request. For implementation details, see Acquire tokens with MSAL Node and the OBO sample. -
Acquire the backend’s Foundry workload token, then send all three headers on the same request:
Reference: Custom header forwarding, End-user identity delegation. Replace
<hosted-agent-responses-endpoint>with your deployed agent’s full Responses URL:https://<account>.services.ai.azure.com/api/projects/<project>/agents/<agent>/endpoint/protocols/openai/responses?api-version=v1. -
Check both the HTTP status and the Responses status. A successful invocation has
status: completed; a handler failure can appear in the Responses lifecycle even when HTTP succeeds.
x-ms-user-identity is included even though the request doesn’t use conversation history, so Foundry and the downstream API represent the same user.
Read the token in your agent
The Python Responses adapter exposes forwardedx-client-* headers through ResponseContext.client_headers, with lowercase keys. The following helper reads the token for the current request and calls a fixed Microsoft Graph endpoint.
- Use an existing Responses handler with
azure-ai-agentserver-responsesandhttpxinstalled. For server setup, see the Python Responses sample. - Call
await read_user_profile(context)from your handler and use the returned display name in its response.
Keep user identity and state aligned
Downstream authorization and Foundry user isolation are separate. Forwarding a delegated token doesn’t, by itself, identify the user to Foundry. Withoutx-ms-user-identity, Foundry sees the backend workload as the caller, even when each request carries a different user’s downstream token.
With authorized end-user delegation on protocol 2.0.0, Foundry exposes the resolved user through get_request_context().user_id in the Python AgentServer SDK. Use that trusted context for user-owned state, not an arbitrary x-client-user-id value. The platform also supplies a per-request call ID for supported calls to Foundry services; that call ID isn’t a Microsoft Graph access token.
Foundry scopes platform-managed conversation history to the resolved user. Your container must separately partition its own files, database rows, and caches by session and resolved user ID. See Multiplex multiple users in one hosted agent session.
Choose the authentication approach
Use token forwarding only when the backend and hosted-agent container are trusted components of the same application. Passing a bearer token into the container gives its code access to the token’s delegated permissions.Protect tokens and handle expiration
Keep tokens out of prompts, model inputs, request bodies, response metadata, conversation history, checkpoints, outputs, exceptions, and logs. Redact both
Authorization and the custom token header in proxies and telemetry.- Request only the necessary delegated scopes. Use a separate token for each downstream audience, and never send refresh tokens or confidential-client credentials to the agent.
- Keep tokens request-scoped and restrict them to approved HTTPS destinations. Don’t let model output choose a URL that receives a token, and don’t follow redirects with credentials.
- For longer work, split operations into requests so the backend can obtain fresh tokens. Don’t persist token-bearing headers for background execution or crash recovery.
- Return authentication failures to the backend to reacquire a token or challenge the user. If consent or Conditional Access requires interaction, preserve the OBO claims challenge. Never switch silently to app-only access.
Verify the flow and troubleshoot
Test through your deployed backend and Foundry Service, not just the local container.- Sign in as two different users who each consent to the required permissions, and invoke the agent for each user. Confirm that Graph returns each user’s own profile.
- Remove the
x-client-graph-access-tokenheader in a controlled test. Confirm that the agent fails without calling Graph. - Use an expired or invalid Graph token. Confirm that the failure reaches the backend without an app-only retry.
- If you use conversation history, verify that one user can’t continue another user’s response chain. Follow Verify isolation.
Related content
- Hosted agent runtime contract describes header forwarding and platform-generated user context.
- Microsoft identity platform OBO flow explains token audiences, consent, and authentication challenges.
- Toolbox authentication describes managed alternatives to application-owned token forwarding.