Share via

User Identity Passthrough for Hosted Agents Calling a Custom MCP Server

Cristopher Coronado 20 Reputation points MVP
2026-04-27T14:07:04.3233333+00:00

Summary

We are building a Python Hosted Agent in Azure AI Foundry that calls a custom remote MCP server protected by Entra ID. We need the MCP server to receive the end user's identity, not the agent's identity, so authorization decisions on the MCP side can be made per user.

Prompt Agents created in the Foundry portal already support this pattern when wired to a tool with OAuth Identity Passthrough (docs). On the first prompt that requires the tool, the response includes an oauth_consent_request with a consent_link; the user signs in, and subsequent calls carry the user's token to the MCP server.

We want the equivalent experience for Hosted Agents (containerized, code-first), but cannot find documentation or a sample showing whether a Hosted Agent's container code can consume an OAuth Identity Passthrough project connection, or trigger the same oauth_consent_request flow from inside the agent's tool invocation.

Environment

Item Value
Hosting type Azure AI Foundry Hosted Agent (container deployed via agent.yaml + ACR image)
Runtime Python 3.12
SDKs agent-framework-core, agent-framework-foundry, agent-framework-foundry-hosting, mcp
Auth library azure-identity (AsyncManagedIdentityCredential, AsyncAzureCliCredential, OBO attempted)
MCP server Remote streamable HTTP MCP, protected by Entra ID, custom API audience (api://<app-id>)
Agent identity Foundry-managed identity of type agentIdentityBlueprint (federated credential fmi-fic only)

What Already Works

When running the agent locally, we use AsyncAzureCliCredential. The developer is signed in via az login, the credential mints a token for the MCP server's audience, the MCP server receives that token, and the call is authorized as the developer. End-to-end identity propagation works in this local mode because the developer's identity is the one acquiring the token.

When running in Foundry as a Hosted Agent, falling back to AsyncManagedIdentityCredential (or DefaultAzureCredential, which resolves to the same managed identity inside the container) at the MCP server scope also works, but the MCP server only ever sees the agent's identity, never the end user's. This matches the documented behavior of agent identity tool authentication, where the agent acts as itself, not on behalf of the user. It is fine for service-to-service calls, but not for per-user authorization.

Desired Behavior

  1. User opens the agent in the Foundry chat (or any Foundry client). No sign-in dialog appears yet.
  2. User sends a prompt that triggers a tool call to the MCP server.
  3. The agent attempts to call the MCP server with the user's identity. If no user token is available, the chat surfaces a sign-in / consent prompt — same UX as a Prompt Agent with an OAuth2 Identity Passthrough tool.
  4. After sign-in, the MCP server receives a token whose oid / upn claims identify the end user.
  5. The token is valid against the MCP server's custom audience, not against https://ai.azure.com.

The handshake does not need to happen at chat-open time. Lazy resolution on the first tool call is acceptable and matches the Prompt Agent UX.

What We Have Tried

1. Direct MCP connection with MCPStreamableHTTPTool and credential fallback

Implementation: an MCPStreamableHTTPTool whose httpx.AsyncClient uses a custom httpx.Auth. The auth class:

  • Captures the caller's bearer token via an ASGI middleware that stores it in a ContextVar.
  • Falls back to AsyncManagedIdentityCredential (in Foundry) or AsyncAzureCliCredential (local) at the MCP server scope.

Result: the MI fallback works for the agent's own identity; the local CLI fallback works for the developer's identity. But the caller bearer token captured in Foundry has audience https://ai.azure.com, not the MCP server's audience, so forwarding it as-is to the MCP server fails with AADSTS500011.

2. Foundry Toolbox + Logic Apps APIM connector with OAuth2

We registered the MCP server as a Foundry Toolbox and exposed it via a Logic Apps APIM connector configured with OAuth2. The connector requires interactive consent on every call, which works for human users in the Foundry portal but not for an unattended Hosted Agent running on Managed Identity. The flow returned a consent URL instead of a token. The Hosted Agent code has no documented way to surface this URL through the chat the way Prompt Agents do.

3. On-Behalf-Of (OBO) flow with a separate App Registration

Plan: create a confidential client App Registration, configure delegated permission to the MCP API, and call AsyncOnBehalfOfCredential(tenant_id, client_id, client_secret, user_assertion=<caller_bearer>) inside the MCP auth flow.

Blockers:

  • The Foundry-managed agent identity is of type agentIdentityBlueprint. It cannot hold passwordCredentials or keyCredentials, so it cannot act as a confidential client for OBO. Only a federated credential is exposed and it appears reserved for Foundry internal use.
  • Even with a separate App Registration, the user_assertion must be a token whose audience matches that App Registration. The token Foundry passes to the agent has audience https://ai.azure.com, so OBO would fail with AADSTS50013 ("assertion audience does not match"). The audience requested by the Foundry client is not under our control.

4. Lazy MCP startup handshake

We considered deferring the MCP tools/list initialize until the first user prompt. Technically feasible, but it does not change the audience problem. Without a way for the agent (or Foundry) to obtain a token for the MCP server's audience on behalf of the user, lazy initialization alone does not unblock identity passthrough.

Questions

  1. Can a Hosted Agent (container, code-first) consume a project connection of category RemoteTool configured with OAuth Identity Passthrough (Custom OAuth, with our own App Registration)? If yes, where is this documented and how does the container code read the user's token at runtime?
  2. Can a Hosted Agent emit an oauth_consent_request response item from inside a tool invocation, equivalent to the flow that Prompt Agents get automatically for MCP tools registered in the portal?
  3. Does the Foundry runtime expose an API for the agent container to request a token on behalf of the caller for an arbitrary audience (api://<custom-app-id>/.default), without going through the agent identity blueprint?
  4. Can the Foundry-managed agent identity (type agentIdentityBlueprint) be configured with additional credentials, or otherwise act as a confidential client for OBO, for cases where the customer cannot create a separate App Registration?
  5. If none of the above is supported today, is this on the roadmap for Hosted Agents? What is the recommended interim pattern for per-user authorization on a downstream MCP server when using Hosted Agents instead of Prompt Agents?
Foundry Agent Service
Foundry Agent Service

A fully managed platform in Microsoft Foundry for hosting, scaling, and securing AI agents built with any supported framework or model


1 answer

Sort by: Most helpful
  1. Q&A Assist
    2026-04-27T14:07:31.9933333+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    Hosted agents and Prompt agents currently share the same MCP authentication primitives, but the context only documents OAuth identity passthrough for tools configured in Foundry (Prompt agents and MCP tools added via the portal), not for code-first hosted agents.

    From the available documentation:

    • OAuth identity passthrough is a tool-level/project-connection feature that Foundry Agent Service drives when a tool is configured with OAuth identity passthrough. On first use, Agent Service generates a consent link (oauth_consent_request) and, after consent, uses the user’s token to call the MCP server.
    • This flow is described for MCP tools configured in the Foundry portal and for MCP servers hosted on Azure Functions, where the tool is created with Authentication = OAuth Identity Passthrough and the OAuth app details (client ID/secret, auth URL, token URL, refresh URL, scopes) are provided. After configuration, Foundry gives a redirect URL that must be added to the Entra app registration so Agent Service can complete the OAuth flow.
    • The OAuth identity passthrough scope is explicitly “per tool (connection) name per Foundry project,” and the consent link is surfaced by Agent Service in response.output_item as an oauth_consent_request item when a user first tries to use a new tool.
    • The docs also state that for MCP servers, the supported auth modes are key-based, Microsoft Entra (agent or project managed identity), and OAuth identity passthrough, all configured as part of the tool/connection definition in Foundry.

    The context does not document any of the following for hosted agents:

    • A way for container code to bind to or consume a project connection of type “RemoteTool” with OAuth identity passthrough and read the user’s token at runtime.
    • A mechanism for hosted agent code to emit an oauth_consent_request item itself or otherwise trigger the same consent-link UX that Agent Service provides automatically for portal-configured tools.
    • An API that hosted agent code can call to obtain a token on behalf of the caller for an arbitrary audience (such as api://<custom-app-id>/.default). The documented patterns for MCP auth are:
      • Key-based (API key / function key) via project connections.
      • Microsoft Entra identity using agent identity or project managed identity, where the service requests a token automatically.
      • OAuth identity passthrough, driven by Agent Service when the tool is configured that way.
    • Any capability to configure the Foundry-managed agent identity (agentIdentityBlueprint) with additional credentials or to use it as a confidential client for OBO.

    The only documented way to get per-user OAuth identity passthrough today is to configure the MCP server as a tool with OAuth identity passthrough in Foundry (for example, via the portal or as an MCP tool definition) and let Agent Service manage the consent flow and token storage. In that model, Agent Service:

    • Prompts the user with a consent link on first use of the tool.
    • Stores and refreshes the user’s OAuth credentials.
    • Uses the user’s token when invoking the MCP server.

    For Azure Functions–hosted MCP servers, the documentation explicitly shows how to configure this (client ID/secret, token URL, auth URL, refresh URL, scopes) and notes that OAuth identity passthrough is supported and intended for “production when each user must authenticate with their own identity and user context must be persisted.”

    The context does not provide:

    • Documentation that hosted agents can directly plug into that OAuth identity passthrough connection model.
    • A supported pattern for hosted agents to perform OBO or arbitrary audience token acquisition on behalf of the user.
    • Roadmap or interim guidance specific to hosted agents for per-user authorization to downstream MCP servers.

    Given the available information, the supported pattern for per-user authorization is:

    • Configure the MCP server as an MCP tool in Foundry with OAuth identity passthrough so that Agent Service manages the user consent and token handling.
    • Use key-based or Microsoft Entra authentication (agent or project managed identity) when the agent itself, not the end user, should be the security principal.

    The context does not state that hosted agents can currently achieve the same per-user OAuth identity passthrough behavior programmatically from inside container code, nor does it describe any API or configuration that would enable the five requested behaviors for hosted agents.


    References:

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.