Agent architecture

Coding agent sandboxing and approvals: what actually contains an agent

Most agents that claim to be sandboxed are running a string blocklist. Here is what real containment looks like, and why a strong sandbox with a weak approval gate still ships the wrong change.

By Kendr Research9 min readUpdated August 14, 2026
Diagram representing sandbox boundaries and approval gates around an AI coding agent
Quick answer

Containment and approval are separate layers and conflating them is the most common security mistake in this category. Containment is enforced by the operating system or a container runtime: Landlock and seccomp on Linux, Seatbelt on macOS, native Windows sandboxes, bubblewrap, or a container with a pinned image digest and networking disabled. Approval decides which proposed actions run at all, and a serious gate is granular, durable across a crash, resolved as a single atomic transition, and applied identically to subagents. A string blocklist over shell commands is neither.

Three very different things called sandboxing

When a coding agent says it is sandboxed, it means one of three things, and the gap between them is enormous. The weakest is a command filter: the harness inspects the shell string the model proposed and refuses to run it if it matches a pattern. This stops the demo case and essentially nothing else, because shell has unlimited ways to express the same effect and the filter has to be right every time while an attacker has to be right once.

The middle option is path and workspace scoping: the harness only exposes typed tools that operate below a configured root, and refuses to read or write outside it. This is genuinely useful — it is the difference between an agent that can edit your project and one that can edit your SSH config — but it constrains the agent’s own tools, not the processes those tools launch. The moment the agent runs a test suite, whatever that suite does is outside the scope.

The strong option is kernel or runtime enforcement, where a policy applies to the process tree regardless of what the model or the code inside it intended. Codex is the reference implementation in this category: Seatbelt on macOS, Landlock with seccomp on Linux, a native Windows sandbox, and network access disabled by default.[1] Container-backed designs get the equivalent from the container runtime. Everything else is a convention.

MechanismEnforced byContains launched processesPractical cost
Shell command blocklistThe harness, by string matchNoZero, and near-zero value
Workspace path scopingThe harness, per typed toolNoLow; effective against accidental scope errors
Seatbelt on macOSKernelYesLow startup cost
Landlock plus seccomp on LinuxKernelYesLow startup cost
bubblewrap namespaces on LinuxKernel namespacesYesLow; needs user namespaces available
Windows Job ObjectsKernelProcess-tree lifetime, not access controlLow; a containment primitive, not a sandbox
Container with pinned digestContainer runtimeYesSeconds of startup; image management
Virtual machine per sessionHypervisorYes, strongestHighest startup and memory cost
Git worktree isolationNothing — it is checkout isolationNoCheap; protects your branch, not your machine

The Windows problem nobody advertises

Almost every sandboxing claim in this category is a macOS and Linux claim. Seatbelt, Landlock, seccomp, and bubblewrap have no Windows equivalent that harness authors can reach for as easily, and the result is that the same product can be kernel-sandboxed on a Mac and effectively unsandboxed on a Windows host running the identical agent against the identical repository.

There are three honest responses and the field uses all of them. Codex ships a native Windows sandbox and is the strongest here. Container-backed designs sidestep the operating system entirely by putting the work inside Docker or Podman, which is why a pinned image digest, an explicit network-off flag, and a cleanup guarantee matter more than they sound. And some harnesses simply say so. Kendr Code is the clearest example of the third response: it publishes a three-way execution taxonomy in which the WSL backend is explicitly labelled shell parity rather than containment, and its host kernel sandbox reports per platform rather than as one word — Landlock plus a network namespace on Linux, verified end to end on a 5.15 kernel; a Seatbelt profile on macOS marked implemented but with enforcement unverified; and Windows reported as unenforced, on the stated grounds that Job Objects bound a process tree’s lifetime rather than its access, with users pointed at the container backend instead.[2]

That last row is the one worth copying. A product that ships a sandbox on two platforms and says plainly that the third is not confined gives a user a decision they can act on. The alternative — one badge, three platforms, no mechanism named — leaves the Windows user believing they have protection they do not have.

The pattern to be suspicious of is a single marketing word applied across platforms. If a product page says sandboxed without naming a mechanism per operating system, assume the weakest one applies on yours.

Worktrees are not a security boundary

