cd /news/ai-agents/mcp-guardrails-with-aarm-and-microso… · home topics ai-agents article
[ARTICLE · art-57361] src=agentgateway.dev ↗ pub= topic=ai-agents verified=true sentiment=· neutral

MCP Guardrails with AARM and Microsoft Agent Governance Toolkit

Agentgateway has added support for MCP guardrails, integrating with Microsoft's Agent Governance Toolkit (AGT) based on the AARM paper to enforce policy decisions in agentic architectures. The system addresses the challenge that AI agents' emergent behavior requires context-aware policy decisions beyond traditional stateless allow/deny models, using richer context and a four-category decision vocabulary (forbidden, context-dependent deny, context-dependent allow, context-dependent defer/escalate).

read7 min views1 publishedJun 29, 2026

Agentgateway can call out to policy engines for LLM guardrail or for enterprise policy decisions. We’ve recently added support for MCP guardrails. This blog goes a layer deeper and shows where MCP guardrails would fit into an agentic architecture following the principals from the AARM paper.

TL;DR

I have put together a demo that digs into the AGT framework with agentgateway.

You can find it here: https://github.com/christian-posta/agent-governance-agw

AI agents are not like microservices. An agent’s intent is “interpreted” and explores its way to a solution for a goal. When agentgateway sits on the request path to other agents, MCP tools, or APIs as a policy enforcement point (PEP), we are one step closer to coralling this emergent behavior with policy and guardrails.

Typical policy decision systems (think things like OPA) are good at evaluating a number of signals and making policy decisions. Think “attribute based access control”. They are stateless, take some “context” to evaluate (subject, roles, the resource being accessed, the action being taken) and return a deterministic allow/deny decision.

For traditional API calls, this works brilliantly. The context is predictable and discrete: user A with role B is trying to invoke operation C on resource D. Write the Rego rule, ship the policy, done.

But AI agents break this model. The same MCP tool call can be entirely legitimate in one context and a serious security or compliance violation in another, and the difference isn’t captured in any single call’s attributes. We have to dig into the pattern of calls and the intent behind them. An agent that reads a config file, then queries a database for credentials, then calls an external HTTP endpoint hasn’t violated any individual policy rule in isolation. Each step may be fully permitted. The threat is the sequence.

This is where agent-native governance toolkits like Microsoft’s Agent Governance Toolkit (AGT) come in. AGT is based on the excellent “AARM” paper (Autonomous Action Runtime Management) from Hermano Errico.

So what is it that AARM / AGT add on top of something like OPA? Actually these systems do use OPA/cedar/whatever under the covers. So specifically from what I can see it adds is:

All of this can be fed into the stateless policy engine to get richer decisioning. I recommend reading the AARM paper for more.

Beyond richer context, AARM also introduces a richer decision vocabulary than a plain allow/deny. The paper defines four action categories that the policy engine must be able to return:

Decision Meaning
Forbidden
Hard block regardless of context. No session history needed — these are absolute organizational limits (e.g., rm -rf / , known-malicious endpoints). Static policy suffices.
Context-dependent deny
The action is policy-permitted in isolation but blocked because accumulated session context reveals inconsistency with the user’s original intent. Classic example: reading customer PII then immediately emailing an external address — neither action alone triggers a violation, but the composition does.
Context-dependent allow
Denied by default but permitted when context demonstrates clear alignment with legitimate intent. Deleting database records looks dangerous in isolation; if the session confirms the user said “clean up my test data,” blocking it is wrong. Context transforms a default-deny into an informed allow.
Context-dependent defer / escalate
Risk cannot be conclusively determined from available context. Rather than committing to an unsafe allow or deny, execution is suspended and escalated for human approval — for example, a credential rotation outside a maintenance window where the context is ambiguous.

The AGT implementation maps these to verdict decisions of allow

, deny

, warn

, escalate

, and transform

. The transform

verdict is particularly interesting: instead of rejecting a response outright, AGT can mutate it by redacting PII from a tool result before it reaches the agent’s context window, for instance.

One of the big things that stood out to me in the AARM approach is the need for a trusted component to do things like session accumulation and runtime enforcement of policy. It can be done within the agent (SDK), but that’s technically within an untrusted domain. That’s where agentgateway fits into the picture.

