Dev.to · 12 min read

Microsoft Foundry Agent Permission Governance: OBO, RBAC, and Approval Boundaries

Microsoft Foundry Agent Permission Governance: OBO, RBAC, and Approval Boundaries

The previous article, Microsoft Foundry Agent Identity Governance: Agent Identities, Blueprints, and Managed Identities mapped the relationships among User Identity, Agent Identity, Agent Identity Blueprint, and Project Managed Identity. This article turns that identity model into a permission ledger, a publish-time migration plan, and a set of negative tests. It uses one scenario to answer three practical questions: When should an agent use On-Behalf-Of (OBO), and when should it use Agent Identity? Why can an agent work in development and suddenly return a 403 after publication? If RBAC is already in place, why do high-risk tools still need approval? Scenario: A Customer Meeting Preparation Agent Suppose a sales team wants an agent to perform three types of work: A salesperson asks, “Help me prepare for tomorrow's meeting with Setoro.” The agent reads the email, calendar events, and documents that this user can access. An enterprise scheduler starts a background job every night. Through an MCP tool that supports Agent Identity, the agent creates a team-level customer summary and writes it to a designated Azure Storage container. After the user confirms, the agent sends the meeting summary to attendees or updates a CRM record. One shared service principal might make all three flows work, but it would also blur their permission boundaries. I would separate them by asking: Who is the agent representing? What can it read or write? Who must approve the action? Task Runtime identity Source of authority Approval requirement Read the current salesperson's email and meetings OBO: user and agent context Intersection of the user's access, delegated scopes, consent, and tenant policies Usually no approval for every call, but the tool should be read-only Generate a team summary in the background and write it to Storage Agent Identity The tool connection supports Agent Identity, and target-resource RBAC is assigned to the current Agent Identity Automate only within a narrow scope; block anomalous or out-of-scope arguments Send email or update CRM records in bulk OBO or a dedicated write identity, depending on business accountability Delegated user permissions or dedicated application permissions Require explicit approval for high-impact actions This table should exist before you configure the tools, not after deployment. For every new action, record six fields: principal, resource, action, scope, approval, and audit. If the team cannot answer any one of them, the design does not yet define an enforceable permission boundary. The identities in the table describe the intended architecture; they do not imply that every tool supports every authentication method. During implementation, check the tool documentation and the connection's authentication type. If a tool supports only a key, OAuth passthrough, or Project Managed Identity, record the resulting sharing, rotation, revocation, and audit risks in the same permission ledger. Path 1: Preserve the User Boundary When the User Is Present The interactive path can be simplified as follows: Sales User Token -> Foundry Agent Service -> OBO Token (Agent + delegated user permissions) -> Microsoft 365 / Downstream Service OBO stands for On-Behalf-Of: the agent acts for the user. It does not copy all of the user's permissions to the agent. Effective access is still constrained by the delegated scopes requested by the application, user or administrator consent, Conditional Access, and downstream authorization. This path requires the caller to invoke the Agent API with the user's Microsoft Entra token. An API key does not carry the delegated user context required by an OBO-authenticated tool. In this example, salesperson A should not gain access to salesperson B's private email merely by using the agent. OBO keeps the agent's read boundary aligned with the current user instead of replacing that user context with one highly privileged background account. Path 2: Use an Independent Agent Identity for Background Work The scheduled summary job has no signed-in user, so it cannot depend on OBO. It should run under its own Agent Identity and receive only the permissions required for the task. This scenario assumes that the agent reaches the downstream resource through an MCP tool that supports Agent Identity authentication. If you choose another tool type, verify the authentication methods it actually supports. For a Prompt Agent, the Agent Identity token exchange can be simplified as follows: Project Managed Identity -> Blueprint -> Agent Identity Token Agent Identity Token -> target audience token -> MCP / Downstream Resource According to the Foundry Agent Identity documentation, the RBAC role on the target resource belongs on the Agent Identity in this flow, not on the Project Managed Identity used to authenticate the blueprint. For example, if the agent genuinely needs read and write access to a Storage Account, the official pattern assigns the role to the current agentIdentityId: az role assignment create \ --assignee "" \ --role "Storage Blob Data Contributor" \ --scope "/subscriptions//resourceGroups//providers/Microsoft.Storage/storageAccounts/" If a newly created Agent Identity cannot be resolved through --assignee because of Microsoft Graph propagation latency, use --assignee-object-id "" --assignee-principal-type ServicePrincipal instead. Storage Blob Data Contributor is not a write-only role. It includes read, write, and delete access to Blob containers and blobs. If the task should only append reports and must not read or delete historical files, evaluate a narrower container scope, a conditional role assignment, a business API, or a custom role. Do not copy a built-in role into production merely because an example uses it. There is one important exception that simplified identity diagrams tend to hide: an MCP connection can explicitly select project-managed-identity. When that is the configured authentication type, the target-resource RBAC assignment belongs on the Project Managed Identity. Troubleshooting must start by checking how the tool connection actually authenticates. The Deployment Order I Use To keep permissions from expanding without control, I use the same five-step sequence for deployment: List the tool contracts. Record every exposed action, its arguments, and its authentication method. Separate read, write, delete, export, and administrative actions. Choose the principal. Use OBO for user data and Agent Identity for background work. Consider Project Managed Identity, keys, or another OAuth method only when the tool connection explicitly requires it. Start with the narrowest scope. Begin at the resource, container, or business API boundary. Do not grant a subscription-level role simply to make testing easier. Rebind permissions after publication. Retrieve the production agent's new agentIdentityId, then migrate each item in the permission ledger. Do not copy every role from development. Test both success and failure paths. Verify not only that the correct user can access the resource, but also that the wrong user, an out-of-scope resource, an unapproved write, and a call after revocation are rejected. This sequence puts permission design before “does it run?” The first configuration may take longer, but it prevents an ever-expanding identity from hiding the actual boundary between the model, connection, and RBAC configuration. Why Does It Work in Development but Return 403 After Publication? Within one Foundry project, unpublished Prompt Agents under development share the project's Agent Identity by default. This reduces repeated configuration during prototyping, but it also expands the shared permission boundary. When an agent is published as an Agent Application, Foundry creates a dedicated blueprint and Agent Identity bound to that application. The new agentIdentityId does not automatically inherit the RBAC assignments of the shared development identity. You must review and reassign the required roles after publication. For the shared development identity, open the Project in the Azure portal, go to Overview → JSON View, select the latest API version, and inspect the agentIdentityId and blueprint ID. After publication, open the corresponding Agent Application resource → Overview → JSON View and copy the new agentIdentityId. If the ID still matches the development identity, first confirm that you opened the Agent Application rather than the Project. Do not keep assigning production roles to the old identity. Hosted Agents have a different lifecycle. Every Hosted Agent deployed to a Foundry project receives its own dedicated Agent Identity and endpoint. The Project Managed Identity supports project-level infrastructure operations, such as allowing the platform to pull an image from Azure Container Registry; it is not the agent's runtime identity. Access to external business resources must still be assigned separately to the Hosted Agent's identity. See the Hosted Agent identity documentation. A 403 Troubleshooting Sequence When a tool call fails, I use the following order instead of immediately adding more roles: Identify the actual principal. Is it the shared Project Agent Identity, the published Agent Application's dedicated identity, a Hosted Agent Identity, an OBO user, or the Project Managed Identity selected by the connection? Verify the grantee. Was RBAC actually assigned to the current principal? After publication, are you still looking at the old agentIdentityId? Check the permission plane. Azure Owner and Contributor provide broad Azure Resource Manager control-plane permissions, but they do not automatically include the Foundry or downstream data-plane permissions the call requires. See the Hosted Agent permissions reference. Check the scope. Does the role apply at the subscription, resource group, resource, container, or data-object level? Is it too broad or too narrow? Check the audience. Azure Storage uses a target resource identifier such as https://storage.azure.com, not the MCP server URL. Check tool support. The Foundry documentation states that only some tools currently support Agent Identity and directs developers to check each tool's documentation. The current documented AgenticIdentityToken connection configurations cover MCP and A2A. Other tools may use keys, OAuth passthrough, or a different connection type. The point of this sequence is to establish who is making the call before asking which permission is missing. Otherwise, adding another role may simply grant access to the wrong identity. Path 3: Having Permission Does Not Mean an Action Should Run Automatically Sending external email and updating a CRM system both create business impact. RBAC can establish that the agent is authorized to call an API. It cannot determine whether prompt injection contaminated the current arguments or whether a bulk update matches the user's actual intent. I separate the controls into three layers: Identity: Who is making the call? Authorization: What is the maximum it can do? Approval: Should this action run now? A Foundry MCP tool can set require_approval: "always" to require a caller to inspect the server, tool, and arguments before execution; the default is always. For example, an agent.yaml Toolbox resource can declare the policy explicitly: resources: - kind: toolbox name: meeting-prep-tools tools: - type: mcp server_label: crm server_url: https:///mcp require_approval: always project_connection_id: crm-connection This configuration only declares the approval policy. For a Toolbox, tools/list returns require_approval in _meta.tool_configuration, but the Toolbox MCP endpoint itself does not block tools/call. A Hosted Agent or custom runtime must read the policy, present the pending action, and wait for confirmation before making the call. If only high-risk operations require approval while read-only tools should remain automatic, an MCP tool can also use a per-tool value such as {"always": ["send_mail", "update_crm"]}. See the MCP tool approval flow and the Toolbox approval guidance. My working rule is simple: low-risk read and summarize operations may run automatically when permissions are narrow and arguments are validated. Sending, bulk modification, deletion, export, and permission changes should use deterministic controls outside the model. A sentence in the system prompt that says “ask the user first” is not an approval gate. Pre-Production Checklist [ ] Every production agent has a named owner, sponsor, purpose, and disable procedure. [ ] Every task path explicitly selects OBO, Agent Identity, or another identity required by the connection. [ ] Tools separate read, write, delete, export, and administrative actions and use an allowlist. [ ] RBAC is assigned to the actual principal at the narrowest scope required for the task. [ ] After publishing a Prompt Agent, every role has been reviewed against the new agentIdentityId. [ ] Hosted Agent infrastructure permissions and runtime business permissions are separated. [ ] High-risk tools use an enforceable approval gate rather than a prompt convention. [ ] Logs can correlate the caller, agent, tool, arguments, resource, approval, and result. [ ] The team has tested what happens after revoking a role, disabling an identity, or blocking a tool. [ ] Keys, connection secrets, and OAuth tokens have defined storage, rotation, and audit policies. Do Not Test Only the Happy Path The most valuable permission test is often whether the system fails when it should. At a minimum, add four negative tests: have a user without document access ask the same question; point the Storage operation at an unauthorized container; reject one outbound-email approval; and revoke the production Agent Identity's role before calling the tool again. The expected result is not merely an error. Confirm that the logs correlate the caller, Agent Identity, tool, resource, approval decision, and correlation ID. Otherwise, the system may reject the action while leaving the team unable to explain why, who was affected, or whether the agent should be disabled. Conclusion The meeting preparation agent is not one “universal identity.” It consists of three explicit execution boundaries: OBO for user data, an independent Agent Identity for background work, and an enforceable approval gate for high-impact actions. The deployment order worth preserving is: identify the caller, grant the minimum authority, then add approval and audit controls to specific high-risk actions. You can outsource your thinking, but you cannot outsource your understanding. Further Reading Agent identity concepts in Microsoft Foundry Hosted agents in Foundry Agent Service Hosted agent permissions reference Connect agents to MCP server endpoints Create and manage a toolbox in Microsoft Foundry Azure built-in roles for Storage Least privilege for AI agents

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More AI & Machine Learning News