Blank white background with no objects or features visible.

We’re sharing complimentary access to the full Gartner Hype Cycle for AI Governance 2026. Get your copy →

Governing Microsoft Foundry Agents: Identity-First Control for Hosted Agents

By Ashish Dubey

Updated: October 27, 2026

Published: October 27, 2026

TL;DR:

A Foundry agent that calls your MCP servers directly is a tool call with no checkpoint. Route it through the gateway and every call gets an identity, a policy decision, and an audit line.

  • Foundry agents reach MCP servers through the TrueFoundry MCP Gateway, not directly. The gateway authenticates the caller, resolves it to a registered agent, applies policy, and performs the token exchange the MCP server requires.
  • Two access modes: client credentials for unattended agents (the MCP server sees roles with Tool.Invoke, no user), and on-behalf-of for agents acting for a signed-in user (a delegated scp of Tool.Write, with the user named).
  • Each Foundry agent has an Entra agent identity; you register it in the TrueFoundry Agent Registry as identity-provider-backed, matched on the agent identity object ID (client credentials) or the agent-client application ID via azp (on-behalf-of).
  • Unlike Copilot Studio, Foundry agents perform their own exchange, so the agent's own identity can travel with the call — which makes per-hop attribution cleaner.
  • Unregistered agents are refused, not passed through — the gateway is a deny-by-default checkpoint, not a proxy.

Why hosted agents need a checkpoint

Microsoft Foundry makes it easy to stand up an agent and point it at tools. The risk is the same as with any capable agent: once it can call an MCP server holding customer data, "who did that, for whom, and were they allowed to?" has to be answerable — and a direct agent-to-server call answers none of it. Putting the MCP gateway on the path turns every tool call into a governed, attributed event, which is the whole premise of AI agent governance.

Two modes: unattended vs acting for a user

Which mode you use depends on whether a human is in the loop:

Client credentials On-behalf-of
When Unattended agents, no user Agent acts for a signed-in user
Token the MCP server sees roles: Tool.Invoke (app-only) scp: Tool.Write, with the user named
Registry subject Agent identity object ID Agent-client application ID (via azp)
User preserved? No Yes
Client credentials for unattended agents; on-behalf-of when the agent acts for a signed-in user.

How the agent maps to a TrueFoundry identity

Each Foundry agent has an Entra agent identity, governed by an agent identity blueprint. You mirror it into the TrueFoundry Agent Registry as an identity-provider-backed entry — the same registration path every externally-issued agent uses:

Registering the Foundry agent as identity-provider-backed, so Entra proves who it is and TrueFoundry governs what it may reach. Source: TrueFoundry docs.

Entra issues the identity; TrueFoundry enforces the call path. Access is governed by the familiar collaborator grants — which MCP servers the agent may call, and which users it may act for — the model in enterprise MCP access control.

The Entra registrations

Three app registrations do the work, two of them shared across both modes:

Registration Purpose Needed for
mcp-api MCP server audience; exposes the Tool.Write scope and Tool.Invoke app role Both modes
agent-service Audience for agent tokens; the credential the gateway uses for exchange Both modes
agent-client The agent's OAuth client identity for sign-in On-behalf-of only

On the TrueFoundry side, you register the MCP server with Entra inbound auth and an outbound config of Client Credentials (scope /.default) or JWT Bearer for on-behalf-of, then add the agent to the registry and grant it access to the server.

Where teams get this wrong

Leaving token version at 1. Set requestedAccessTokenVersion: 2 on agent-service, or the azp and issuer claims come out wrong and the gateway can't resolve the agent.

Skipping admin consent. Without it, the roles claim is simply missing and client-credentials calls fail with an insufficient-role error.

Resetting a credential without `--append`. It deletes existing secrets. And preAuthorizedApplications replaces rather than merges — re-adding one entry can drop the others.

Comma-separating scopes in Foundry. Scopes there are space-separated; client credentials uses /.default, not named scopes. Small syntax slips here surface as audience or scope errors downstream.

