Tool Mandates: Zero-Trust Approvals on the MCP Server
Cross-organization tool integrations break any safety pattern that delegates approval enforcement to the caller. When the MCP Server and MCP Client belong to separate teams or companies, the MCP Server owner must control which tools require sign-off and verify human consent on the server side.
Why Client-Enforced Elicitation Fails Zero Trust
Per the Model Context Protocol specification, an MCP Server can redeploy and serve an altered list of tools at any time without alerting client-side engineers. Hardcoding risk rules inside the MCP Client drifts on the very first server deployment.
Form Mode vs. URL Mode Elicitation
MCP Elicitation defines two distinct modes with very different trust boundaries:
- Form Mode (Non-Auth Data Only): Form Mode delegates UI prompts to the client and returns
{ action: "accept" }payloads, so reserve it strictly for non-auth, non-approval input collection. Because the MCP Server accepts that JSON reply without cryptographic proof, a buggy, prompt-injected, or malicious MCP Client can skip the modal and forge"accept"onissue_refundordelete_records. - URL Mode (Out-of-Band Browser Redirects): URL Mode pauses execution and hands the client an external link to a server-controlled page (such as an OAuth Server), preventing the client from forging completion state on the backend. When a human sits at an interactive browser, URL Mode handles login and OAuth consent safely, yet it still leaves gaps as a universal tool-approval mechanism:
| Limitation | Why URL Mode Falls Short |
|---|---|
| Client-Mediated Links | The client still displays the URL - a compromised client can swap the destination for a phishing page, and habitual mid-chat prompts raise "assistant phishing" risk. |
| Browser Requirement | URL Mode requires a human sitting at an interactive browser session, leaving headless, API, and background agents blocked. |
| No Reusable Scope Bounds | Redirecting per call lacks standardized, parameter-bound authorization envelopes (e.g., pre-authorizing refunds up to $50 within one session). |
Theoretical Blueprint: AP2 Signed Mandates & OAuth Servers
We do not have an industry solution for general tool approvals at this time. Today, Google's Agent Payments Protocol (AP2) (governed under the FIDO Alliance) solves cross-party proof of authorization specifically for credit card purchases using Signed Mandates - tamper-evident credentials signed outside both the LLM and caller.
Pairing AP2's Signed Mandate pattern with two existing OAuth standards outlines a theoretical blueprint for securing every sensitive MCP tool across organizational boundaries:
- OAuth 2.0 Rich Authorization Requests (RAR - RFC 9396): Replaces broad scopes such as
billing:writewith structuredauthorization_detailsJSON inside the access token, pinning permission to one specific tool name, record ID, and numeric limit. - OpenID Connect Client-Initiated Backchannel Authentication (CIBA): Decouples where the agent runs from where the human approves, letting an OAuth Server push a typed confirmation prompt to the user's phone or hardware key so an untrusted MCP Client never touches or forges the signature.
Theoretical Zero-Trust Approval Flow
In this cross-company Finance MCP flow, the Finance MCP Server registers pending parameters directly with an OAuth Server (oauth.acme.example) and executes only after verifying the resulting human signature:
Server Risk Manifest & Signed Mandate Pair
To keep policy authoritative across independent deployments, the MCP Server publishes a server-signed Tool Risk Manifest pointing protected tools at its OAuth Server and requires a human-signed Execution Mandate before execution:
{
"server_id": "finance-mcp.acme.example",
"policy_version": "2026-11-14",
"tools": {
"search_invoices": { "gate": "auto" },
"issue_refund": {
"gate": "midstream_mandate",
"oauth_server": "https://oauth.acme.example/approve"
},
"delete_records": {
"gate": "midstream_mandate",
"oauth_server": "https://oauth.acme.example/approve"
}
},
"manifest_sig": "ed25519_server_sig_..."
}When the human approves issue_refund via https://oauth.acme.example/approve, the OAuth Server binds the exact fields into a short-lived Signed Execution Mandate:
{
"mandate_id": "mnd_98f21a",
"tool": "issue_refund",
"constraints": {
"invoice_id": "INV-4092",
"max_amount_usd": 450
},
"expires_at": "2026-11-14T16:15:00Z",
"signer_proof": "fido2_webauthn_sig_..."
}If an external MCP Client or prompt-injected payload changes max_amount_usd to 4500 or substitutes delete_records, the server's signer_proof check fails before any mutation runs. While this combined manifest-and-mandate pattern remains theoretical outside payments today, binding human signatures directly to server-verified parameters gives tool providers a concrete zero-trust target.
Review Human Gates, read Consistent Contracts over Broad Bash, or return to the AX Engineering Series Hub.