Infrastructure Review Stack

What a Sandbox Filesystem Boundary Actually Enforces

Process jails, containers, and microvMs each block different threats.

· 8 min read
Cover illustration for “What a Sandbox Filesystem Boundary Actually Enforces”
Choosing a Sandbox for AI Agents · October 24, 2026 · 8 min read · 1,791 words

A sandbox filesystem boundary is a stack of enforcement mechanisms. Process jails, containers, user-space kernels, microVMs, and kernel hooks each refuse different operations. Choosing and combining them requires a precise account of what each layer blocks, which processes it covers, and what it leaves to operator policy.

Why "the sandbox" is not a single enforcement mechanism

An engineer enables a coding agent’s sandbox and expects private files to be out of reach. Yet the agent can still have access to credential paths. Those beliefs do not line up by themselves. An agent running as the invoking user inherits that user’s filesystem access, while its choice of what to open follows model judgment. What, then, makes the system refuse access to the files it is expected to keep out of reach?

Claude Code’s security documentation makes the distinction concrete. Its documented default read behavior allows access to the entire computer, including credential locations such as ~/.aws/credentials and ~/.ssh/. The word “sandbox” can describe at least four distinct protections, namely the compute boundary, filesystem custody, network egress, and secret custody. A guarantee about where code executes does not establish which files it may read, which secrets it receives, or where it may send them.

What OS-process jails (bubblewrap, Seatbelt) actually refuse — and what they only ask about

OS-process jails put kernel enforcement behind a policy for subprocesses. In the sandboxed shell path, bubblewrap on Linux and Seatbelt on macOS govern shell commands and their children. When the policy denies an operation, the kernel refuses it. The command cannot use an application-level prompt to get past that refusal. Which operations actually enter that jail?

Claude Code’s documentation answers that question in its “Scope” section. The sandbox “isolates shell commands and their child processes,” while built-in file tools such as Read, Edit, and Write follow permission rules outside it. These are separate paths through the system. The kernel can block a shell command, while an agent file-tool call goes through an application-level check that decides whether to prompt the user.

Even the narrower guarantee depends on setup. Ubuntu 24.04 and later have a default AppArmor policy that prevents bubblewrap from creating the required user namespaces. The documentation also describes enableWeakerNestedSandbox for environments without privileged namespaces and states that it considerably weakens security.

What container namespaces enforce at the kernel boundary — and the shared-kernel gap they leave open

Standard Linux containers, including Docker and runc, provide genuine filesystem namespace isolation. A process sees only the mounted filesystem tree. The kernel remains shared. A vulnerability in a reachable kernel syscall path can therefore cross the separation that the filesystem view appears to establish.

gVisor’s documentation expresses this exposure directly. “This means the workload is only one system call away from host compromise.” That statement describes a trust boundary where an exploit is possible but need not occur. Hardening profiles using seccomp, AppArmor, SELinux, and dropped capabilities reduce the operations available to a workload. They do not give it a separate kernel.

The runc vulnerabilities CVE-2019-5736 and CVE-2024-21626 provide concrete evidence that runtime escape is not merely hypothetical. Both enable escape through the container runtime. Red Hat’s advisory states that SELinux in enforcing mode mitigates CVE-2019-5736 on Red Hat Enterprise Linux 7, illustrating how configuration changes exploitability. Containers are still a reasonable place to start for trusted development workloads, but untrusted AI-generated or user-supplied code needs more protection because a runtime escape can expose the host.

How gVisor's user-space kernel interposition narrows the syscall surface without hardware virtualization

gVisor changes which implementation receives the application’s syscalls. Its user-space Sentry process reimplements Linux syscalls, intercepting and handling application requests. In the described escape model, compromise requires both a flaw in the Sentry’s reimplementation and a separate vulnerability permitting escalation from user space. The workload no longer directly exercises the host’s full syscall surface.

That separation comes with compatibility and performance constraints. gVisor does not implement every Linux syscall, and workloads that issue syscalls frequently pay overhead for interception through the Sentry. Its own operation also requires a limited set of host syscalls. The host kernel remains reachable through that smaller surface, so the protection is software interposition.

This distinction gives gVisor a position of its own. It fits workloads that require container-compatible tooling but cannot accept the full per-workload kernel overhead of a microVM. Choosing gVisor depends on how well its syscall compatibility and interception costs fit the workload’s needs. Its interposition does not itself answer which credential files should be exposed or which outbound connections should be authorized.

What a microVM boundary actually enforces that a container or gVisor cannot

A microVM gives each workload a dedicated kernel running under hardware virtualization through KVM. A guest-kernel exploit on its own does not give control of the host kernel or other workloads. Hardware enforces that separation, rather than a policy restricting access to a shared kernel.

The filesystem view changes with that boundary. The agent sees the virtual block device presented by the hypervisor. Container mount-namespace escapes therefore do not apply to that view. Firecracker boots in approximately 125ms with roughly 5MB memory overhead per VM, making per-workload kernel isolation operationally viable for agent workloads at scale.

Passing a GPU through to a VM adds its own trust surface, and some production systems use containers when both the user and the agent need GPU access, knowingly accepting the weaker boundary. More generally, a microVM does not decide which files or secrets the operator supplies. Its kernel separation can hold while the workload reads an exposed credential and sends it through an allowed network connection.

