Network Egress Controls in AI Agent Sandboxes
Blocking outbound connections is the only layer that reliably stops compromised agents.

Network egress controls decide whether an AI agent sandbox actually contains anything or just looks like it does. The premise underneath the sandbox model is simple: assume the interior is compromised, and build the boundary so that assumption stops mattering. Most of the attention in agent security still goes to isolation technology and ingress filtering, which undersells where the real exposure sits. Data exfiltration, credential theft, command-and-control callbacks: none of that happens on the way in. Every one of those happens on the way out, which makes the outbound path the actual security perimeter rather than a secondary concern bolted onto it.
Traditional application security had it easier. A developer writes code, and every outbound call the application will ever make is knowable at build time; enumerate them, allowlist them, move on. Agent workflows break that model entirely, because the agent decides what to call at runtime, based on a model's output, and a static allowlist built during design review tells you almost nothing about what the agent will actually try to reach once it's live. That gap between what got planned for and what the agent decides to do is where a runtime enforcement layer has to sit, and it's the gap most teams underbuild for, usually because they built their threat model for software that doesn't improvise.
Take the cloud metadata endpoint at 169.254.169.254, the address cloud providers use to hand instance credentials to anything running on the host. An agent that can reach it doesn't need a sophisticated exploit; it just needs an open route. One unblocked path to that address turns a contained sandbox into a fully compromised cloud account, credentials and all. Isolation and safety get treated as synonyms constantly, and that's probably the single most common mistake in how teams reason about sandbox security. They are separate claims with separate failure modes, and conflating them is how a demo that looks secure ships as a system that isn't.
That conflation is exactly why, once agent infrastructure reaches enterprise security review, the first question asked is rarely about the model or the prompt. Security teams ask what outbound connections the sandbox can make, and an undefined egress posture doesn't get a follow-up ticket; it blocks the deployment outright. Egress controls function as the primary runtime enforcement layer everything else in the security model leans on, which is exactly why they belong in the architecture from day one rather than bolted on after a pen test flags them.
How indirect prompt injection turns the agent itself into the egress threat
Indirect prompt injection is the mechanism that makes egress the load-bearing control, and it's worth being precise about why. The payload doesn't come from the user's message. Instead it sits inside content the agent retrieves on its own, a webpage, a PDF, a tool response, and the agent has no reliable way to tell an instruction apart from a description of one. The attack chain runs in four steps: the agent fetches content, reads an embedded instruction buried inside it, takes the action the attacker specified, and that action is, more often than not, an outbound network call.
The clearest documented case is the "ZombAIs" demonstration, where a hidden prompt injection payload embedded in a webpage caused an agent to download a binary, mark it executable, run it, and connect out to a command-and-control server. The full chain completed on the first attempt, with no iteration needed and no human being socially engineered anywhere in the loop; the agent did the social engineering to itself.
Later incidents follow the same shape with different plumbing underneath. Other documented incidents have combined indirect prompt injection with weak command validation to let attacker-controlled instructions reach stored credentials without triggering human-in-the-loop review. Other incidents have shown prompt injection steering agents into writing or modifying configuration files in ways that then enabled further compromise. Exploit chains against MCP server implementations have achieved remote code execution through prompt injection alone, with no second vulnerability class needed to close the loop.
MCP itself has become a wider attack surface as adoption spreads. As MCP adoption has spread, the threat model has moved past proof-of-concept demos and into an actual ecosystem, with real actors targeting real packages and real deployments.
OWASP has flagged indirect prompt injection as an architectural risk sitting above the level of prompt engineering, and the guidance is blunt: isolate untrusted inputs, enforce deterministic egress blocks, and stop treating prompt-level filtering as sufficient on its own. Sit with that distinction for a second: the agent's reasoning process is the attack surface, and reasoning is exactly the thing that can't be fully constrained through instructions alone. Egress enforcement is what stops the action even after the reasoning has already failed, which is the only place left to stop it.
What a well-structured egress policy actually covers
Default-deny is the baseline, and it means precisely what it sounds like: every reachable destination exists because someone made an explicit decision to allow it, not because nobody got around to blocking it. Decision versus omission. That's the whole difference between a policy and an accident waiting to be discovered during an incident review.
A workable policy separates traffic into categories, each with its own owner and its own review cadence. Model API access, the calls to the LLM provider itself, tends to be narrow and stable, so it's rarely where problems start. Package registries like PyPI or npm are a different animal, and they're a common source of scope creep: someone opens registry access to install a dependency during setup, and that access never gets narrowed back down once the install finishes. Approved external APIs, weather services, search, internal business data sources, form a third category. Internal services, databases, vector stores, and internal tooling form a fourth. General browsing is the highest-risk category by a wide margin, and it should require someone to justify turning it on, not default to open.
A handful of failure patterns show up often enough to name directly. A network gets opened for package installs during initial configuration and never gets narrowed back, while a bash tool ends up reaching domains the browser tool is explicitly supposed to block, because two different people configured the two tools at two different times without comparing notes. An allowlist covers hostnames but skips the business reason behind each one, so six months out nobody can tell whether an entry is load-bearing or just forgotten. The subtlest failure of all: a prompt injection drives the agent to exfiltrate data through an endpoint that's legitimately sitting on the allowlist, because an endpoint being approved says nothing about what data flows through it or why it was approved in the first place.
The metadata endpoint deserves its own line item, separate from the general allowlist conversation. It needs to be explicitly denied at the network layer, iptables or the equivalent, rather than simply left off an allowlist that someone could theoretically edit later. An absence and an active block are different security postures: one relies on nobody making a mistake, while the other stops the connection no matter how it got attempted.
Application-level limits don't hold up on their own either, because agent-generated code can route straight around them. If the constraint lives only in application logic, an agent generating its own code path can generate its way past that constraint without much effort. The limit has to also live at the infrastructure layer, cgroup-level or equivalent, somewhere the agent's own code has no ability to reach around.
Domain policy works best as organization-level configuration, not a per-session preference, and it needs a managed delivery channel: MDM, Group Policy, an admin console, a CI runner's environment. No individual agent session should be able to quietly override what the organization already decided.
The three implementation layers and how they stack
Layer one is default-deny at the network boundary. Cloud sandboxes should run with network access off until the environment configuration explicitly turns specific access on, so that every domain the sandbox can reach traces back to a deliberate decision baked into that configuration rather than an oversight. Purpose-built agent sandbox platforms are a useful reference here: Daytona, a cloud infrastructure for running untrusted AI-generated code, is one example. The strongest implementations block ingress by default and explicitly deny egress to private LAN ranges, internal cluster DNS, and the cloud metadata server before any further configuration.
Layer two is a layered allow/deny system with clear precedence rules. Some platforms default to blocking everything when both lists sit empty; others run allow-first configurations under organizational control. What matters more than which default a platform picks is what happens when the two lists collide: denials need to win over allowlist wildcards, full stop. An attacker who manages to influence what gets added to an allowlist should never be able to override an explicit deny sitting underneath it. Evolving MCP specification work has brought this same logic to the tool-calling layer, pushing toward minimal-scope access per operation rather than blanket grants handed out upfront. Deployments that haven't adopted these updates stay exposed to the fuller original attack surface.
Layer three is proxy-mediated outbound traffic, with secrets injected at the proxy instead of stored inside the sandbox. Domain filtering at a proxy layer catches traffic that manages to slip past host-level rules, which happens more often than teams expect it to. Secrets injection means plaintext credentials never actually enter the agent's environment. The agent calls an approved endpoint, the proxy attaches the credential on the way out, and nothing sits in the sandbox for a prompt injection to steal even if it makes it that far. A dedicated egress gateway also gives a fleet of sandboxes one place where all outbound traffic gets logged, instead of scattered per-sandbox logs nobody actually reviews.
The logic behind stacking three layers instead of leaning on one is straightforward, if a little uncomfortable to admit: each layer assumes the layer above it will eventually fail. The IMDS block at the iptables level exists precisely because the allowlist will, at some point, have a gap in it. That's just how layered defense is supposed to work, and pretending otherwise is how single points of failure get built in without anyone noticing.
Allowlist bypass regressions are worth keeping as a concrete data point rather than an abstract warning, because they prove even carefully designed matchers misfire. Teams running agent sandboxes should pin to patched runtimes and build in the operating assumption that the matcher will fail at least once somewhere over the life of a deployment. That assumption is exactly what makes the layers underneath it matter.
How sandbox isolation technology shapes what egress controls can enforce
Here's a question worth sitting with: what good is a network policy if the thing enforcing it shares a kernel with the thing it's supposed to constrain? Standard containers share the host kernel, and a kernel exploit inside that shared kernel can bypass application-level controls and, depending on the exploit, some network-level controls too. An egress policy is only as strong as the boundary it is applied against, and careful allowlist design cannot fix a boundary that was never really a boundary.
microVM technologies, Firecracker and Kata Containers among them, give each sandbox its own dedicated kernel, its own filesystem, and its own network stack. Egress rules enforced inside that VM can't be circumvented from the host, and rules enforced at the host level can't be circumvented from inside the VM, because there's no shared kernel connecting the two attack surfaces to begin with. Kata Containers applies this isolation model while maintaining compatibility with standard container workflows, which keeps operational overhead closer to what teams already run instead of demanding a wholly separate toolchain.
Here's the part worth stating plainly: the identical default-deny policy is a meaningfully weaker control applied to a shared-kernel container than applied to a microVM or a gVisor sandbox. Same rules, same words in the config file, yet a different amount of security actually delivered, because the isolation boundary determines how many escape routes sit underneath the policy in the first place. Choosing container isolation for an agent that executes untrusted, model-generated code and treating that choice as equivalent to a microVM is the mistake most worth correcting before it ships.
Cold start latency used to be the standard argument against stronger isolation, and it carries much less weight today. The startup overhead of stronger isolation technologies has become more competitive, which quietly removes the last easy justification for choosing weaker isolation on speed grounds alone.
Orchestration-layer work is beginning to formalize the pairing of isolation and egress policy under one umbrella. That matters because it means teams stop hand-wiring isolation and network policy together themselves, and the orchestration layer treats the two as one concern rather than two separate ones that drift out of sync.
Egress control in stateful and long-running agent sessions
Ephemeral sandboxes make this whole problem simpler than it would otherwise be: the session ends, the network context gets destroyed along with it, and there's nothing left to keep consistent. Stateful sessions don't get that luxury; policy has to persist and stay consistent across restarts, resumptions, and whatever else happens to a sandbox over its lifetime.
Snapshot and checkpoint mechanics open up policy surface area that's easy to overlook entirely. A snapshot captures filesystem and memory state at a point in time, but the question that actually matters is this: does a restored snapshot inherit the egress policy of the environment it was originally captured from, or the policy of whatever environment restores it? If the policy lives inside the snapshot itself rather than being enforced externally, a stale or misconfigured snapshot can restore carrying incorrect egress rules right along with it. The workable model enforces policy at the infrastructure layer, entirely outside the snapshot, so restoring a snapshot has no ability to override what the infrastructure has already decided. Embedding policy in the snapshot is the more common design and the wrong one; it optimizes for portability at the exact point where it should be optimizing for control.
Forking adds its own layer of lineage trouble. When a sandbox forks to run parallel agent workflows, each fork becomes fully independent of the others, and each one needs its own egress policy applied directly, not inherited from the parent sandbox in a way that skips whatever review process new sandboxes are otherwise supposed to go through.
Standby periods are not a policy-free zone either, even though it's tempting to treat them that way. A sandbox sitting in standby that still retains network stack state can potentially receive inbound connections, or resume carrying a stale allowlist that no longer reflects current policy. Enforcement needs to happen at resume time, not just at the moment the sandbox was originally created.
Orchestration frameworks that treat sandbox sessions as Activities, Temporal or similar tools, should validate egress policy at the start of each Activity rather than assuming policy carried over correctly from the previous invocation. Underneath all of this sits the broader requirement: egress policy belongs in version control alongside the agent workflow definition itself, rather than configured once in a console and assumed to hold steady indefinitely.
What to look for in a sandbox platform's egress implementation
The right question for a vendor isn't whether egress controls exist. Nearly every platform will say yes to that one without blinking. The question that actually tells you something is which layer enforces them, and what could bypass that layer if it wanted to badly enough.
A handful of criteria separate a real implementation from a marketing slide. Is the default posture network-off until explicitly enabled, or network-on until someone eventually gets around to restricting it? Is the metadata endpoint blocked at the network layer explicitly, or merely absent from an allowlist that could theoretically be edited to include it later? Is policy delivered through a managed, org-controlled channel, or can an individual session quietly override it? Does egress enforcement sit on top of a microVM or gVisor isolation boundary, or on a shared-kernel container where a single kernel exploit nullifies whatever network rules got written down?
Secrets handling matters just as much. Does the platform support proxy-mediated secrets injection, so credentials never actually enter the sandbox where a prompt injection could reach them? Snapshot policy inheritance is worth asking about directly too: is policy enforced externally at the infrastructure layer, or embedded inside the snapshot where it can quietly go stale without anyone noticing? And audit surface: one egress gateway logging all outbound traffic across the fleet, or logging scattered per-sandbox and easy to miss when something actually goes wrong?
One more question that's easy to skip past: does the platform publish CVEs and patch notes when egress-related regressions surface, the way a publicly disclosed allowlist bypass regression would, or does it treat its egress implementation as something nobody outside the vendor gets to inspect? The strongest purpose-built sandbox platforms enforce their secure-by-default network posture, with private LAN ranges and IMDS blocked by default, at the platform level, which means teams aren't relying on every individual engineer to configure it correctly by hand each time. That's a meaningfully different guarantee than a platform where the default depends on someone remembering to set it right.
Open-source or otherwise auditable implementations matter here in a way they might not for other parts of the stack, because egress policy is a security control in the strictest sense of the term, and a black-box implementation can't be pen-tested, audited, or trusted the way regulated environments require. Enterprise security reviews turn this into a concrete checklist rather than an abstract preference: security teams ask for evidence that outbound data flows are controlled, logged, and reviewed on some fixed cadence. A platform that can't produce that evidence hands the compliance burden straight back to whichever team deployed it.
Operationalizing egress policy as the agent fleet grows
Egress policies drift in one direction, and it's never the direction anyone actually wants. Domains get added for legitimate, in-the-moment reasons, an install here, an API integration there, and they almost never get removed once the immediate need has passed. Left alone, an allowlist only grows; it doesn't self-correct.
Fighting that drift takes a few concrete habits, not a policy document nobody reads. Every allowlist entry should carry a business justification, a named owner, and a review date, not just a bare hostname sitting in a config file with zero context about why it's there. Domain policy changes should go through the same process as code changes: a pull request, a review, a merge, rather than a console edit made by whoever happened to be blocked at the moment and had admin access handy. Periodic allowlist audits should actively remove entries whose original business reason no longer applies, and package registry access opened for a one-time install is the single most common candidate for that kind of cleanup.
Alerting needs to cover two different things, not just the obvious one. Alert on egress attempts to destinations that aren't on the allowlist at all, and also alert on unusual volume to destinations that are approved, because an endpoint sitting on the allowlist says nothing about whether current traffic to it is normal. A sophisticated prompt injection doesn't need an unapproved destination if it can quietly move data through one that's already trusted.
Incident response needs a specific capability built in ahead of time, not improvised during the incident itself: when a prompt injection is suspected, the first move should be isolating the sandbox's network access. That only works if egress can be revoked at runtime, mid-session, rather than just configured once when the sandbox was originally created. A control that only applies at creation time does nothing for a session already running when something goes wrong.
Watching the disclosure stream matters more than it might seem worth the effort, too. Documented allowlist bypass regressions have demonstrated, concretely, that allowlist matchers fail even when carefully built. Teams running agent sandboxes should subscribe to security advisories for every egress enforcement component in their stack and treat a patched runtime as a deployment-blocking update with the same urgency as any other critical security patch.


