Policy-as-Code Enforcement for AI Agent Tool Calls
Securing AI agents requires enforcement rules at the tool boundary, not trust in system prompts.

AI agents now execute real actions across real systems: sending emails, querying databases, calling APIs, triggering workflows. Policy-as-code is the answer to a problem that static access controls were never built to solve: how do you govern something that decides what to do at inference time, moment by moment, instead of following a fixed script? This piece walks through how the threat actually gets in, why the usual fix (a well-worded system prompt) falls apart under pressure, and what a real enforcement layer looks like when it's built at the tool-call boundary.
Model Context Protocol, or MCP, has become the default way enterprise agents plug into everything else: file systems, databases, internal APIs, SaaS tools like a messaging platform or a CRM. That's a big shift from the old world of static APIs with fixed request shapes and predictable inputs. An agent connected through MCP makes its own call about which tool to use, when, and with what data, often chaining several tool calls together where each step depends on what the last one returned. The whole thing, agent, context, and tool, moves as one system.
A May 2026 survey out of the University of Connecticut (the LASM survey, arXiv:2604.23338) names three properties of this attack surface that simply don't exist for a stateless language model answering one prompt at a time. Harm can be emergent: no single action in the chain looks malicious, but the combination does real damage. It can be compositional: a defense sitting at one point in the stack can't catch an attack that gets routed through a different component entirely, what the researchers call a non-transferability result. And it can be temporally extended: a payload gets planted weeks before it fires, and when it finally does, there's no discrete event that looks like an attack.
The exposure is already large and growing. By early 2026, close to 7,000 internet-facing MCP servers had been cataloged, and roughly half of them ran with no authentication. A separate internet scan conducted in July 2025 turned up 1,862 publicly reachable instances answering requests from anyone, no credentials needed. And the attacks aren't hypothetical anymore. IBM's 2026 breach research found that one in four malicious breaches involved AI, a 56% jump over the year before. CrowdStrike's 2026 Global Threat Report clocked an 89% rise in attacks from AI-enabled adversaries, with average breakout time (the gap between initial compromise and lateral movement) dropping to 29 minutes.
Flexibility and risk come from the same wire: the thing that makes MCP genuinely useful, letting the model read a tool's natural-language description and decide on its own how to use it, is the exact same mechanism that makes it exploitable. Flexibility and risk come from the same wire.
How the threat reaches agents through their tools
A March 2026 guide from Aembit breaks MCP risk into five layers: transport and communication, authentication and identity, context integrity and confidentiality, authorization and privilege management, and supply chain security. Each one has already produced a real incident.
Start with supply chain, because it's structural rather than a bug in one company's code. OX Security published research (they called it the "Mother of All AI Supply Chains") showing a command execution flaw baked into Anthropic's official MCP SDKs, across Python, TypeScript, Java, and Rust. The root cause: STDIO transport hands parameters straight to the host operating system's shell without cleaning them first. CSA estimated around 200,000 vulnerable instances sitting downstream of a supply chain that's seen more than 150 million package downloads. Anthropic confirmed the behavior was intentional by design. Fixing it is now every downstream developer's job, not theirs.
Then there's tool poisoning, where the control plane itself turns into the weapon. A malicious MCP server crafts its tool responses to nudge the model toward outputs it shouldn't produce. Research from Wang and colleagues at AAAI 2026 measured a peak attack success rate of 72.8% across tested models, with a mean of 36.5%, for shifting agent behavior this way. Invariant Labs documented something worse: a single poisoned server can weaponize other, fully trusted servers sitting next to it through what's called cross-server tool shadowing. Trust one server, and the blast radius isn't limited to that one server.
Prompt injection is the category with the clearest headline incident. EchoLeak (tracked as CVE-2025-32711, CVSS score 9.3) is the first documented zero-click attack on an AI agent. An attacker planted hidden instructions inside an email. Microsoft 365 Copilot pulled that email in as context, followed the buried instructions, and exfiltrated data, all without the user clicking anything or approving anything. HackerOne's 9th Annual Hacker-Powered Security Report recorded a 540% surge in prompt-injection vulnerabilities and called it the fastest-growing threat category in AI security.
OWASP's own rankings reflect how fast this moved. In the 2026 OWASP Top 10 for LLM Applications, "Excessive Agency" jumped from sixth place to third, the single biggest move on the whole list. Prompt injection has held the top spot for multiple consecutive years. MITRE ATLAS, the industry's reference catalog of adversarial techniques, tracks prompt injection as AML.T0051 and continues to expand its coverage of agent-specific attack patterns as the threat landscape evolves.
The pace of exploitation backs all of this up. More than 30 CVEs surfaced in a single 60-day window. CVE-2026-33032, rated 9.8, is under active exploitation. A supply-chain attack silently BCC'd emails from more than 437,000 environments before it was caught.
Why system prompts cannot serve as enforcement
Most teams running agents today keep their policy in the system prompt. Plain-language instructions telling the model what it can touch, what data it can see, what steps to follow before acting.
It's an appealing setup on the surface. It reads like a policy document. It's written in a natural language, so anyone can review it. And in casual testing, the model usually does what it's told.
That's exactly the problem. A system prompt is a probabilistic instruction. The model approximates compliance every time it generates a response; it doesn't enforce anything. A cleverly worded input, a manipulated tool description, or a goal that conflicts with its instructions can produce a policy violation that looks, in the transcript, exactly like a legitimate action. EchoLeak proves the point directly: the agent carried out the attacker's instructions without any explicit user action, and the exfiltration occurred entirely through normal-looking model behavior.
There's also a mismatch in cadence. Traditional governance works fine when the unit of decision is a human signing off on a model release every six months. It falls apart when the unit of decision is an agent firing off tool calls continuously across multiple connected systems. No review board, however well-staffed, checks each of those calls before it happens.
That gap between written policy and enforced policy is measurable. The LASM survey mapped defense coverage across a grid of architectural layers and time horizons, and found seven of 28 cells with zero defense coverage at all, three of which already contain documented attacks. Policy on paper, unenforced in practice: the numbers put a shape to what was already suspected.
Which leads to the point the rest of this piece builds on. Enforcement can only be made deterministic outside the model's own reasoning, in the gap between an agent deciding to act and that action actually executing.
What policy-as-code enforcement means at the tool-call boundary
AI agent policy enforcement is the runtime process of deciding whether an agent gets to do something specific: call a tool, hit an API, read a sensitive record, kick off a workflow, based on policy and whatever context is available at that instant. Runtime is the operative word. Enforcement is a decision made at the point of action, before every single tool call. It's a decision made at the point of action, before every single tool call.
"Policy-as-code" is what turns that decision into something machines can actually apply consistently. Instead of prose, policies get written as versioned, machine-readable configuration: OPA and Rego rules, Cedar's permit and forbid statements, JSON policy documents. That format can be tested against sample scenarios, reviewed in a pull request the same way application code is, and enforced by software rather than interpreted by a person. When policies are served from a running policy engine, changes go live without needing a full deployment cycle.
The enforcement point has to sit at the tool-call layer, not inside the agent itself, because the agent shouldn't be the one deciding what it's allowed to do. That job belongs to the policy engine. Even if an attacker tricks the agent into attempting something it shouldn't, the engine sits between the attempt and the target system and blocks it before it lands.
That architecture breaks into four working pieces:
The policy definition layer holds the declarative rules: least privilege, governance requirements, whatever intent the organization wants encoded. The decision point, sometimes called the control plane, evaluates each requested action against those policies plus whatever live context is available, and returns one of four verdicts: allow, block, modify, or escalate to a human. The enforcement points, the data plane, are the inline interceptors sitting at tool calls, API gateways, identity layers, and data access paths that actually carry out that verdict. And feeding all of it, context sources, identity, workflow state, environment, and behavioral history, along with an audit and feedback store that keeps an immutable record of every decision made.
What this buys that a system prompt never could: deterministic evaluation. The same input produces the same verdict, every time, regardless of how cleverly an attacker phrased the prompt that got the agent there. An agent holding both a send_email tool and a query_database tool has no business calling drop_table, and OAuth scopes plus IAM roles only get you halfway there. Those control which services an agent can reach. Policy-as-code controls what it does once it's already connected.
The policy engines being used in practice: OPA, Cedar, and layered approaches
Open Policy Agent, or OPA, is the general-purpose baseline most teams reach for first. It's open source, a graduated CNCF project, and it enforces one consistent, context-aware policy across the whole stack rather than a patchwork of rules per system. It sits between the agent and the tool the same way described above, so the agent never gets to be the one deciding what's permitted.
In practice, teams use OPA for things like row- and column-level database security based on who or what the agent is acting on behalf of, restricting which cloud resources an agent can touch and in which regions, filtering which API endpoints are reachable, and gating CI/CD pipelines on compliance rules. Microsoft's internal microbenchmarks found policy evaluation adds sub-millisecond overhead per call for typical rule sets, small change relative to the time an LLM round trip already takes. Vercel's AI SDK ships a package, @ai-sdk/policy-opa, that moves authorization logic out of application code entirely and into standalone.rego files, testable in CI with opa test, editable without redeploying the SDK when served from a live OPA instance.
Writing Rego by hand is still a skill most teams don't have on staff, which is the gap Apple's Prose2Policy (P2P) research targets. Published in March 2026 (arXiv:2603.15799), it's an LLM-based tool that takes natural-language access control requirements and translates them into executable Rego, running the whole thing through policy detection, component extraction, schema validation, linting, and automatic test generation before anything ships. It doesn't replace Rego's deterministic guarantees; it just makes authoring accessible to people who never learned the language.
On the Cedar side, Amazon Bedrock AgentCore Policy went generally available on March 3, 2026, after being announced at AWS re:Invent. The AgentCore Gateway intercepts every request an agent makes to a tool and evaluates it against Cedar policies before the tool call actually fires, outside the agent's code and outside the model's reasoning entirely, which is what makes it immune to prompt injection as an enforcement bypass. It works through two complementary mechanisms. Cedar-based policy handles deterministic permit and forbid rules over a principal, an action, and a resource (with optional conditions attached), and every decision is logged automatically for audit. Lambda interceptors run before or after a tool call to handle dynamic validation, enrich payloads, exchange tokens, or filter responses. Teams can even write policy intent in natural language and have it auto-convert into Cedar syntax, no changes to agent code required when the policy itself changes.
A few other approaches include the following. Strata's Maverics AI Identity Gateway embeds an OPA engine directly to evaluate fine-grained policy on MCP tool calls at request time, positioning OPA as a perimeter every tool invocation has to clear before it reaches anything upstream. Microsoft's Agent Governance Toolkit takes a full-stack view, covering policy enforcement and zero-trust identity, among other areas of agentic governance, execution sandboxing, and reliability engineering together, and claims coverage against all 10 categories in the OWASP Agentic Top 10.
And for organizations running more than a handful of agents, stitching together a policy engine, a gateway, and a separate identity tool creates its own gap: a policy enforced in one layer might be invisible to the next. That's pushing some teams toward unified platforms that combine access to a large catalog of MCP servers (upward of 18,000), built-in OAuth and credential handling, SSO and standards-based provisioning, and policy enforcement down at the tool-call level, backed by tamper-proof audit logs and full distributed tracing. The idea is to make the enforcement layer and the enablement layer the same surface, so identity travels with every action instead of getting bolted on after the fact.
Authentication and identity as the foundation policy-as-code depends on
Knowing, with certainty, who or what is making the request is a precondition for any of this to work. The MCP specification requires OAuth 2.1 with PKCE for every protected HTTP-based deployment, HTTPS across all endpoints, and discoverable authorization server metadata.
Reality lags the spec by a wide margin. Research tracking MCP deployments found that only 8.5% of MCP servers actually implement OAuth, despite it being the protocol's mandatory security baseline for anything deployed remotely. That's most of the ecosystem running without the one control the spec treats as non-negotiable, far more than a rounding error. That's most of the ecosystem running without the one control the spec treats as non-negotiable.
The MCP authorization protocol itself came out of a broad industry collaboration, including Anthropic, Microsoft, and Okta/Auth0 among others, and defines OAuth-style protected resources, a way to discover authorization servers, audience binding through Resource Indicators (RFC 8707), and delegation through Token Exchange (RFC 8693). The July 2026 spec update, MCP 2026-07-28, dropped the initialize handshake and the session ID that Streamable HTTP transport relied on, moving toward a stateless core with first-class extensions and tighter authorization.
Gaps remain even after that update. The OAuth 2.1 profile still has no standardized audit trail format. SSO-integrated authentication is flagged as one of the top enterprise requests on the 2026 MCP roadmap, but it's a stated commitment, not something shipped yet. Token vaulting, just-in-time consent, user verification, role-based access control, and audit logging above the basic OAuth handshake are all left to whatever runtime layer sits on top of MCP, because the protocol itself doesn't cover them.
Auth0's "Auth for MCP" went generally available on May 6, 2026, built to close some of that distance, including client ID metadata document (CIMD) registration and related tooling aimed at making identity for MCP servers something teams can stand up without hand-rolling it themselves. That's the direction the whole ecosystem needs to keep moving. Policy-as-code can only enforce what it can identify. Get authentication and identity wrong, and every Rego rule or Cedar statement built on top of it enforces policy against a request it never should have trusted.

Sources
- Top AI Security Threats in 2026 (And How to Defend Against Them) - Practical DevSecOps
- A Systematic Survey of Security Threats and Defenses in LLM-Based AI Agents: A Layered Attack Surface Framework
- MCP Security Crisis: Systemic Design Flaws in AI Agent Infrastructure
- MCP Security Vulnerabilities: Complete Guide for 2026
- MCP Security Statistics 2026: CVEs, Vulnerabilities & Breach Data - Practical DevSecOps
- microsoft.github.io
- workos.com
- infoq.com