Microsoft’s Agent Governance Toolkit is an implementation of the AARM paper. AARM specifies two main ways to implement its ideas: SDK or proxy/gateway. AGT provides for both. We are going to look at the proxy approach.

Before looking at the configuration, it helps to understand where in the agent lifecycle AGT can intervene. The ACS (Agent Control Specification) — the policy layer inside AGT — defines eight intervention points that span the full agent loop:

Intervention point When it fires
agent_startup
Before the agent run begins — evaluate session metadata and identity
input
At request ingress, before the agent loop starts
pre_model_call
Before the LLM is called — inspect messages, context, and tool definitions
post_model_call
After the model responds, before the host acts on it
pre_tool_call
Before each tool/MCP call executes
post_tool_call
After each tool result, before it returns to the agent
output
On the assembled final response to the user
agent_shutdown
On session termination — evaluate summaries and audit metadata

This matters for the agentgateway integration because agentgateway covers several of these intervention points directly at the network layer: the mcpGuardrails

feature maps onto pre_tool_call

and post_tool_call

, while agentgateway’s existing LLM guardrails cover pre_model_call

and post_model_call

. The remaining points (startup, input, output, shutdown) can be covered by the AGT SDK inside the agent itself, giving you defense in depth across both the application layer and the network layer.

Agentgateway 1.3 recently added a new “mcpGuardrails” functionality (delivered in PR #1842) to complement its existing LLM guardrails capabilities and External Authz callouts.

The wire protocol is modeled directly on Envoy’s ext_authz

, but operates at the JSON-RPC method layer of MCP — gating and mutating individual methods like tools/call

, tools/list

, prompts/get

, and resources/read

— rather than at the raw HTTP layer. A remote gRPC policy server implements a two-method service:

service ExtMcp {
 rpc CheckRequest(McpRequest) returns (McpRequestResult);
 rpc CheckResponse(McpResponse) returns (McpResponseResult);
}

That split matters: ext_authz

only sees the inbound request, but mcpGuardrails

also gives the policy server a clean shot at the response after agentgateway has merged any fanned-out results into the client-facing view. This is what makes transform

-style verdicts (redacting PII from a tool result, for example) feasible without each policy server having to re-implement MCP framing and multiplexing.

For example, we can configure this mcpGuardrails like this:

 mcp:
 guardrails:
 processors: # ordered chain, first reject short-circuits 
 - methods: # allowlist with phase per method
 "tools/call": Full  # Request | Response | Full | Off
 "*/list": Response  # exact, `prefix/*`, `*/suffix`, or `*`
 remote:
 backendRef: # Service or Backend 
 name: my-policy-server
 failureMode: FailClosed  # or FailOpen 
 metadata: # CEL → google.protobuf.Struct
 tenant: "request.headers['x-tenant']"
 allowedRequestHeaders: [x-tenant] 
 disallowedRequestHeaders: [":authority"]

With the mcpGuardrails config we can:

tools/call

), prefix wildcards (tools/*

), suffix wildcards (*/list

), or *

for everything.Request

, Response

, Full

, or Off

. ``tools/list`

fan out to every backend. Even so, agentgateway fires CheckRequest

for the whole client call (with service_names

listing all targets) and CheckResponse

on the Mutated

request replaces the JSON-RPC params

bytes before they reach the upstream; a Mutated

response replaces the JSON-RPC result

before the client sees it. This is what enables AGT’s transform

verdict — redact a field from a tools/call

argument, drop a tool from a tools/list

result, scrub a PII column from a database query response.failureMode: FailClosed

(default) rejects the call if the policy server is unreachable or returns garbage; FailOpen

lets it through. The same setting governs gRPC errors and protocol violations (e.g. a Mutated

response that doesn’t parse back into a valid ServerResult

).processors

list is an ordered chain; the first to Reject

short-circuits, mutations from earlier processors are visible to later ones, and metadata maps merge across the chain.I have put together a demo that digs into the AGT framework with agentgateway.

You can find it here: https://github.com/christian-posta/agent-governance-agw

Ready to put MCP guardrails in front of your own agents and tools? Start with the standalone or Kubernetes quickstart, then follow the MCP guardrails docs to wire up an external policy server. Clone the AGT + agentgateway demo to walk through the full AARM flow end to end.

── more in #ai-agents 4 stories · sorted by recency
── more on @agentgateway 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/mcp-guardrails-with-…] indexed:0 read:7min 2026-06-29 ·