An agent that writes code becomes useful the moment it can run that code. It also becomes dangerous at exactly the same moment.
Once an agent has a shell, a Python interpreter, or a container build step, your infrastructure starts executing instructions that no human reviewed. The model writes the command. The runtime runs it. Nothing in that loop asks whether the command was a good idea. This is not a theoretical risk, and the industry stopped treating it as one. Through 2026 the practitioner consensus hardened into something blunt: shared-kernel container isolation is not an acceptable default for code you did not write.
The threat is easy to describe. Prompt injection hides instructions in content the agent reads: a web page, a PDF, a support ticket, a tool response. Because the agent has a shell, it can act on those instructions. A poisoned document turns into a remote code execution primitive. Add a credential the agent can see and you have an exfiltration path. The OWASP Top 10 for LLM Applications (2025) ranks prompt injection first and excessive agency sixth, and the follow-on Agentic AI Top 10 puts tool and plugin misuse in its top three. Traditional controls do not map cleanly here. A web application firewall does not understand an agent's reasoning chain. A data loss prevention tool does not inspect an LLM's context window. Your endpoint agent sees a legitimate process on a legitimate host.
Why ordinary containers are not enough
Docker and runc give you Linux namespaces, cgroups, seccomp filters, and dropped capabilities. That is a solid boundary for workloads you trust, and it stays the right answer for agents that only call APIs your team wrote. It is a weak boundary for untrusted code because every container on the host shares one kernel. A single kernel exploit crosses from the agent's process into yours. The blast radius of a breakout is the host, not the sandbox.
Treat the distinction as a rule rather than a preference. If a human reviewed the code, a hardened container is fine. If a model generated it, the container is the wrong tool. The 2026 guidance from platform vendors and independent researchers converges on the same sentence: do not run model-generated or user-supplied code in a shared-kernel runtime and call it sandboxed.
What a real attack looks like
The chain matters more than the label. An agent is asked to summarize a vendor's onboarding guide. The guide contains a hidden paragraph instructing the agent to check its environment for API keys and POST them to an external URL. The agent has a shell, reads the environment, finds a long-lived cloud token someone mounted for convenience, and complies. The model never decided to attack anyone. It followed the most recent instruction in its context, which is what language models do.
Two controls break that chain, and neither is a filter on the prompt. The first is egress: a sandbox that cannot reach the attacker's URL fails the exfiltration step even with the token in hand. The second is credential scoping: if the token was short-lived and limited to one bucket, the theft buys nothing. Detection might have flagged the odd network call. Detection alone would not have stopped it, which is why deterministic controls carry the weight.
Four isolation primitives, strongest boundary first
MicroVMs
Firecracker and Kata Containers give each workload its own kernel inside a lightweight virtual machine. The isolation is a hardware boundary, so a kernel exploit inside the sandbox never reaches the host kernel. This is the strongest practical option available today, and Firecracker's role as the foundation of AWS Lambda says something about its operational maturity. E2B, the reference agent-sandbox project, is built on Firecracker: it boots a session in roughly 150 milliseconds, resumes from pause in about a second, and caps sessions between one and twenty-four hours. Fly.io's Sprites and Blaxel sit in the same family. The price is memory overhead per sandbox and cold starts that are slower than a plain container.
User-space kernels
gVisor intercepts syscalls in user space and reimplements the parts of the Linux ABI a workload needs. You get a real kernel boundary without the full weight of a virtual machine, which suits compute-heavy agents with limited I/O. Modal runs gVisor on KVM and leans on it for GPU-adjacent batch work. The tradeoff is syscall coverage. Some workloads hit a path gVisor has not implemented and need a fallback to something else.
Hardened containers with extra isolation
Sysbox lets a container run its own init system, systemd, or even nested Docker while still mapping to the host isolation model more tightly than a privileged container would. Daytona runs OCI containers with optional Kata or Sysbox and advertises cold starts under 90 milliseconds. This is the pragmatic middle ground for teams where microVM overhead is too much to justify but plain runc is too loose.
Language-level isolates
Cloudflare's Dynamic Workers, in open beta since April 2026, run each execution context in a V8 isolate. Startup is measured in sub-milliseconds, roughly a hundred times faster than a microVM, with ten to a hundred times less memory per context. The boundary is not a kernel, so this fits short-lived, high-frequency tool calls rather than long jobs that need a real filesystem or arbitrary binaries.
Matching the sandbox to the workload
Applying the strongest boundary to everything is expensive and slow. Pick by what the code actually does.
- An agent that only calls your own APIs needs scoped credentials and a normal process, not a sandbox.
- An agent running automation scripts your team reviewed can live in a hardened container with seccomp, AppArmor, and no added capabilities.
- An agent executing model-generated shell commands belongs in a microVM or under gVisor. No exceptions.
- An agent running thousands of tiny, stateless snippets per minute is the one case where a V8 or WASM isolate beats a microVM on both latency and cost.
The trap is defaulting every agent to the same runtime because it is easier to operate. Two tiers, one hardened container pool and one microVM pool, covers most enterprise fleets without the operational drag of a third.
The confused deputy problem
Agents usually run under their own identity, not a user's. That creates a classic confused deputy: a low-privilege user asks the agent to do something, the agent does it with its own high-privilege credentials, and the privilege check that should have failed never runs. Non-human identities now outnumber human ones in most large environments, and an agent that can act across systems concentrates privilege in a single token.
Two habits reduce the damage. Attribute every tool call to both the agent and the requesting user, so audits show who triggered an action rather than just which service performed it. Then split the agent's rights so the planning step cannot also perform the write. An agent that can decide and act with the same credential cannot be constrained by policy after the decision is made.
The boundary is the floor, not the ceiling
Isolation stops an escape. It does nothing about what happens inside a sandbox the agent legitimately controls. Layer these on top.
Network egress control is the highest-value control after isolation itself. A sandbox that cannot reach the internet cannot exfiltrate anything, regardless of what the model was tricked into running. Default to deny, allowlist the package registries and internal endpoints the workload genuinely needs, and log every blocked attempt as a signal.
Resource limits stop a runaway loop from becoming an outage. Cap CPU, memory, disk, process count, and wall-clock time per sandbox. Skip this and one agent pinning a node for an hour is the predictable failure.
Credential scoping matters more than most teams expect. Most agent breaches are not exotic kernel escapes. They are an agent holding an over-broad token that a prompt injection learned to use. Issue short-lived credentials per task, scope them to the single resource the task needs, and never mount a long-lived cloud key into a sandbox.
Deterministic controls outside the reasoning loop are worth more than any filter inside it. The Frontier Model Forum's 2026 brief makes the point directly: because prompt injection research is still maturing, do not rely on detection. Put hard limits on which tools an agent may call and which actions it may take, in a layer the model's context cannot rewrite. Meta's Agents Rule of Two frames the same idea as a design constraint. A control the model can argue its way around is not a control.
Monitoring closes the loop. You want step-level visibility into what the agent executed, which files it touched, and what it tried to reach over the network, all correlated to the session that produced it. Without that correlation, an incident review is guesswork and every alert looks the same.
Compliance is arriving on a schedule
Europe's AI Act makes the regulatory case for containment concrete. Obligations for high-risk systems begin applying on 2 August 2026, with penalties that can reach 7 percent of global annual turnover. An agent that executes code in production, touches customer data, and influences decisions that affect people is squarely in scope. An auditor will ask what boundary separated generated code from production systems, what limited its network reach, and what record exists of what it executed. Those answers have to exist before the question is asked, which means the sandbox decision is a compliance decision, not just an engineering one.
What this costs
MicroVM sandboxes are not free. Budget memory per sandbox, expect cold starts between 150 milliseconds and one second, and account for session caps that force state to be checkpointed and restored. E2B pauses a sandbox in about a second; Fly.io checkpoints in roughly 300 milliseconds. If your agents run long jobs, build checkpointing into the design instead of discovering the need when a 24-hour cap kills a task mid-run.
Managed sandbox platforms price per second, which is manageable for bursty use and painful for agents that idle. The deciding variable is whether the platform bills for standby. Some zero out cost while a sandbox is paused; others keep the meter running. Model that against your real duty cycle before signing a contract, because an agent that idles 90 percent of the day is a very different bill than one that runs flat out.
Red-team the sandbox
A boundary you have not tested is an assumption. Point a prompt-injection suite at a staging agent and try to make it escape, reach the internet, read a file outside its working directory, or spend a credential it should not hold. Run the same tests after every change to a tool definition, a system prompt, or the sandbox image itself. The Frontier Model Forum guidance expects testing before launch and after every material change, which in practice means treating the sandbox configuration like any other production artifact with its own test suite.
A path you can start on Monday
Inventory every agent that can execute code, including the ones a team spun up without telling anyone. Assign each to a tier. Move anything running model-generated code behind a microVM or gVisor before you do anything else. Turn on network egress deny-by-default and the resource caps in the same change, since isolation without egress control leaves the exfiltration path open. Move credentials to short-lived, per-task tokens. Add step-level monitoring last, because it is far less useful without the isolation underneath it.
None of this is novel security engineering. It is the same containment discipline you would apply to any untrusted workload, pointed at a new source of untrusted code. The teams getting this right in 2026 are not the ones with the cleverest guardrails. They are the ones that assumed the model would eventually be fooled and built the boundary so that being fooled would not matter.
Where to start
- Default to running model-generated code in a microVM or under gVisor, never a shared-kernel container.
- Deny network egress by default and allowlist only what the workload needs.
- Cap CPU, memory, disk, process count, and wall-clock time per sandbox.
- Issue short-lived, single-resource credentials per task and rotate them automatically.
- Enforce tool and action limits outside the model's context window.
- Attribute every tool call to both the agent and the user who triggered it.
- Test the boundary with a prompt-injection suite before launch and after every change.
If your team runs agents in production and cannot answer which isolation boundary stands between generated code and your systems, that gap is worth closing before the next agent ships.