Skip to lesson

MicrosoftMicrosoft Certified: Multi-Agent AI Solutions Expert2026-104.2 Design and implement guardrails for multi-agent solutions

Authorize tool calls before approving side effects

Completed by the knowledge check

Learning objective

Authorize tool calls by agent/user identity, permissions, and policy; require explicit approval before sensitive or irreversible side effects, even when arguments are schema-valid.

Core idea

A valid tool call is a proposal, not an authorization. Schema validation can establish that an amount is numeric and an account identifier has the required shape. It cannot establish that the acting principal may access that account, that the payment complies with business policy, or that an authorized person approved the transfer.

Keep three decisions explicit: whose authority the call carries, whether that authority and application policy permit the specific operation, and whether the operation requires human approval. Approval is an additional prerequisite for a permitted sensitive action. It does not override a missing downstream permission or an application prohibition. See 2.3.1 for typed tool contracts and 4.1.4 for token delegation.

How it works

Identify the principal at each execution edge

Foundry toolbox authentication is configured on project connections. The authentication type determines whose credentials reach the downstream service: agentic-identity uses the agent’s identity, project-managed-identity uses the project’s managed identity, oauth2 uses the user completing OAuth authorization, and user-entra-token uses the signed-in Microsoft Entra user’s audience-specific token.

Choose the type the target supports and the task requires. A shared service credential does not become per-user authority because a user started the conversation. Per-user toolbox access also needs the hosted request’s caller context: the documented integrations use FoundryToolbox in Python or AddFoundryToolboxes in .NET to forward x-agent-foundry-call-id. Do not hard-code or reuse that value across requests. Connection configuration and propagation of the request context are both necessary; the authentication setup is covered in 4.1.5.

For agentic access, Foundry obtains an audience-scoped token and the downstream resource validates it and checks permissions assigned to the agent identity. agentIdentityId is the documented identifier used for those assignments. The agent’s permission to invoke a platform does not prove it may read or mutate every resource behind that platform. Keep resource-level checks at the backend that owns the operation.

Enforce permissions and application policy

For an Entra-protected gateway, Azure API Management’s validate-azure-ad-token policy validates the presented token; see 4.1.3 for gateway configuration. Successful token validation still needs the target operation’s permission checks. A token for the correct service is not a blanket grant to every account.

The backend must also enforce business rules that the identity system does not express, such as which accounts can receive transfers or whether a case may be deleted. These are application policies, not capabilities inferred from a model prompt. Resolve the target record, principal, operation, and effective arguments in trusted code. Deny a call that violates policy even if the user would approve it.

In Agent Framework’s Python function middleware, FunctionInvocationContext exposes function, validated arguments, session, metadata, and kwargs. A FunctionMiddleware implementation can check the operation before calling call_next(), which continues the chain or executes the function. For approval-requiring functions, the framework creates the approval request before function middleware runs. Check application policy before displaying that request when you need to reject prohibited proposals without involving a reviewer, then repeat the execution checks in function middleware. Supply trusted request identity through the application’s request context; do not accept a principal identifier generated in tool arguments as proof of identity.

This function-invocation seam covers application-executed functions. It does not establish control over provider-executed hosted tools. Keep authorization in their connection and downstream service as well. The experimental Python Agent Hooks documentation explicitly says its pre_tool_call seam cannot block provider-side execution; see 4.2.4 for that scope limitation.

Require approval for the exact effect

For Python Agent Framework function tools, approval_mode="always_require" requests approval before execution; see 1.1.6 for the request/response cycle. Present the actual operation, target, and effect to an authorized reviewer rather than asking whether the agent is generally trusted. The documented examples contain fixed approval values for demonstration; a production approval surface must obtain an explicit decision rather than copy an automatic True.

For Foundry Agent Service remote MCP calls, require_approval="always" requires approval for each call. Restrict discoverable tools with allowed_tools, but remember that this is an exposure choice rather than a replacement for backend permissions. A returned mcp_approval_request identifies the proposed tool and arguments. Continue with an mcp_approval_response containing approval_request_id and approve, using previous_response_id to identify the preceding response.

