Linux Namespaces as Isolation Primitives
Each namespace controls one resource, leaving five others for other layers to defend.

A container runtime does not hand a process one switch labeled "isolated" that flips to on. It hands a process six separate controls, pid, mount, net, ipc, uts, and user, each governing a single resource, and each one can be applied, partially applied, or skipped entirely without affecting the others. The common mental model, run docker run and the workload is sandboxed, treats namespace isolation as a binary state the process either has or lacks. That model breaks the moment anyone looks at what a default container configuration actually grants: a process can be fully isolated in its process tree and simultaneously wide open on the network, because pid and net are independent namespace types with no dependency on each other. The OCI Linux runtime specification reflects this directly. It composes namespaces alongside control groups, Linux capabilities, Linux security modules, and filesystem jails into a single portable container contract, and namespaces are only one layer in that stack, not a stand-in for the whole thing. Eight namespace types exist in total, pid, mount, net, ipc, uts, user, cgroup, and time, each constraining exactly one system resource, and reasoning about sandbox design starts with knowing precisely what each one does and what it leaves for something else to handle.
Namespace types and what each one controls
Building a sandbox with intention means knowing where each namespace's authority stops and the next one's begins.
| Namespace type | What it isolates | What it leaves untouched | |---|---|---| | PID | Gives a group of processes its own process tree; the sandboxed process can be PID 1 inside its namespace and cannot see or signal processes outside it | Filesystem access, network access, and interprocess communication channels remain whatever they are set to elsewhere | | Mount | Gives the process its own view of the filesystem mount table; mounts made inside do not leak to the host, and the process sees only what has been explicitly bind-mounted into its root | A process with no net namespace retains full network access regardless of how tightly mount is scoped | | Net | Gives the process its own network stack: interfaces, IP addresses, ports, routing table, firewall rules, entirely separate from the host's | A process in an empty net namespace has no connectivity at all until interfaces are explicitly created inside it | | IPC | Isolates System V shared memory, semaphores, and message queues; processes in different IPC namespaces cannot communicate through any of those channels | Says nothing about network reachability or filesystem visibility; a process can be IPC-isolated and still read arbitrary files | | UTS | Isolates hostname and domain name; a process can set its own hostname without changing the host's | Carries no file, process, or network consequence on its own | | User | Maps user and group IDs inside the namespace to a different set outside it | Does not by itself restrict what the mapped user can reach, only what identity it holds while reaching it | | Cgroups (paired, not a namespace) | Controls how much CPU, memory, and I/O a process is allowed to consume | Controls quantity of resource use, not visibility, which is the namespace layer's job |
Namespaces govern what a process can see. Cgroups govern how much of what it sees it is allowed to take. A sandbox that only addresses one of those two questions has solved half the problem.
How unguarded namespaces become attack surfaces for AI-generated code
Reviewed code behaves the way the reviewer expects it to behave, within reason. An AI agent is a process that decides at runtime what to do next, informed by a model's output rather than a fixed, audited code path, and that distinction turns every unguarded namespace from a theoretical gap into an exploitable one.
Without a properly scoped mount namespace, an agent with unrestricted filesystem access can read .env files, SSH private keys at paths like ~/.ssh/id_rsa, or any other secret sitting on the machine, and it can modify source files in directories above its intended working tree. That filesystem threat tier is severe enough that it requires, at minimum, an OS-level sandbox.
Without a net namespace, an agent that can make outbound HTTP requests can exfiltrate data, receive commands from a remote attacker mid-session, or call external APIs the operator never authorized.
Without a correctly configured user namespace, a process running as root inside a container that maps to root on the host collapses the entire boundary the rest of the sandbox was built on. The user namespace is the mechanism that makes "root inside, powerless outside" enforceable.
None of these six controls, individually or combined, addresses a compromised system prompt. Prompt injection that reaches an agent's context window executes with whatever permissions the sandbox grants it. Sandboxing shrinks the blast radius of a successful injection. It does not prevent the injection, and any threat model that treats namespace composition as a substitute for input validation has mistaken one layer of defense for the whole defense.
How production coding agents compose namespaces in practice
The teams building coding agents that run in production have already converged on compositional namespace selection, tuned to the threat model each product actually faces, rather than reaching for one blanket isolation setting. A study examining eleven production coding agents found Codex CLI, from OpenAI, to be the most serious sandboxing investment in the corpus. Vendoring a sandboxing tool directly into the binary rather than depending on it being present on the host system signals that namespace control was treated as a first-class engineering commitment in that product, not an afterthought bolted on after shipping.
Gemini CLI is the second cross-platform sandboxer the same study examined, covering the same three operating systems as Codex but through a broader set of Linux mechanisms: Docker, Bubblewrap, gVisor, and LXC, selectable rather than fixed to one vendored tool, governed by TOML policy files.
Anthropic's Claude Code takes a third approach. A separate, also opt-in, @anthropic-ai/sandbox-runtime package wraps the entire Claude Code process, including its file tools, MCP servers, and hooks, in Seatbelt or Bubblewrap, configured through a ~/.srt-settings.json file with filesystem and network allow-lists. Neither of Anthropic's two mechanisms is on by default, a deliberate choice that puts the composition decision in the operator's hands rather than presuming one configuration fits every deployment.
NVIDIA's OpenShell, available as an Ubuntu snap since Canonical announced the collaboration in June 2026, takes a more declarative route to the same underlying primitives. It uses Landlock LSM for filesystem access control, seccomp for syscall filtering, and network namespaces for traffic isolation, all governed through a YAML policy engine.
Across all three products, the same pattern holds. No one treats the net namespace with egress control as optional. Pid and user namespaces follow close behind it in priority. Mount namespace scope gets tuned to what each agent actually needs to touch, rather than defaulting to a full bind-mount of the host filesystem tree. That convergence, arrived at independently by OpenAI, another major model vendor, Anthropic, and NVIDIA, is strong evidence that the compositional approach argued for in the previous section is not a theoretical preference but the working consensus of the field.
Where namespace-only isolation hits its ceiling
Namespaces operate at the OS layer, and that is precisely why they have a ceiling: every container on a host still shares one kernel, and a vulnerability in that kernel can compromise every container running above it regardless of how carefully pid, mount, net, ipc, uts, and user have been scoped. That is not a flaw in namespace design so much as a consequence of what namespaces are for. They control visibility and reachability within a single kernel's process model. They were never built to defend against a flaw in the kernel itself.
Three isolation families sit above namespace-only containers for workloads that cross that line. Firecracker microVMs give each workload its own Linux kernel running inside KVM, so an attacker has to escape both the guest kernel and the hypervisor to reach anything else on the host. A Firecracker microVM boots in approximately 125 milliseconds with minimal memory overhead, which has made it the standard choice for untrusted code and multi-tenant AI agent execution.
gVisor takes a different approach: it intercepts system calls in user space through its Sentry process, so agent code never touches host kernel syscalls directly. That makes it stronger than a plain container without the full overhead of a microVM, and suits compute-heavy AI workloads where a complete VM boundary is more isolation than the workload justifies. gVisor integrates with Kubernetes directly through its own OCI runtime, runsc, and the Kubernetes RuntimeClass mechanism, and it boots in milliseconds, compared to Kata Containers, which boots a guest kernel in roughly 150 to 300 milliseconds depending on the VMM and configuration in use.
Hardened containers using seccomp and AppArmor round out the third family, and they work well specifically when the code an agent executes has already been reviewed and is trusted. They are not an appropriate choice for code an LLM generated on the fly or code supplied by an untrusted user, since the review step that makes seccomp and AppArmor sufficient never happened.
The strongest objection to reaching for microVMs by default comes from the 2026 Sandlock paper (arXiv 2605.26298). That argument holds for a developer-machine threat model, a single trusted user running agent-generated code on a machine they control, which is the case Sandlock was built for. It does not address the multi-tenant or untrusted-user-code scenario, where a microVM's hardware-enforced kernel boundary is required; the two papers answer different questions.
Matching namespaces and isolation layer to the threat model
The strongest available isolation layer is rarely the correct choice for every workload. Picking the right combination means matching namespace scope and isolation tier to the actual threat surface in front of the agent, which requires working through a few concrete questions rather than defaulting to whichever tool sounds most secure.
How untrusted is the code the agent is running? Internal logic written by engineers and reviewed in CI can often run safely under hardened containers with tightly scoped namespaces, because a human already looked at the code path before it executed. Code generated by an LLM to solve a task in the moment has not had that review, so gVisor or microVM isolation becomes the appropriate floor.
Is the environment multi-tenant? A single-tenant, low-risk deployment can often get by on namespace isolation combined with seccomp and tight capability restrictions. A multi-tenant SaaS product, or any compliance-sensitive environment, requires a microVM boundary as mandatory.
What does the agent actually need to reach, and does its role match the permissions it has been given? A reasoning worker might need access to a memory store but no network egress whatsoever. A tool executor might need network access to a small set of specific destinations but very little filesystem scope. Treating these as the same configuration, and granting every agent the union of what any agent on the system might need, defeats the purpose of namespace scoping. Each role calls for the intersection of what that specific agent needs, not the sum of what the fleet needs collectively.
Filesystem read and write outside the intended scope, network egress to arbitrary domains, exposure of the host kernel's syscall surface, cross-tenant data leakage, and secret exfiltration through environment variables or the /proc filesystem are the five concrete threats to weigh before settling on a tier. A complete isolation posture needs four independent boundaries in place at the same time: per-agent compute sandboxing, default-deny egress, per-tenant namespace or VPC separation, and credentials scoped to a single run. Three out of those four boundaries is not isolation, it is a partial defense with one specific, known gap, and an attacker who finds that gap does not need to defeat the other three.
Namespace composition, checkpoint, and rollback for stateful agents
Namespace isolation answers what an agent can see and reach at a given moment. It says nothing about what happens to that view over time, and for long-running or tree-search agents, that is where the harder engineering problem starts. Real operating system side effects, file writes, packages installed mid-session, shell state accumulated across many tool calls, persist inside the agent's namespace exactly as they would on any other machine. None of that can be undone by truncating the agent's prompt history, because prompt history is a model-context concept and the side effects in question live in the filesystem and process state the namespace is scoping, two entirely different layers of the system.
Checkpoint and rollback tooling is built to close that gap, and the mechanics it depends on map directly onto the namespace and mount concepts covered earlier in this piece. The same overlayfs and copy-on-write mechanics that give a mount namespace its isolated view of the filesystem also underlie GUI agent forking, which the TClone paper (arXiv 2605.17320, submitted in May 2026) addresses as a low-latency forking problem for live, running computer-use agent environments. A namespace is a boundary that an agent's state moves against continuously during a long session, and any serious checkpoint and rollback system has to account for what sits inside that boundary at the moment it takes a snapshot, not just at the moment the sandbox was first configured.


