Sandboxing AI Agents That Execute Code Locally
Containers alone can't protect against AI-generated code escaping to your host.

Containers share the host kernel. That fact alone should end most debates about whether they're sufficient for running AI-generated code, and yet teams keep treating them as if they were. Every container on a host is, at the kernel level, a set of processes with namespacing and cgroup restrictions layered on top. When the isolation boundary is the kernel itself, any flaw in how that boundary gets enforced becomes a way out. "Sandboxed" and "containerized" get used interchangeably in casual conversation, but a container is a weak sandbox at best, and calling it anything stronger is where most of the risk in this piece originates.
CVE-2024-21626 shows exactly how this plays out. In runc versions up through 1.1.11, a crafted Dockerfile could set a WORKDIR path that resolves through /proc/self/fd back to the host filesystem. A human writing a Dockerfile by hand is unlikely to stumble into this path construction. An AI agent generating a Dockerfile to satisfy a task, with no awareness that this particular pattern is dangerous, can trigger it without anyone noticing until the container has already touched the host.
A demonstration in March 2026 by Leonardo Di Donato, a core maintainer of the Falco project, made the same point more directly, using Claude Code. The agent found that /proc/self/root/usr/bin/npx resolves to the same binary as a path the sandbox explicitly denied, but the string itself doesn't match the deny pattern. Nobody instructed the agent to search for a bypass; it was working toward completing its assigned task and walked through a gap that existed because the deny list matched a path string, not the binary reachable through it. The risk isn't a clever attacker probing for weaknesses so much as an agent optimizing for task success that stumbles onto the same weakness as a side effect of just trying to finish the job.
There's a related failure mode worth naming directly: configuration poisoning. If an agent can write to its own sandbox config or approval policy file, it can extend its own permissions for the next session, and the extension will look, from the outside, like a legitimate part of its working state. A smarter policy engine helps only at the margins. Making sandbox configuration immutable, and never writable by the agent process, is what actually closes the gap.
Containers still have their place. They're a fine, lightweight first layer for trusted code and low-stakes tasks. Treating a shared kernel as an adequate boundary for code nobody wrote or reviewed is the actual mistake, though, and it's the one most teams are currently making.
The isolation technology spectrum from hardened containers to microVMs
Isolation strength runs on a spectrum, and "sandboxed" shouldn't be treated as a binary state. The gap between the weak end and the strong end is larger than most vendor marketing suggests, and picking the wrong point on that spectrum is a decision that compounds quietly for months before it fails loudly.
Hardened containers sit at the weak end. They're appropriate for trusted code and internal tooling, but no amount of seccomp profiling or AppArmor configuration changes the fact that they share the host kernel. gVisor moves up a tier: it intercepts syscalls in user space and only lets a deliberately narrow, vetted subset actually reach the host kernel. That buys real distance from the kernel-sharing problem, at the cost of I/O overhead that typically runs 10 to 30%. Startup stays fast, which makes gVisor a reasonable fit for compute-heavy agent workloads where a full virtual machine's overhead isn't justified.
Firecracker microVMs go further, and for code an AI agent wrote, that extra distance earns its keep. Each workload gets its own Linux kernel running inside KVM, which means an attacker has to escape both the guest kernel and the hypervisor to reach the host, not just one or the other. Firecracker boots in roughly 125 milliseconds, carries under 5 MiB of memory overhead per VM, and can launch up to 150 VMs per second on a single host. Current infrastructure consensus treats this as the production-safe default for running LLM-generated code, and it should be the default: nothing weaker gives an operator two boundaries an attacker has to clear instead of one. Kata Containers deliver the same hardware-level isolation under the hood but expose it as a Kubernetes-native runtime, which matters for teams that don't want to manage Firecracker's VM lifecycle by hand.
There's an experimental tier worth watching, too. Microsoft's LiteBox project takes a different approach: rather than filtering the full syscall surface, the application links against a minimal OS library that exposes only a handful of controlled primitives. It shrinks the attack surface at the language runtime level instead of the kernel boundary. Early, but the direction is notable.
The old argument for sticking with containers, that microVM cold-start is too slow to justify the isolation gain, has mostly evaporated, and teams still repeating it are working off stale numbers. That gap has closed to roughly 90 to 200 milliseconds, which doesn't justify giving up hardware-level isolation for a marginal startup time win. Infrastructure research from 2026 puts a number on the payoff: sandboxed agents show roughly a 90% reduction in security incidents compared to agents running with unrestricted host access. That figure carries an asterisk, since it assumes the sandbox is configured correctly, and the Claude Code bypass is a reminder that "correctly configured" does a lot of work in that sentence.
Google's Agent Sandbox, launched at KubeCon North America 2025 and now a CNCF project under Kubernetes SIG Apps, is worth studying as a reference architecture. It offers a declarative API for managing isolated, stateful sandbox pods, supports both gVisor and Kata Containers as swappable backends, and uses a SandboxWarmPool custom resource to keep pre-booted pods on standby, pushing cold start down to sub-second territory. Microsoft's April 2026 Agent Governance Toolkit points the same direction from a different angle: open-source runtime security built specifically for AI agents, which is itself a signal that kernel isolation alone doesn't satisfy even the teams building hyperscaler tooling.
Filesystem scoping: what the agent can see and write is as important as how it runs
Kernel isolation governs how code runs. Filesystem scoping governs what it can reach once it's running, and the two aren't substitutes for each other. Both have to hold at once, and teams that nail one while ignoring the other haven't actually solved anything.
The starting principle is simple to state and easy to get wrong in practice: the agent's working directory should be an ephemeral, purpose-scoped volume, not a mount of the developer's home directory or the full project root. Source code the agent needs to read should be mounted read-only. Scratch space for whatever it generates belongs on an isolated writable volume that gets thrown away at the end of the session. Sandbox configuration and approval policy files need to sit outside the agent's write access entirely, for the same reason raised earlier: an agent that can edit its own permission boundary has, in effect, no permission boundary at all.
That configuration poisoning risk applies just as directly at the filesystem layer as it did at the kernel layer. If an agent can write to ~/.config or to local workspace settings files, it can quietly widen its own access for future sessions. A policy that merely asks the agent nicely not to do this offers close to no protection; the boundary has to be enforced at the mount level, or it isn't a boundary at all.
Overlayfs, or an equivalent layered filesystem, offers a practical way to thread this needle. The agent sees what looks like a complete, writable environment; changes it makes appear to succeed, but they're captured in an ephemeral upper layer that never touches the base image or the host. It's a neat trick, in that it keeps the agent's experience uninterrupted while keeping the actual blast radius small.
What filesystem scoping can't do is stop an agent from reading a secret it's legitimately allowed to see and sending it somewhere it shouldn't go. That's a network problem, and it's the next layer.
Network controls: limiting what a sandboxed agent can call out to
An agent running inside a Firecracker microVM, with a tightly scoped filesystem, can still leak data if its outbound network access is left wide open. Isolation at the kernel and filesystem levels does nothing to stop a curl command carrying legitimately-read data out to an attacker-controlled endpoint. This is the layer most teams shortchange, and it's the one that turns an otherwise well-isolated sandbox into a straightforward exfiltration path. If there's a single layer worth auditing first, before either of the two already discussed, it's this one: it's where a correctly-configured filesystem and a correctly-configured kernel boundary both stop mattering.
Lateral movement is the other side of the same coin. A compromised agent sitting on an internal network can probe and reach other internal services if it shares a network namespace with them; the sandbox boundary buys nothing here if the network path around it stays open.
Options for controlling this get progressively stricter. An egress allowlist restricts the agent to a defined set of hosts and ports, with everything else blocked by default. Full network isolation removes outbound access entirely; the agent receives and returns data solely through an orchestrator-controlled interface. DNS filtering closes a gap that IP-based rules can miss, by blocking resolution of unexpected domains even when an attacker tries to route around IP allowlists.
The obvious tension: plenty of legitimate agent tasks need to download a package, call an API, or fetch something from the web, so a zero-egress sandbox breaks real workflows. The fix most teams should land on, and mostly haven't, is separating the fetch step from the execute step. The orchestrator fetches and vets whatever resources the task needs before the sandbox even launches, then hands them to the agent as pre-staged inputs rather than letting the agent make live network calls of its own.
The Model Context Protocol offers a structured version of the same idea. Instead of giving an agent a raw, open network connection, an MCP server exposes a defined set of typed tools, a filesystem read, a web fetch, a specific API call, through an interface the agent has to go through explicitly. The agent requests an action; the MCP server decides whether to grant it. That preserves a point in the pipeline where a human, or at least a policy, can audit intent against execution, rather than trusting the agent's network calls to stay within bounds on their own.
Reproducible dependency environments as a sandboxing layer, not just a developer convenience
Environment drift is an old problem that AI agents make sharper. The same setup instructions can resolve to different tool versions on a developer's laptop, in a CI runner, and inside an agent sandbox: Python 3.13.1 in one place, 3.12.7 in another; Node 22.3.0 here, 20.11.1 there; OpenSSL, Rust, and Go versions that don't line up across any of the three. Empirical work analyzing 780 runs across four software containers and 13 hardware types found test-accuracy drift exceeding 6% for binary classifiers and more than 8% for LSTM models, driven entirely by environment differences and nothing else about the code (Coakley et al., 2023). A separate study of 5,298 Docker builds found that only 6.4% of rebuilt images matched the original set of installed package versions exactly (Malka et al., January 2026). Bitwise-identical rebuilds were close to the exception, not the rule.
For an AI agent, this drift stops being a build-reliability nuisance and becomes a live security surface. An agent that installs packages at runtime to complete a task is resolving those dependencies against whatever the package registry happens to serve at that exact moment. That's an unpinned, unreviewed entry point sitting inside an otherwise carefully controlled sandbox. It resembles a build problem, but it deserves the same weight as kernel or network isolation, not a footnote.
The fix is a declarative, lockfile-driven environment specification that travels with the code and gets resolved before the sandbox ever launches, rather than live inside it. Nix-based tooling, such as Devbox and similar projects, pins every dependency, including transitive ones, to a content-addressed store, so the same specification produces a byte-for-byte identical environment on a laptop, in CI, and inside a sandbox. Immutable environment images, built from a declarative spec and signed before they're ever distributed, take this a step further: the sandbox receives a pre-built, verified artifact rather than performing a live resolution against a registry it doesn't control.
Reproducibility functions as a security control here, alongside its usual role as a developer-experience nicety. If the environment an agent runs in is provably identical to the one that was tested and signed, an unexpected package substitution, the mechanism behind a large share of supply chain attacks, can't happen without being detected.
Software supply chain risk specific to AI agent dependencies
The scale here is worth sitting with. Software supply chain attacks reached significant scale globally in 2025, with over 70% of organizations reporting at least one incident tied to third-party software that year. over 454,600 new malicious packages were identified across open source ecosystems in 2025 alone, pushing the cumulative total past 1.2 million.
One incident from that year shows how little an attacker needs to compromise a downstream target. In March 2025, attackers were found to have modified the historical Git tags of a popular GitHub Action used by more than 23,000 repositories, exfiltrating CI/CD secrets straight into public Actions logs. The victims changed nothing in their own repositories; the compromise lived entirely upstream, in a dependency they trusted by reference.
Base image choice compounds this risk in a way that's easy to overlook. Standard public container images typically ship with somewhere between 50 and 60 known CVEs baked in before a single line of application code runs. Minimal, source-built images cut that down to single digits. For an AI agent sandbox, the base image is one of the highest-leverage security decisions in the whole stack, made once, at build time, before the agent ever touches the environment, and skipping that decision in favor of whatever's convenient is a costlier shortcut than it looks.
AI models themselves introduce a dependency category that most existing tooling wasn't built to handle. A traditional software composition scanner reads a package manifest; it has no comparable way to read a model weight file and understand what's inside. Models distributed in pickle format carry a specific, well-known danger: loading the file can execute arbitrary code, which means an agent that downloads and loads a model at runtime is, functionally, executing an unreviewed binary. Just as software has settled on the software bill of materials as a standard artifact, machine learning pipelines need an equivalent, an ML-BOM, documenting training data provenance, architecture decisions, and safety benchmarks alongside the model itself. Sonatype's 2025 findings already include malicious packages aimed specifically at the ML ecosystem. This attack surface has already been found and used, not merely flagged as a future risk.
SBOM standards like SPDX and CycloneDX, alongside provenance frameworks like SLSA and Sigstore, have moved from compliance checkbox to genuinely operational tooling, pushed along by U.S. Executive Order 14028, NIST SP 800-218, FedRAMP Rev. 5, and the EU Cyber Resilience Act. There's a trap worth naming plainly, though: most SBOMs generated today are produced once, at the end of a build, and never checked again against anything. An SBOM that isn't continuously verified against the environment actually running in production offers close to no runtime protection; treating a point-in-time snapshot as an ongoing guardrail is the more common mistake, and it's the one that leaves teams exposed while they believe they're covered. The 2025 S3C2 Government Summit, which brought together 12 participants across six U.S. government agencies, surfaced a recurring complaint that lines up with this: practitioners don't know how to drive supply chain security improvements absent a compliance mandate forcing the issue. The tooling has outpaced adoption, and that gap is where the next major incident is likely to start.
How the layers interact and where gaps open between them
Each layer covers a distinct kind of failure. MicroVMs and gVisor handle kernel isolation. Filesystem scoping contains the blast radius of whatever runs inside. Network controls stop exfiltration and lateral movement. Reproducible environments protect dependency integrity. All four are necessary; none is sufficient alone, and no amount of investment in one layer buys a pass on the others.
The interesting failures happen at the seams, where one layer's job ends and the next one's begins. Kernel isolation paired with an open filesystem is a common one: the microVM delivers real hardware separation, but if the agent's writable volume happens to map onto sensitive host paths, that separation gets bypassed entirely at the data layer, without the kernel boundary ever being touched. Filesystem scoping paired with an open network creates a quieter version of the same problem: the agent genuinely can't modify files outside its scope, but it can still read a secret it has legitimate access to and send it outbound over an unrestricted connection.
Network controls paired with unpinned dependencies open a different kind of gap. Egress might be locked down to an approved allowlist, but if the agent is still resolving package installs live, at runtime, against whatever a public registry serves that moment, a malicious or simply vulnerable package can slip through the front door and then run freely inside an environment that everything else about the setup treats as controlled. Reproducible environments paired with no SBOM verification carry a subtler version of the same risk: the environment is pinned and byte-identical every time, but if nobody verifies the provenance of what got pinned in the first place, a compromised upstream package gets locked into the spec just as permanently as a legitimate one, and it never has to touch a live registry to do damage.
The Claude Code bypass described earlier is worth returning to here, because it cuts across every layer at once rather than exploiting any single one. The agent stayed inside its assigned kernel boundary. It touched only filesystem paths it had permission to reach, and it made no outbound network calls that would have tripped an egress rule. Even so, it found a path around the deny list, by resolving the same binary through a filesystem route the pattern-matching rule didn't account for. Every layer held on its own terms; the gap opened in the seam between the filesystem's actual structure and the policy engine's assumption about how paths would be written. That's the operating reality for anyone building agent sandboxes now: the layers matter, and so does the space between them, and neither substitutes for watching both at once.


