Codex sandbox and approval modes explained properly

Codex separates what an agent is capable of from when it asks permission. Most people configure one and assume it did the other, which is why the sandbox surprises them in both directions.

By the Continuum team. We build a workbench that runs Claude Code, Codex, and their peers, so the model rates quoted here are the ones our own cost analytics ship with.

The short version

sandbox_mode is a hard capability boundary enforced by the operating system: read-only, workspace-write, or danger-full-access. approval_policy decides when Codex pauses to ask: untrusted, on-request, or never. They are independent settings, and the useful configurations pair a tight sandbox with light prompting. A newer permission-profile system, set with default_permissions and [permissions.<name>], replaces both and adds per-domain network rules.

What you need to know
  • The sandbox is enforced outside the model. The approval policy is a conversation.
  • workspace-write plus on-request is the right default, and it is the shipped one.
  • Network is off by default in workspace-write. This surprises everyone exactly once.
  • Approval policies are untrusted, on-request, never. on-failure is gone as of 2026.
  • Enforcement is Seatbelt on macOS, bubblewrap on Linux and WSL2, a native sandbox on Windows.
  • codex sandbox <command> runs anything you like inside the same jail.
  • Newer builds prefer permission profiles. Do not mix them with sandbox_mode.

The two dimensions

Everything confusing about Codex permissions comes from treating one setting as if it were two. It is genuinely two, and they are independent.

sandbox_mode: what Codex can do at all.

ModeCan readCan writeNetwork
read-onlyEverywhere in scopeNothingNo
workspace-writeEverywhere in scopeThe workspace rootsNo, by default
danger-full-accessEverythingEverythingYes

approval_policy: when it stops to ask. Verified against codex --help, August 2026.

PolicyAsks
untrustedBefore anything outside a known-safe command set such as ls, cat, sed
on-requestWhen the model itself decides it needs to escalate
neverNever. Failures are returned to the model instead, and the sandbox is the only boundary

What actually enforces it, per platform

The mechanism differs, and so does the strength of the guarantee.

PlatformMechanismNotes
macOSSeatbeltThe same facility macOS uses to confine its own apps
Linuxbubblewrap (bwrap)Install it from your package manager; a bundled helper is the fallback
WSL2bubblewrapSame as Linux, which is why WSL2 is the strong route on Windows
Windows, nativeWindows sandboxSet up from PowerShell; /setup-default-sandbox configures the elevated one
On Debian and Ubuntu.
sudo apt-get install -y bubblewrap
bwrap --version

The network default that catches everyone

In workspace-write, outbound network access is disabled. This is a deliberate and good default, and it is also the single most confusing thing about Codex for a new user, because the failure looks like a broken tool rather than a policy.

What you see.
npm install
  -> ECONNREFUSED / getaddrinfo EAI_AGAIN

pip install requests
  -> Could not find a version that satisfies the requirement
~/.codex/config.toml. Turn it on when you actually need it.
[sandbox_workspace_write]
network_access = true

# extra directories the agent may write to, beyond the workspace
writable_roots = ["/Users/you/.pyenv/shims"]

# the temp-directory escape hatches, both default to allowing tmp
exclude_tmpdir_env_var = false
exclude_slash_tmp      = false
Better: grant it for the one command that needs it, outside the agent.
# install dependencies yourself, then let the agent work offline
npm ci
codex -s workspace-write -a on-request

The combinations worth using

Three sandbox modes times three approval policies is nine combinations. Four of them earn their keep.

WorkSandboxApprovalsWhy
Understanding an unfamiliar reporead-onlyneverIt cannot break anything, so prompts are pure noise
Normal developmentworkspace-writeon-requestThe default, and correct
A long run you will review afterworkspace-writeneverCommit first; the worktree is the boundary
A repository you do not trustread-onlyuntrustedBelt and braces
Inside a containerdanger-full-accessneverThe container is the sandbox
Setting the pair per run.
# explore safely, no interruptions
codex -s read-only -a never

# normal work
codex -s workspace-write -a on-request