What kernel-level hooks (BPF LSM, Landlock, seccomp) enforce that VM and container boundaries leave undeclared

Inside either a container or a microVM, a separate question remains. Which individual filesystem operations should the process be allowed to complete? BPF LSM hooks and Landlock can enforce path restrictions, while seccomp restricts which syscall numbers a process may invoke. These controls operate within the execution environment. They supplement the compute boundary.

A BPF LSM hook on lsm/file_open can return -EPERM for paths outside a declared project directory and stream every attempt to an audit log. That refusal happens at the kernel call site. Landlock instead lets a process declare its permitted path set before execution and confine its own future accesses. Once set, the process cannot widen that confinement. Seccomp combined with a BPF LSM policy further reduces the syscall surface available to code inside the boundary.

Without a syscall-level hook, determining which paths the agent actually reached requires reconstruction from side effects. A hook that exposes file-open attempts shows where actual access departs from intended policy. The existence of a VM says nothing about whether a particular file-open attempt was allowed, denied, or recorded.

What no individual layer enforces: secret custody and network egress as policy gaps above the compute boundary

Diagram: Four Layers of Sandbox Enforcement — and What Each Leaves Open. Visualizes: Visualize a vertical stack of four enforcement layers, each narrowing a different threat surface, but each leaving a distinct gap the next layer must fill.

Secret custody and network egress depend on declared policy. An API key placed in the sandbox filesystem is reachable by the agent process if its permissions allow access. Moving secrets into Docker’s secrets store or a vault sidecar is a separate choice about how to build the system. No compute primitive makes that choice automatically. Credential-bearing environment variables likewise reflect what the operator supplies.

The same asymmetry applies to outbound connections. Network egress defaults to permissive in most sandbox configurations, so an isolated microVM can still open arbitrary outbound sockets unless a policy blocks them. In the proposed architecture, an outbound proxy provides the single chokepoint the sandbox cannot bypass and enforces a default-deny allowlist. A filesystem-isolated process with unrestricted outbound access has a launchpad. Blocking system paths such as /etc, /var, /home, and /proc also requires an explicit policy.

Secrets make this gap particularly consequential. A blocked connection is an operational inconvenience, while an exfiltrated long-lived credential can remain useful after the sandbox disappears. The Open Agent Passport paper makes a related distinction between limiting the blast radius of code as it runs and stopping actions that have not been authorized. Pre-action authorization at the tool-call level is a separate enforcement mechanism.

How the layers interact when composed — and the gaps that only emerge at the seams

A microVM, BPF LSM policy, egress proxy, and external secrets store protect different parts of the same execution path. Their combined strength depends on their handoffs. What does each layer assume another has already refused? The subprocess-jail and file-tool split illustrates the danger of an unstated answer, because a restriction in one path does not automatically follow an operation through another. MCP servers, hooks, and extensions create further seams when they retain full process permissions outside the declared isolation layer.

Agentic workflows alternate between active steps and idle intervals, making those intervals useful checkpoint boundaries. Capturing state there avoids treating transient mid-execution peaks as the state to preserve. A meaningful restore point must account for filesystem and process memory together, rather than treating the filesystem boundary as independent of the process using it.

Tencent Cloud’s DeltaBox system illustrates that approach. It represents filesystem and process memory as a transactional, change-based state pair called DeltaState inside a Firecracker microVM, using a userspace daemon built on CRIU. On software engineering benchmark workloads, checkpoints take approximately 14ms on average to complete, and restore times are at or below 6ms at the 95th percentile. Infrastructure built for agents can spell out how component isolation and snapshot semantics work instead of relying on assumptions from generic developer tooling.

A practical decision framework for choosing and combining enforcement mechanisms

Enforcement should match the code’s trust level. OS-process jails suit subprocess isolation of trusted agent code on a developer workstation, provided distribution prerequisites are verified. Hardened containers with seccomp and mandatory access control suit trusted development workloads where startup latency outweighs isolation depth, but are insufficient for production AI-generated code. gVisor fits untrusted workloads that require container-compatible tooling and cannot accept per-workload kernel overhead, subject to syscall compatibility. MicroVMs such as Firecracker, with orchestration such as Kata Containers, fit production workloads handling untrusted generated code or sensitive user data.

The next decisions concern custody and access. Set which paths are mounted, state which system directories are restricted, and keep secrets exclusively in a dedicated external store. Enforce default-deny egress through an outbound proxy the sandbox cannot bypass. Add kernel-level path enforcement through BPF LSM or Landlock, with an audit mechanism that records actual access attempts.

Finally, verify coverage component by component. File tools, MCP servers, hooks, and extensions each need an identified enforcement path. For SOC 2, HIPAA, or GDPR-sensitive workloads, isolation and audit requirements belong in the initial architecture, since a shared-kernel container alone does not produce the required per-access record. The defensible choice for “a sandbox” is therefore a composed system whose refusals, policy dependencies, and handoffs can be explained.

Sources

  1. Before the Tool Call: Deterministic Pre-Action Authorization for Autonomous AI Agents
  2. AI Code Sandboxes: A Comparative Security Study. Part 1 of 2 -- Engine-Level Properties (Attack Surface, Leakage, Stackability, CVE History, Patch Cadence, Fuzzing)

More in Choosing a Sandbox for AI Agents