Skip to main content
Use this guide when you have agents in Microsoft Foundry (formerly Azure AI Foundry) and MCP servers hosted in your own Azure subscription. Instead of letting agents call those servers directly, you route the calls through the TrueFoundry MCP Gateway. The gateway authenticates the caller, resolves it to a registered agent, applies your access policy, and performs the token exchange the MCP server requires. Your MCP server never has to trust a raw agent token, and every call is attributable in the audit trail.
Entra Agent ID and its Foundry integration are evolving quickly, and parts are in preview. The flows below reflect the documented model as of mid-2026 — verify feature status against Microsoft’s Entra Agent ID documentation before depending on specifics.

What you are setting up

Prerequisites

  • A Microsoft Foundry project with at least one agent, and permission to create app registrations in the same Entra tenant.
  • An MCP server running in your Azure subscription that validates Entra JWTs. To write one, see Create an OAuth MCP server with Azure Entra.
  • Azure CLI signed in to the tenant (az login), plus jq and uuidgen for the commands below.
  • Entra registered as an identity provider in TrueFoundry. See Identity Providers.
  • An MCP Server Group in TrueFoundry. See MCP Gateway getting started.

Mapping an Entra Agent ID to a TrueFoundry agent

When you create an agent in Foundry, Entra mints an agent identity for it — a service principal that represents that agent, governed by an agent identity blueprint. Find its object ID in the Azure portal on your project or agent resource, under JSON view. To make the gateway aware of that agent, create an entry in the Agent Registry: On every call the gateway reads the identity out of the incoming token and matches it against this entry. Once an agent resolves, you can:
  • Scope tool access per agent — which MCP servers, and which tools on them, this agent may call.
  • Control who it may act for — in on-behalf-of mode, which users this agent is allowed to represent.
  • Attribute every call — the audit trail records the agent, not just the application that authenticated.
  • Apply guardrails and limits per agent rather than per credential.
The claim the gateway matches on differs between the two modes: client credentials matches the token subject, and on-behalf-of matches azp. Each part below states which to use.

The blueprint, and governing agents as a class

Every agent identity is created from an agent identity blueprint — the governing template for a class of agents. Foundry provisions one for your project and creates each agent identity from it. The blueprint holds the credentials; the agent identities themselves hold none, which is why an agent identity cannot be used as a sign-in client. The blueprint is where class-level controls apply:
  • Conditional Access policies applied to the blueprint cover every agent created from it.
  • Disable or revoke once to affect the whole class, rather than chasing individual agents.
  • Audit and inventory agents by class as their number grows.
The blueprint’s application ID also travels in the token, in the xms_par_app_azp claim. That gives you a tier-level check independent of any individual agent: a gateway policy or an MCP server can require that a caller was minted from your blueprint, rather than accepting any agent identity that happens to exist in the tenant. The blueprint ID appears alongside the agent identity in the same JSON view on your project or agent resource. It is also what authorizes your agents against the agent-service audience in the first place — see step 5 of Part 1.
Register individual agents in the Agent Registry for day-to-day scoping and attribution; use the blueprint for controls that should apply to an entire class at once. They are complementary, not alternatives.

App registrations you need

Foundry creates the agent identity and its blueprint for you. You create the rest in Entra.
Entra requires that the application performing an on-behalf-of exchange is the audience of the token it redeems. The gateway therefore exchanges as agent-service, using its client secret. There is no TrueFoundry application registration in your tenant.

Choosing between client credentials and on-behalf-of

Both modes run through the same gateway and the same MCP server. You can register both and run them side by side.

Part 1: Client credentials

The agent authenticates with its own Entra agent identity. No user is involved, and the MCP server authorizes the call on an application permission.
Client credentials flow: the Foundry agent obtains an agent identity token whose subject is the agent identity and which carries no user, the TrueFoundry MCP Gateway resolves the agent from that subject and exchanges the token as agent-service against api://mcp-api/.default, and the MCP server receives an application token carrying the Tool.Invoke role.
The agent identity is proven end to end. Because no user ever enters the chain, there is no user identity to lose.
1

Create the two application registrations

The service principals are required. Without one, an application cannot be consented to and cannot be named as a resource in a token request.
2

