Securing AI agents in MCP: mandates instead of API keys

The Model Context Protocol makes it easy to connect AI agents to tools. It only becomes secure once every call with consequences is checked against clear limits and recorded as evidence.

Key points

  • MCP governs how an agent calls a tool, not whether it may do so in a given case.
  • OAuth protects access but not the limit of the individual action.
  • A gateway with a decision before execution checks every call with consequences against the mandate.
  • Signed decisions and receipts provide evidence that holds up even after an incident.

Why MCP is a security question

The Model Context Protocol connects AI applications with tools and data: calendars, ticketing systems, databases, ordering and payment functions. An agent that can call a tool such as “place order” through MCP thereby acts on behalf of its principal.

The more tools an agent reaches, the larger the attack surface. The question is no longer only whether an agent can technically call a tool, but whether it may do so at this moment, for this purpose and to this extent.

The typical risks

  • Overly broad access: a server token or API key allows everything the account allows, without reference to the task.
  • Injected instructions: content from tools, websites or documents makes the model issue unwanted calls (prompt injection).
  • Manipulated tool descriptions: a third-party server describes its tools so the model uses them wrongly.
  • Confused deputy: a server acts with its own rights for a user who lacks those rights.
  • Missing evidence: after an incident, it cannot be shown which call was allowed.

What the specification covers

For access to protected servers, the MCP specification provides authorization based on OAuth. This makes it possible to define which client may access which server and with which permissions. That is an important building block.

OAuth, however, answers the question of access, not that of the individual action. A token with the right “write orders” does not distinguish between an order of CHF 50 and one of CHF 50,000. That distinction must be made by an additional layer.

The pattern: a decision before execution

A gateway between agent and tool has proven effective. Before a call with consequences is executed, a decision service outside the model checks the call against the mandate: is the action type allowed, is the amount within limits, is the counterparty permitted, is the mandate still valid?

  1. The agent calls the tool through the gateway.
  2. The decision service checks the call against the mandate and signs a decision: allow, deny or escalate to a person.
  3. Only on “allow” does the gateway execute the call.
  4. The result is appended to a receipt chain as an execution receipt.

Such a gateway is offered, for example, by the reference implementation Mandact (from the operator of KYA).

Least privilege per tool

The second building block is least privilege. Instead of releasing all tools of a server to an agent, it receives exactly the tools and limits each task requires. Reading tools need different rules than writing ones, and tools with payment consequences need stricter rules than those without.

A simple classification helps: tools without consequences run freely, tools with limited consequences run with a decision, and tools with major consequences also require a person's approval. The agent stays useful without every instruction in its context taking immediate effect.

Evidence that holds up later

After an incident, what counts is what is proven. A gateway that signs decisions and receipts provides exactly the evidence that audits, customers or courts ask for: which mandate applied, how it was decided, what was executed, and when.

KYA verifies this evidence independently, locally in the browser or as a package in one's own pipeline. The certificate shows step by step what is proven and what is not. Go to the developer section.

An example from purchasing

A purchasing assistant may place orders with three suppliers through an MCP server, each up to CHF 2,000. A supplier website contains a hidden instruction to also order from an unknown vendor. The model proposes the call; the gateway checks it against the mandate, finds that the vendor is not permitted and denies it. The denied decision is recorded and stands out in monitoring.

Frequently asked questions

Is OAuth enough to secure MCP?

OAuth governs a client's access to a server. Whether an individual call is allowed at its specific scope needs an additional check, for example against a mandate with limits.

Where should the decision service run?

Outside the model and independently of the agent, for example in a gateway in front of the tools. An agent that decides on its own authority offers no protection against mistakes or manipulation.

Does every tool call have to be checked?

Not every one. Reading calls without consequences can run freely. Calls with consequences, such as orders, payments or changes to data, should be decided before execution.

How do I verify the evidence of an MCP gateway?

With KYA, in the browser or through the engine in your own pipeline. It checks mandate, decision and receipt by the same ten steps.

What is the confused deputy problem in MCP?

A server acts with its own broad rights for a user who lacks those rights. A mandate per user and task prevents the server from doing more than the user may.

Do I need a separate mandate for every tool?

Not necessarily. A mandate can cover several tools but should be tailored to one task and include limits for tools with consequences.

Are there ready-made gateways for MCP?

There are various offerings, including the reference implementation by the operator of KYA. What matters is that decisions are signed and receipts are verifiable.

Sources

  1. Model Context Protocol: Spezifikation: https://modelcontextprotocol.io/specification
  2. OWASP Top 10 für LLM-Anwendungen: https://genai.owasp.org/llmrisk/llm01-prompt-injection/
  3. NIST: Least Privilege: https://csrc.nist.gov/glossary/term/least_privilege