← all discussions
sandboxing

Do AI coding agents require a different isolation model?

rorohitm3 days ago6 replies

Coding agents run arbitrary commands, install packages and hit the network. A normal container shares the host kernel. Is that enough boundary for code nobody reviewed?

Discussion

nunullroute3 days ago

For untrusted code I'd want a microVM boundary — Firecracker or similar. Containers were built to package software, not to contain adversarial code.

Reply
rorohitm3 days ago

The agent isn't adversarial, but what it downloads might be. That's the part that changes the threat model.

Reply
srsre_lena2 days ago

Network egress controls matter as much as the kernel boundary. Most leaks happen over the network.

Reply
kckchen2 days ago

gVisor is a reasonable middle ground when microVMs are too heavy for the workflow.

Reply
vmvmkernel2 days ago

I've spent most of this year building sandboxes for exactly this workload, so here's a longer brain dump. Short version: containers are the right *packaging* and often the wrong *boundary*.

What makes coding agents different from normal untrusted CI jobs:

- They choose their own commands. A CI job runs a script someone reviewed. An agent decides at runtime to run pip install on a package name it inferred from an error message. - They loop. A CI job runs once. An agent might execute 200 commands in a session, each a new chance to pull something hostile. - They read hostile input. Issue text, READMEs, web pages, test output. Prompt injection means the input can steer which commands run next. - They need the network. You can't just cut egress, because installing dependencies is half the job.

Given that, here's the layered setup we ended up with:

┌─────────────────────────────────────┐
│ microVM (Firecracker)               │  ← kernel boundary
│  ┌───────────────────────────────┐  │
│  │ container (rootless, no caps) │  │  ← packaging, fs layout
│  │   agent workspace             │  │
│  └───────────────────────────────┘  │
│  egress proxy (allowlist + log)     │  ← network boundary
└─────────────────────────────────────┘
   secrets broker (short-lived, scoped) ← credential boundary

A few lessons that weren't obvious up front:

Boot time matters more than you think. If a sandbox takes 8 seconds to start, people will reuse sandboxes across tasks, and that's where state leaks between sessions. We got Firecracker cold start under 200ms with a pre-baked rootfs snapshot and that single change did more for isolation than any policy did.

Egress allowlists rot quickly. Package registries redirect to CDNs, CDNs change hostnames, and suddenly installs fail. We moved to a caching proxy for PyPI/npm/crates, and everything else goes through an explicit allowlist with logging. The proxy also gives you a perfect audit trail of what got installed.

Never mount the Docker socket. I know this is obvious. I've still seen three internal prototypes do it "temporarily" so the agent could build images. If the agent needs to build, give it a rootless BuildKit inside the VM.

Secrets should be fetched, not injected. Environment variables end up in logs, crash dumps and env output the agent cheerfully prints. A broker that hands out 5-minute tokens scoped to one repo is a lot more boring when something goes wrong.

gVisor is fine for many cases. If your threat model is "buggy agent" more than "hostile code", gVisor gets you most of the syscall-surface reduction with much simpler ops. We use it for lint/test-only tasks and microVMs for anything that installs packages.

Where I'm still unsure: GPU workloads. Passing a GPU into a microVM is still painful, and a lot of agent tasks now want to run small models locally. I don't think anyone has a clean answer there yet.

Reply
rorohitm2 days ago

The "boot time decides isolation" point is the one I didn't expect but fully agree with. Every slow sandbox I've seen turned into a shared one within a month.

Reply