Configure agent-service with an identifier URI, v2 tokens, and a scope

Set the token version to 2. This is the easiest setting to miss and the hardest to diagnose. Version 1 tokens name the calling application in appid rather than azp, and carry a different issuer (sts.windows.net). Both break gateway configuration that is otherwise correct — and on-behalf-of agent resolution depends on azp specifically.
The identifier URI must exist before you can use api://$AGENT_SVC as an audience anywhere else.
3

Expose the application permission on mcp-api

4

Grant the permission to agent-service and admin-consent it

Consent, or nothing changes. Without it Entra still issues the token — just without the roles claim, so the call fails at your MCP server, not the gateway. Allow a moment for it to propagate.
5

Authorize your agents on agent-service, through the blueprint

Entra issues an agent identity a token for agent-service only if that audience authorizes it. List your blueprints, then pre-authorize them:
Why the blueprint and not the agent. Agent identities hold no credentials of their own and cannot be consented interactively — an attempt returns AADSTS82014. Authorization is granted once at the class level, on the blueprint, and every agent identity created from it inherits the grant. Add an agent to the project later and it works with no further Entra change.This is the tier-level control in practice: the blueprint decides which agents may obtain a token for your agent tier at all, while the permission granted in the previous step decides what the gateway may then do downstream. The two are independent, and you need both.
Send this as a second call. Graph validates preAuthorizedApplications against already-persisted scopes, so creating a scope and pre-authorizing it in one request fails with InvalidValue.
6

Give the gateway a credential

Always pass --append. Without it, credential reset deletes every existing secret on the application, silently breaking anything else already using it.
7

Configure the Foundry MCP connection

Set the auth type to Microsoft Entra — agent identity, the audience to api://$AGENT_SVC, and the server URL to your TrueFoundry MCP Gateway URL.
Audience, not URL. The audience is the OAuth resource identifier of the exchanging application — not the address of the MCP server. An incorrect audience fails authentication even when every role assignment is right.
8

Register the MCP server in TrueFoundry

Register the server against your MCP server URL:
  • Inbound: your Entra identity provider.
  • Outbound: OAuth2 → Microsoft Entra → Client Credentials, with the agent-service client ID and secret, and scope api://$MCP_API/.default.
For the full field reference on this auth type, see Microsoft Entra app setup.
Store client_secret as a TrueFoundry Secret FQN rather than a raw value.
Client credentials uses /.default, not a named scope. The application permissions you granted determine what the token carries; requesting api://$MCP_API/Tool.Write here fails, because that is a delegated scope and there is no user.
9

Register the agent in TrueFoundry

Add an Agent Registry entry:The registry entry shadows the Foundry agent. It creates no new credential and no second principal — it is a governance record keyed to the same Entra agent ID that Foundry already minted, so the agent Microsoft runs and the agent TrueFoundry governs are one identity seen from two sides.That is what makes the attribution trustworthy: the gateway is not labelling the call from configuration you typed, it is reading the agent identity out of the token Entra signed and looking up the entry that claims it. Grants, tool scope, guardrails, and audit all attach to that entry, and they apply to the Foundry agent itself rather than to a stand-in for it.
Register one entry per Foundry agent whose calls you want scoped and attributed separately. Agents you leave unregistered do not resolve, so their calls are refused rather than silently passed through — which is what makes registration the chokepoint.

What your MCP server receives

Validate the audience, then require Tool.Invoke in roles.

What you can enforce

All of it is agent-scoped. There is no user in this mode, so no user-scoped policy applies.

Part 2: On-behalf-of

A signed-in user consents once, and the agent then calls tools with that user’s delegated permissions. The token carries both the user and the agent, so the gateway can attribute and authorize on both.
On-behalf-of flow: the user consents once through the agent-client application, producing a token that carries the user in oid and the agent in azp. Both identities arrive at the TrueFoundry MCP Gateway together, which resolves the user from oid and the agent from azp, then performs an on-behalf-of exchange as agent-service so the MCP server receives a delegated token naming the user with the Tool.Write scope.
The agent is identified by azp — the OAuth client that obtained the token. This is why on-behalf-of needs its own agent-client registration. Part 2 builds on Part 1: complete steps 1 through 6 above first, then continue here.
1