Git worktree isolation has become nearly universal for parallel agent work, and it is genuinely valuable: each agent gets its own branch and its own checkout, so two agents editing the same repository do not fight, and your working branch stays untouched. Nearly every parallel-agent orchestrator in the field is built on it.[3]

It is not containment. A worktree is a directory. An agent working in one can still read your home directory, still reach the network, still install a package, still run whatever a test script tells it to. Treating worktree isolation as a safety answer is the most common category error in this space, and it is easy to make because the word isolation appears in both contexts.

The correct mental model is layered. Worktrees isolate your source-control state. A sandbox isolates the process. An approval gate isolates the decision. You need all three for unattended work, and only the third one is visible in the product demo.

What a serious approval gate looks like

The approval gate is the least glamorous and most consequential layer in a coding agent, because it is the only one that operates on intent rather than on effect. A well-built gate has five properties, and most harnesses have two or three of them.

First, granularity: individual actions are decided, not whole sessions, and the decision surface shows the exact arguments rather than a summary. Second, durability: the pending approval persists with the exact proposed arguments and an audit fingerprint, so a process kill while you are away from the keyboard does not silently discard it. Third, atomicity: approve and reject resolve as one conditional state transition, so two clients — a desktop app and a command-line client, say — cannot both decide the same action or overwrite a decision already made. Fourth, feedback: a rejection carries free-text reasoning back to the model as a tool result instead of failing the turn, so the agent adapts rather than retrying identically. Fifth, and most often missing, uniform delegation: tool calls proposed by subagents pass through the same gate as the parent turn.[2]

That fifth property deserves emphasis. Subagent fan-out is now standard across Claude Code, Codex, OpenCode, and most independent harnesses.[4] A gate that a delegated child can bypass is not a gate; it is a speed bump on the main path with an unguarded side road. When evaluating any harness that advertises subagents, this is the single question worth asking.

  • Reusable rules are the difference between a gate people use and a gate people disable. Look for approvals that can mint a standing rule scoped to a tool, a command prefix, or a path prefix — and an interface that lists and revokes them.
  • Approval fatigue is a security failure mode. A gate that asks about every file read trains users into blanket approval, which is worse than a coarser gate they actually read.
  • Check the escalation ladder. Most harnesses have three rungs — confirm everything, auto-accept edits, full autonomy — and the interesting question is what full autonomy still refuses to do.
  • Check that the gate and the model layer agree. If the engine gate and the provider gateway apply different rules, a turn can die instead of asking.

The always-on class carries a different risk profile

One category deserves a specific warning. Personal-assistant agents that run as a persistent gateway reachable from messaging channels — the OpenClaw ecosystem is the largest example, with a very large fork tree — combine broad tool access, always-on availability, and network exposure. That combination has produced repeated documented security incidents, and multiple independent security analyses of the framework and its variants were published during 2026.

This is not an argument against self-hosted assistants. It is an argument that the threat model for an always-on gateway is fundamentally different from the threat model for a coding agent you launch in a terminal and close, and that the sandboxing question for that class is about network exposure and credential scope rather than about filesystem policy. Judge them on that basis; do not import a coding-agent scorecard and assume it transfers.

Frequently asked questions

Which coding agent has the best sandbox?

Codex. It enforces containment at the kernel level with Seatbelt on macOS, Landlock plus seccomp on Linux, and a native Windows sandbox, with network access disabled by default so a compromised dependency cannot reach the network during a test run.

Do git worktrees make an agent safe?

No. A worktree isolates source-control state so parallel agents do not collide and your branch stays clean. It does not restrict filesystem access, network access, or what a launched process can do. Worktrees, sandboxes, and approval gates are three separate layers.

Is Windows less safe for coding agents?

Usually yes, in practice. Most sandboxing in this category relies on macOS and Linux kernel features with no direct Windows equivalent, so the same product can be strongly contained on a Mac and effectively uncontained on Windows. Container-backed execution is the most portable answer.

What is the most commonly missing approval feature?

Uniform enforcement across delegation. Subagent fan-out is now standard, and a gate that a delegated child can bypass provides no guarantee at all. Durable pending approvals that survive a process kill are the second most commonly missing property.

Sources and evidence

Primary and authoritative sources used for factual claims. Company research and executive forecasts are labeled as such in the article.

  1. 1
  2. 2
  3. 3
  4. 4