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.
- The sandbox is enforced outside the model. The approval policy is a conversation.
workspace-writepluson-requestis 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-failureis 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.
| Mode | Can read | Can write | Network |
|---|---|---|---|
read-only | Everywhere in scope | Nothing | No |
workspace-write | Everywhere in scope | The workspace roots | No, by default |
danger-full-access | Everything | Everything | Yes |
approval_policy: when it stops to ask. Verified against codex --help, August 2026.
| Policy | Asks |
|---|---|
untrusted | Before anything outside a known-safe command set such as ls, cat, sed |
on-request | When the model itself decides it needs to escalate |
never | Never. 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.
| Platform | Mechanism | Notes |
|---|---|---|
| macOS | Seatbelt | The same facility macOS uses to confine its own apps |
| Linux | bubblewrap (bwrap) | Install it from your package manager; a bundled helper is the fallback |
| WSL2 | bubblewrap | Same as Linux, which is why WSL2 is the strong route on Windows |
| Windows, native | Windows sandbox | Set up from PowerShell; /setup-default-sandbox configures the elevated one |
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.
npm install
-> ECONNREFUSED / getaddrinfo EAI_AGAIN
pip install requests
-> Could not find a version that satisfies the requirement
[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
# 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.
| Work | Sandbox | Approvals | Why |
|---|---|---|---|
| Understanding an unfamiliar repo | read-only | never | It cannot break anything, so prompts are pure noise |
| Normal development | workspace-write | on-request | The default, and correct |
| A long run you will review after | workspace-write | never | Commit first; the worktree is the boundary |
| A repository you do not trust | read-only | untrusted | Belt and braces |
| Inside a container | danger-full-access | never | The container is the sandbox |
# 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
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.
| Profile | Does |
|---|---|
:read-only | Keeps local command execution read-only |
:workspace | Allows writes inside the active workspace roots and system temp directories |
:danger-full-access | Removes local sandbox restrictions entirely |
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"
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.