Expose a delegated scope on mcp-api

Sending oauth2PermissionScopes replaces the whole collection. Include any scopes you already have.
2

Create the agent-client registration

Use a registration that represents the agent. azp names whichever client obtained the token, and it is the only place an agent can appear in a delegated token. Reuse a general-purpose client and the gateway sees that client, not the agent.
3

Give agent-client its delegated permissions and consent them

offline_access is what yields a refresh token. Without it the user is re-prompted every time the access token expires.
4

Pre-authorize agent-client on agent-service

This step is optional but recommended: it suppresses a per-user consent prompt on this scope, so users are not asked to approve something an administrator has already approved.
This field replaces, it does not merge. Sending only the new entry drops the Part 1 blueprint authorization and silently breaks client-credentials mode. Read the current value and append.
5

Grant agent-service the delegated scope on mcp-api

This is what lets the gateway complete the on-behalf-of exchange. It is the delegated form of the same permission you granted as an application role in Part 1 — an application needs both if it supports both modes.
6

Configure the Foundry MCP connection

Set the auth type to OAuth identity passthrough → custom OAuth, using the agent-client ID and secret, and your tenant’s v2.0 endpoints:Register the redirect URL Foundry returns after saving:
Scopes are space-separated, not comma-separated. A comma is accepted by the form and fails later at token time, where it reads like a permissions problem.
Use an audience you control. Foundry refuses to send a token with a well-known Microsoft audience to a custom MCP endpoint. Because the scope above resolves to agent-service — your own registration — this is the supported shape.
7

Register the MCP server in TrueFoundry

Set Outbound to OAuth2 → Microsoft Entra → JWT Bearer, with the agent-service client ID and secret, and scopes api://$MCP_API/Tool.Write offline_access.For the full field reference on this auth type, see Microsoft Entra On-Behalf-Of for MCP.
Store client_secret as a TrueFoundry Secret FQN rather than a raw value.
8

Register the agent in TrueFoundry

Add an Agent Registry entry:Unlike Part 1, there is no single Entra object here that is the agent. The Entra agent identity cannot appear in a delegated token at all, so the Foundry agent is represented by an agent-service / agent-client pair: agent-client is the OAuth client that signs the user in and therefore lands in azp, and agent-service is the audience it targets and the credential that performs the downstream exchange. Between them the pair stands in for the Foundry agent — one half naming it on the way in, the other acting for it on the way out.
A different claim from Part 1. On a delegated token the subject is the user, not the agent. An entry matched on the subject will never resolve the agent here — it must match azp.
Running both modes for the same Foundry agent means two registry entries — one keyed to the Entra agent identity for unattended calls, one keyed to agent-client for delegated calls. Give them matching owners so the two legs of the same agent stay attributable to one team.

What your MCP server receives

Validate the audience, then require Tool.Write in scp. The user is in the standard claims — use oid as the stable key rather than sub, which is unique per application.

What you can enforce

Permissions intersect. A delegated token can only carry permissions the user actually has and that the agent has been granted. Neither party can exceed its own access by going through the other — which is the main reason to choose on-behalf-of over client credentials.

Comparison, limits, and scale

One limit worth knowing

A single Entra token cannot carry both an end user and an Entra agent identity. Agent identities appear only in application tokens, where there is no user; a delegated token names its agent through azp, which is an ordinary application registration. If you need both, run the modes side by side — the gateway records the agent on every call in either case, so the two legs can be correlated in the audit trail.

Scaling to many agents

Point every agent at the same agent-service audience. The audience identifies the tier of callers, while each agent is still distinguished by its own identity in the token, so the number of gateway registrations stays proportional to your MCP servers rather than to your agents. Adding an agent means one Agent Registry entry, not a new application registration.
With a shared audience, per-agent permissions are enforced at the gateway rather than by separate Entra grants. Keep separate audiences only where a requirement demands that the identity provider itself draws the line.

Troubleshooting

Most failures in this chain surface a hop or two away from their cause. For gateway-side connectivity and OAuth debugging, see the MCP troubleshooting guide.

Next steps