# long unattended run, after committing
codex -s workspace-write -a never

# inside a container only
codex -s danger-full-access -a never

# one extra writable directory for this run
codex --add-dir ../shared-protos
A three by three grid of sandbox mode against approval policy, with five cells labelled as the pairings worth using and the workspace-write on-request cell marked as the default SANDBOX MODE APPROVAL POLICY untrusted on-request never read-only workspace-write danger-full-access untrusted repo belt and braces explore no writes, no asks the default normal development unattended run commit first container only not your own machine Nine combinations exist. These five are the ones that earn their keep.

Permission profiles, the newer model

Recent Codex builds ship a second, richer system. Instead of one sandbox mode and one workspace-write block, you name a permission profile that combines filesystem rules and network rules, and select it with default_permissions.

The three built-in profiles.

ProfileDoes
:read-onlyKeeps local command execution read-only
:workspaceAllows writes inside the active workspace roots and system temp directories
:danger-full-accessRemoves local sandbox restrictions entirely
~/.codex/config.toml. Extend a built-in rather than starting from nothing.
default_permissions = "dev"

[permissions.dev]
extends = ":workspace"

# filesystem rules: read | write | deny. The most specific rule wins,
# and deny beats write, which beats read.
[permissions.dev.filesystem]
"~/.ssh"        = "deny"
"~/.aws"        = "deny"
"~/code/shared" = "write"

# network rules are per domain, not one on/off switch
[permissions.dev.network]
"registry.npmjs.org" = "allow"
"github.com"         = "allow"

In a running session, /permissions shows what the agent is currently allowed to do and lets you change it without restarting. It is worth typing before any run you intend to leave alone.

Two things the sandbox gives you for free

Run your own commands inside it

The confinement is not agent-only. codex sandbox runs an arbitrary command under the same policy, which makes it a general-purpose way to run something you half trust.

# run a suspicious build script with no network and no writes outside here
codex sandbox -- ./scripts/vendor-setup.sh

Route approvals to a reviewer instead of yourself

Approval requests do not have to interrupt a human. The approvals_reviewer setting can route them to auto_review, a prompted subagent that gathers context and applies a risk framework before approving or denying. /approve lets you override one of its denials.

approval_policy   = "on-request"
approvals_reviewer = "auto_review"
The same argument one level up: three sessions, three worktrees, three branches, so an unattended agent can only affect the one it was given.

Questions people ask

read-only, which cannot write anything; workspace-write, which can write inside the workspace roots; and danger-full-access, which has no restrictions and is intended for containers and disposable VMs.

The sandbox is a hard capability boundary enforced by the operating system. The approval policy decides when Codex pauses to ask you. They are independent, so a tight sandbox with no prompting is a perfectly sensible configuration.

Because workspace-write disables outbound network by default. Set network_access = true under [sandbox_workspace_write], or better, use a permission profile with a per-domain allowlist so only the registries you named are reachable.

No. As of August 2026 codex --help lists three policies: untrusted, on-request, and never. If your config still names on-failure, run with --strict-config to surface it.

With bubblewrap. Install bwrap from your package manager; a bundled helper is the fallback and it needs unprivileged user namespaces enabled. Where they are disabled, run inside a container instead and treat the sandbox setting as advisory.

Only where something else provides the boundary, such as a container or a disposable VM. On your own machine it means the agent can do anything you can, including reading every credential in your home directory.

Yes, if the sandbox is tight. read-only with never is excellent for exploration, and workspace-write with never is reasonable after committing, because git is then the undo.

Codex enforces capability outside the model with Seatbelt and bubblewrap, so a read-only session genuinely cannot write. Claude Code uses allow and deny rules applied by the agent harness, which is more granular about specific commands and easier to talk past.

Sources

Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.

  1. Codex sandbox documentation
  2. Codex permission profiles
  3. OpenAI Codex documentation
  4. openai/codex on GitHub
Try it

Isolation that
is real.

Continuum runs every code session in its own git worktree, so an unattended agent can only affect one branch.

free app · your subscriptions · local-first