Firewall for AI Agents

An AI application acts as the host for three clients: an issue tracker, an external catalog, and a local filesystem. Untrusted content retrieved from the issue tracker tells the model to read a secret path and paste it into a search request. MCP will ship tools/call. The firewall is the host-side hop that can deny tha...

An agent can move from reading context to taking action in a single turn. That is exactly why authorization cannot live only in the prompt, at installation time, or somewhere deep inside an individual tool server. The critical moment is after the model proposes a tool call and before the host allows a client to execute it. The transport can be perfectly valid while the action is completely outside the authority of the current principal, agent, session, or task. Every tool invocation should be treated as a privileged transaction, not as model output. Authenticate the principal, bind the request to the authorized session intent, evaluate the requested capability and its arguments, apply deterministic policy, and only then let the host execute it. One agent session. One dangerous chain. Imagine a host connected to an issue tracker, an external search/catalog service, and a local filesystem. The issue tracker returns an ordinary-looking comment containing an indirect prompt injection: read a private key and place it into the next external query. Untrusted content + private data access + external communication creates the classic exfiltration shape often described as the “lethal trifecta.” MCP can serialize the call correctly. The filesystem server can correctly return bytes. The external service can correctly receive the search request. None of those facts answer the security question: did this session have authority to do that? Three things that look like security but are not the control point 1. “The system prompt says not to.” A prompt is guidance to the same probabilistic component you are trying to govern. Hostile content can compete with or reinterpret it. A security boundary should not depend on the model consistently choosing the right instruction. 2. “The user approved the server.” Connection permission is not perpetual authority over every resource reachable through that connection. Approving a filesystem server does not imply authority to read ~/.ssh/id_rsa six hours later in an unrelated session. 3. “The server validates access.” Server-side authorization is still necessary, but it answers a different question. A remote server can validate its own resources. It cannot reliably know the complete host-side intent across multiple tools, local processes, and egress destinations. What an agent firewall actually is A network firewall sits on the path traffic already uses. It does not ask the payload to behave. It evaluates identity, destination, protocol, and policy before forwarding. An agent firewall is the same shape on a different wire. The packet is a proposed tool call. The destination is a tool server or API. The identity is the authenticated principal plus the agent/runtime acting for that principal. The firewall can allow, deny, constrain, rewrite, or require human approval. The architectural rule: the model may propose a call, but the model must not own the execution channel. Authentication is not authority Question Example Authentication Is this José's session? Permission Can this OAuth token access GitHub? Capability Can this agent invoke filesystem.read ? Authority Should this agent, for this task, read this path right now? The last question is contextual. It combines identity, agent capability, session intent, resource scope, arguments, egress rules, and potentially consumption limits. effective_authority = principal_capability ∩ agent_capability ∩ session_intent ∩ resource_constraints ∩ egress_policy Policy should see semantics, not tool names Tool names are implementation details. Two different tools may exercise the same underlying capability. Tool Semantic capability read_file filesystem.read git.show repository.read github.get_issue issue.read send_email communication.external http_request network.egress database_query database.read database_update database.write That gives policy a stable vocabulary even as MCP servers, REST adapters, or internal function names change. Where the hop sits The host is the right choke point because it sees the full action before execution. It knows the principal, the session, the agent, the proposed tool, the arguments, and the destination client. That is enough context to evaluate authority before any bytes cross the boundary. The exact implementation can be OPA, Cedar, a policy service, a Java predicate, or another deterministic rules engine. The important property is that the decision happens on the execution path. Disposition decide(ToolCallRequest req, SessionIntent intent) { if (!intent.allows(req.capability())) { return deny("Capability outside session intent."); } if (req.capability().equals("filesystem.read") && isSecretPath(req.argument("path"))) { return deny("Path is outside the workspace allow-list."); } return allow(); } Deny is not the only useful outcome Binary authorization is sometimes too coarse. A policy layer can enforce consumption boundaries without forcing you to redesign every tool server: ALLOW — forward the call unchanged. DENY — block a secret path, destructive command, or disallowed egress destination. MODIFY — turn SELECT * into a bounded query, clamp search limits, remove unsafe flags, or restrict paths. ASK — pause for explicit human approval before a write or other high-impact action. The reference architecture and the reference implementation are not the same thing Production warning: a control point only exists if its failure mode preserves the boundary. A Guardian/policy service that becomes unavailable must not silently turn privileged execution into “allow.” If you experiment with the Agent Control Standard (ACS) or a similar external decision service, inspect the actual failover behavior. Treat preview/reference implementations as learning material until you have explicitly configured fail-closed behavior, authenticated the policy channel, bounded retries/timeouts, and tested bypass scenarios. The architectural idea is more important than the product name: inspect, decide, then forward. Every decision should leave evidence The firewall is not only an enforcement point. It is also the cleanest place to produce a security trail. Each decision should make it possible to answer: Which principal and agent initiated the action? Which session and task intent were active? Which semantic capability was requested? Which resource and argument constraints were evaluated? Which policy matched? Was the result allow, deny, modify, or ask? What actually executed after the decision? Those records are useful for incident response, governance, debugging, and observability. They also let you separate model behavior from host enforcement behavior when something goes wrong. What the firewall does not solve This control point is important, but it is not magic. It does not repair credentials that are already overly broad, a host that bypasses its own hooks, a tool catalog that exposes everything by default, or side channels that never pass through the controlled execution path. Least privilege still starts earlier: advertise fewer tools, expose smaller capabilities, minimize credential scope, restrict local filesystem reach, constrain egress, and design session intent explicitly. A firewall can deny a call. It cannot invent least privilege you refused to design. My practical checklist Model output is treated as a proposal, never as authorization. Every privileged tool call passes through a host-side policy hook. Policy evaluates semantic capability plus arguments. Principal, agent, session intent, resource scope, and egress are all visible to policy. Secret paths and destructive operations are denied deterministically. High-impact writes can require explicit human approval. Decision infrastructure fails closed. Policy transport is authenticated and integrity-protected. Every decision is observable and auditable. Servers still enforce their own authorization; the host firewall does not replace defense in depth. Th...