Neither an approval message nor an allowlist grants downstream data permissions. These mechanisms communicate whether the caller permits execution of the proposed call. The application must verify who submitted the approval and whether that person can approve the effect. Use the exact call identifier and displayed arguments to avoid treating consent for one operation as consent for another.

Recheck the approved operation before execution

Between proposal and execution, a target can change, permissions can be revoked, or middleware can rewrite arguments. Revalidate application policy and target permissions at execution. If the effective recipient, amount, or resource differs from what was reviewed, request approval for the changed operation.

A sensitive call is therefore checked against application policy before its approval request and again in function middleware before it executes.

A sensitive call is checked before its approval request and again before it executesStarts at a schema-valid tool call. Application policy is checked first: a prohibited proposal is denied without a reviewer. A permitted sensitive action becomes an approval request to an authorized reviewer. The approved operation is rechecked in function middleware: a policy violation is denied, an operation that differs from what was reviewed loops back for a fresh approval request, and only a revalidated operation executes the function.prohibitedpermitted, sensitiveapproved operationviolates policyoperation differsrevalidatedSchema-valid toolcallApplication policyDenyApproval requestAuthorizedreviewerFunctionmiddlewarerechecksExecute thefunction

Agent Framework’s experimental Python Agent Hooks integration documents this argument-change case: for a function with approval_mode="always_require", a pre_tool_call transform that changes approval-bound arguments causes a replacement approval request. The original grant executes nothing. This behavior is specific to that integration; do not assume arbitrary application code can mutate an approved request and retain equivalent protection.

For approvals that must survive a restart, use the persisted request/resumption design in 2.4.6. This lesson’s decision is the authorization and exact side effect, not how to persist a workflow wait. Keep repeated-call handling and retry safety separate as well; see 2.3.8.

Key distinctions and trade-offs

Validation versus authorization: Validated arguments describe a structurally acceptable call. Authorization determines whether the verified principal may perform it on the resolved target.

Authorization versus approval: A permitted action can still require explicit consent. Consent cannot make an impermissible action legitimate.

Tool exposure versus enforcement: allowed_tools narrows what the model can propose through that integration. The tool backend still verifies the operation and resource.

Approval on every harmless read adds friction, while omitting it for an irreversible write creates an uncontrolled effect. Classify operations by the effect they can produce, including sensitive disclosure, rather than by whether their names sound destructive. Keep the sensitive paths gated even when a model proposes them confidently.

Architecture / decision scenario

A finance agent can read invoices and propose a payment. Invoice reads use a per-user toolbox connection so the downstream service applies the requester’s access. The payment function uses a narrowly authorized service identity and application rules limiting eligible accounts and recipients.

The model proposes a schema-valid payment. Before displaying the framework’s approval request, the application resolves the invoice and checks the verified requester, service permissions, recipient, and policy. A prohibited recipient is denied without asking a reviewer to override the rule. A permitted payment still needs the always_require approval flow, displaying the recipient, invoice, and amount. After approval, function middleware repeats the checks before call_next() executes the function.

If the approver rejects, the application resumes with a negative approval response and sends no payment. If the amount changes before execution, the application requests a fresh approval and rechecks permissions. Moving the same payment behind a Foundry MCP tool changes the approval transport to mcp_approval_request and mcp_approval_response; it does not remove backend checks or turn allowed_tools into payment authority.

Common exam traps

  • Treating a schema-valid call as authorized.
  • Treating a signed-in user as the principal when a shared connection executes the call.
  • Accepting model-generated identity fields as authenticated context.
  • Letting human approval override a backend permission denial.
  • Reusing approval after changing the effect or target.
  • Assuming client function middleware intercepts provider-hosted execution.

What to remember

Resolve the acting identity, enforce target permissions and business policy, and require approval for the exact sensitive effect. Recheck the operation at execution. Tool schemas, allowlists, and approval messages each answer a different question; none replaces the others.

Knowledge check

References