Skip to content
Rutger Hemrika
Menu
← Blog

Agent platform field notes · 4/8

When every tool is a server: where MCP gateways really enforce policy

Rutger Hemrika6 min read

Agent platform field notes, four of eight. Note three ended on tool mediation as one of the five decisions frameworks leave to you. This note is about the component most teams reach for to fill that gap.

The question

The Model Context Protocol did something useful and something dangerous at the same time. Useful: every tool an agent can use now speaks one protocol, so you can put one thing in front of all of them. Dangerous: every tool is now a server, reachable over a network, often hosted by someone else, and the model gets to discover and call it.

So the question for a governed platform is: if we put a gateway between the agent and every tool, which of the five governance decisions does that gateway actually take? Identity and delegation, policy enforcement, approval binding, tool mediation, evidence. The honest answer is one and a half.

What I read

For the platform, I evaluated eight MCP gateways and tool-routers, from a cloud vendor’s Kubernetes-native reference gateway, to an Envoy-based control plane that is now a foundation project, to hosted integration platforms that front thousands of SaaS actions, to small open-source routers. For the open-source ones I read the code statically, because the documentation and the implementation disagreed more often than I expected. Nothing here was built or run; the findings are from reading.

Four ideas survived the reading and went into my own design.

Four ideas worth taking

Tool-level authorisation as declarative policy. The Envoy-based gateway evaluates an expression over the caller’s token claims, the request headers, the backend, the tool name and the tool arguments, at the gateway, before the call reaches any server. That moves “may this principal call this tool with these arguments” out of each server and into one policy file you can review. It is the single most important pattern in the set, because it is the only place in the chain where the decision is made by something that is neither the model nor the tool.

Forward only what each backend declares. The same project builds a fresh upstream request per backend and forwards only the headers that backend explicitly lists. The user’s identity fans out only to servers inside the trust boundary. Most gateways do the opposite by default: they pass the inbound token on, so every tool server becomes a place your credentials can leak.

Progressive discovery instead of a flat tool list. Two of the hosted platforms expose a handful of meta-tools: discover, describe, execute. The model loads only the schemas it needs. This is as much a governance pattern as a context-window trick: a model that cannot see a tool cannot be prompted into calling it.

Per-end-user instances with delegated rights. The better integration platforms model each end user as a principal with their own stored grants, so one deployment acts with each person’s own rights rather than one shared service account. For a municipality this is not optional. An agent working a citizen’s case must act as the caseworker, not as “the platform”.

What a gateway cannot do

agentMCP gatewayper-tool authzheader forwardingegress allow-listcall logtool server 1tool server 2tool server 3governs: tool mediation, some identitycannot: bind approvals, see the run, make the server safe
A gateway mediates tool calls and forwards identity. It never sees the plan, so it cannot bind an approval, and it cannot make the tool server behind it safe.

Here is the half. A gateway sits on the path of a tool call. It can authorise the call, filter the tool list, strip and inject credentials, log the exchange, and enforce an egress allow-list on where the tool is allowed to reach. That is tool mediation, done properly, and a slice of identity.

It cannot bind an approval to a plan revision, because it never sees the plan. It cannot enforce policy on model calls, unless it also fronts the model, which one of the eight does and the rest do not. It does not know what a run is, so its log is a list of calls, not evidence of a decision. And it cannot make the tool server itself trustworthy: a gateway in front of a server that runs shell commands in its own process has governed the door and left the room open.

Which brings me to what I found when I read the code.

A gateway in front of an insecure tool server is a very good lock on a door in a wall that is not there.

What the code said

I will not name the projects for this part, because some of the issues were unfixed when I read them and that is a matter for their maintainers, not for a blog.

In two of the open-source gateways, the built-in authentication issued valid tokens to anyone who asked. In one, the configuration reload endpoint accepted unauthenticated requests. In another, templates used to shape requests could read the gateway’s environment, where the secrets live. In one, the helper that handled an authentication failure accepted credentials as an argument supplied by the model. In one, authorisation errors failed open: if the policy could not be evaluated, the call went through. Several of these were fixed on the main branch and not in any release, so a team installing the latest tag would ship the flaw.

None of these were exotic. They were the classic mistakes of fast infrastructure code, in components whose entire purpose is to be the control point. The lesson is not “open source is unsafe”. It is that a gateway is a security component and must be evaluated as one, with the same rigour as a reverse proxy or an identity provider, not adopted because it has the right protocol in the name and a healthy star count.

The decision I made

The gateway is a sourced component, not part of the spine. It implements tool mediation under contracts the spine owns: the allow-list per use case, the egress policy, the identity it is allowed to forward, and the evidence it must emit. If the gateway fails, the run fails closed. If the gateway is replaced, nothing in the policy or evidence model changes.

I also decided that the model gateway and the tool gateway are different problems with different failure modes, and resisted the appeal of one box for both. The model route is a qualified, pinned contract with legal and transfer decisions attached, as note two described. A tool route is an authorisation decision on a request. They share telemetry. They do not share a policy engine.

What I cannot prove yet

Same grade: prototype, and in this case thinner. My reading was static. I did not run the eight gateways under load, did not fuzz them, and did not re-read them after their next releases. Some of the flaws above are probably fixed by the time you read this; new ones have probably appeared. The patterns are durable, the specifics are not.

What to do with this

If an MCP gateway is on your diagram, ask for three things before it goes near a case file. The policy file where per-tool authorisation lives, and who reviews changes to it. The list of headers each backend receives, and why. And the date of the last security review of the gateway itself, as opposed to the tools behind it. If the answer to the third is “it’s open source, lots of people look at it”, you have your answer.

Next note: durable execution. Why “a run” has to be the unit of governance, and what Temporal, DBOS and Restate have to do with municipalities.

Moss once handed Jen the Internet in a small black box with a light on top. Some of the gateways I read ship the same way: the box is real, the light is on, and the label is the only secure part.

References

The allusions and quotations in this piece, with their origin:

  • The IT Crowd, “The Speech” (2008): Moss and Roy hand Jen “the Internet”, a small black box with a blinking light.

Rutger Hemrika

AI strategy and governance for vertical-market software. Writes from building, not from slides; every claim carries an evidence grade.

Full experience · About

The case behind this seriesA governed AI-agent platform for Dutch local governmentDesigned and built from the ground up on the premise that agents are only governable if every boundary crossing is governed.