Routing Foundry agents at your MCP servers?

A worked example

A team runs an unattended Foundry agent that enriches records from an internal MCP server. They create the mcp-api and agent-service registrations, expose the Tool.Invoke app role on mcp-api, grant it to agent-service, and admin-consent it. In Foundry they set the MCP connection to "Microsoft Entra — agent identity"; in TrueFoundry they register the server with Entra inbound and client-credentials outbound (/.default), and add the agent to the registry. Now the agent gets an identity token, the gateway exchanges it as agent-service, and the MCP server receives a clean Tool.Invoke application token — with the gateway's audit trail recording which agent made the call. When they later add a user-facing flow, they layer on the on-behalf-of registrations and switch that connection to identity passthrough.

Gotchas worth knowing

  • Foundry agents perform their own exchange, so unlike Copilot Studio the agent's own identity can travel with the call — useful when you need the agent named downstream, not just in the gateway log.
  • Unregistered agents are refused, so an agent that isn't in the registry simply can't call through — deny-by-default, not fail-open.
  • Common errors are claim-shaped: missing_token, insufficient_scope, insufficient_role, and audience mismatches usually trace back to token version, consent, or scope syntax.
  • Cached tokens after a consent change can mask a fix — force a fresh token when validating.
  • Per-hop exchange is evolving; for multi-agent chains, confirm how delegation is stitched in your version.

What the gateway adds, concretely

"Route it through the gateway" is easy to say; it is worth being precise about what that actually buys, because each item is a control a direct agent-to-server call simply does not have:

  • Caller authentication and agent resolution — the incoming token is authenticated and mapped to a registered agent from its claims; an unregistered agent is refused.
  • Per-agent tool scoping — you restrict which tools an agent may call, not just which servers, so a read-only agent cannot reach a write tool that happens to live on the same server.
  • User-delegation limits — in on-behalf-of mode, the agent can only act for users who granted it access, independent of what the user could reach directly.
  • Rate limits and guardrails — applied per server or tool, so an agent in a loop cannot exhaust a downstream system or exfiltrate data unchecked.
  • Token exchange — the gateway mints the exact token the MCP server expects, so the server never has to understand Foundry or Entra specifics.
  • Per-agent audit attribution — every call is recorded against the agent (and, in OBO mode, the user), which is the evidence an auditor asks for.

These hold the same way in both modes; only the token brokering differs. That consistency is the point — you reason about access once, and it applies whether the agent runs unattended or on behalf of a person.

The setup, step by step

The docs split the configuration into two parts: client-credentials first, then on-behalf-of layered on top. Client credentials is the shorter path — roughly eleven steps — and it is worth doing first even if you ultimately want OBO, because it proves the plumbing before you add the user dimension.

  1. Create the mcp-api and agent-service registrations and their service principals.
  2. Configure agent-service with an identifier URI, token version 2, and an access_as_user scope.
  3. Expose the Tool.Invoke app role on mcp-api, grant it to agent-service, and admin-consent it.
  4. Pre-authorize the agent blueprint on agent-service as a separate call, and create a credential on agent-service using --append.
  5. In Foundry, set the MCP connection to "Microsoft Entra — agent identity" with audience api:// plus the agent-service ID.
  6. In TrueFoundry, register the MCP server with Entra inbound and "OAuth2 → Microsoft Entra → Client Credentials" outbound (scope /.default), then add the agent to the registry.

On-behalf-of (part two) builds on that: add a Tool.Write delegated scope on mcp-api, create the agent-client registration with access_as_user and offline_access, pre-authorize agent-client on agent-service (appended, not replaced), set the Foundry connection to "OAuth identity passthrough → custom OAuth", and switch the TrueFoundry outbound config to "JWT Bearer".

Troubleshooting the common failures

Almost every failure here is claim-shaped — the call is refused because a token came out with the wrong version, audience, or scope. The fixes are specific:

Symptom Likely cause Fix
azp / issuer wrong Token version still 1 Set requestedAccessTokenVersion: 2 on agent-service
roles claim missing Admin consent not granted after assigning the app role Grant admin consent on the Tool.Invoke assignment
Existing secrets vanished Credential reset without --append Always use --append on credential changes
Pre-auth entries dropped preAuthorizedApplications replaces, not merges Re-add all entries together
insufficient_scope Scopes comma-separated, or named scope used for client creds Space-separate scopes; use /.default for client credentials

One more that masks a correct fix: after changing consent, a cached token can keep failing — force a fresh token before concluding the configuration is wrong. If the gateway refuses with a registry subject mismatch, confirm the registry subject matches the agent identity object ID (client credentials) or the agent-client application ID on azp (on-behalf-of).

Related reading

Conclusion

Foundry makes agents easy to build; the gateway makes them safe to run. By putting the TrueFoundry MCP Gateway on the path, a Foundry agent's tool calls get an identity Entra issues, an access decision TrueFoundry enforces, the right token exchange for the MCP server, and an audit line naming the agent — and, in on-behalf-of mode, the user too. Client credentials covers unattended work; on-behalf-of covers acting for a person. Unregistered agents simply don't get through.

That is the difference between a hosted agent that can reach your systems and one that reaches them under governance.

Govern every Foundry agent's tool calls.

Try now.

One gateway for all your models, MCP servers, and agents.
No credit card needed.

Start free
Table of Contents

One Gateway for Every LLM, Agent and MCP Server

Book a 30-min with our AI expert

Book a Demo

The fastest way to build, govern and scale your AI

Book Demo
Summarize with
ChatGPT logo by OpenAI
Perplexity AI logo
Blurry red snowflake on white background, symmetrical frosty design with soft edges and abstract shape.

Discover More

No items found.
October 27, 2026
|
5 min read

Governing Microsoft Foundry Agents: Identity-First Control for Hosted Agents

No items found.
October 27, 2026
|
5 min read

Claude vs ChatGPT for Enterprise: Security, Cost, and Control

No items found.
October 27, 2026
|
5 min read

Governing Microsoft Copilot Studio Agents: Identity, Access, and Audit at the Gateway

No items found.
October 27, 2026
|
5 min read

Securing AI Agents with SPIFFE and SPIRE: Workload Identity for Autonomous Agents

No items found.
No items found.

Recent Blogs

Black left pointing arrow symbol on white background, directional indicator.
Black left pointing arrow symbol on white background, directional indicator.

Frequently asked questions

How do Foundry agents reach MCP servers under governance?

Through the TrueFoundry MCP Gateway rather than directly. The gateway authenticates the caller, resolves it to a registered agent, applies access policy, performs the token exchange the MCP server requires, and writes an audit line. Unregistered agents are refused.

What's the difference between client-credentials and on-behalf-of mode?

Client credentials is for unattended agents with no user — the MCP server sees an app-only token with the Tool.Invoke role. On-behalf-of is for agents acting for a signed-in user — the token carries both the user and the agent, with a delegated Tool.Write scope.

How is a Foundry agent registered in TrueFoundry?

As an identity-provider-backed entry in the Agent Registry, matched on the agent identity object ID in client-credentials mode, or the agent-client application ID (via the azp claim) in on-behalf-of mode.

Why is my roles claim missing?

Almost always because admin consent wasn't granted after assigning the Tool.Invoke app role, or because token version is still 1. Set requestedAccessTokenVersion to 2 on agent-service and grant admin consent.

Can the agent's own identity travel with the call?

Yes — Foundry agents perform their own token exchange, so the agent identity can be carried downstream, unlike Copilot Studio agents whose Entra Agent ID stays in the gateway audit trail.

Can I run the gateway in my own cloud?

Yes. The TrueFoundry Gateway can be self-hosted or deployed in your VPC, so agent tokens, exchanges, and audit stay within your environment alongside your Azure resources.

Take a quick product tour
Start Product Tour
Product Tour