GPTMap

Codex CLI Sandbox Modes: sandbox_mode and approval_policy Explained

Codex CLI sandbox has four levels — read-only, workspace-write, external-sandbox, danger-full-access — plus a separate approval_policy axis. Every value checked against the codex source enums.

TL;DR
Codex CLI sandbox_mode has four values: read-only (optional network_access), workspace-write (writes cwd, writable_roots adds dirs, .git stays read-only), external-sandbox (for containerized runs), danger-full-access (unrestricted). approval_policy is a separate axis: on-request (default), on-failure (alias), granular, never — untrusted is no longer supported.
The Codex CLI sandbox is an OS-level boundary that controls where the coding agent may write files and whether it may reach the network, set by the sandbox_mode key in config.toml — independent of approval_policy, which controls when the agent stops to ask you.

How to

  1. Open the config file

    Edit ~/.codex/config.toml (project-level overrides live in .codex/config.toml at the repo root).

  2. Pick a sandbox_mode

    Set sandbox_mode = "workspace-write"; use "read-only" for review-only runs, "external-sandbox" inside containers, and reserve danger-full-access for fully trusted setups.

  3. Set approval_policy

    Add approval_policy = "never" for unattended runs; keep the on-request default for interactive use, or granular for per-category control.

  4. Tune workspace-write options

    Configure writable_roots, network_access = true and the tmp exclusions to widen or tighten what the workspace-write level permits.

The Codex CLI sandbox is an OS-level boundary: it decides where the coding agent may write files and whether it can reach the network — and it is independent of approval_policy, which controls when the agent pauses for your approval. Many users treat the sandbox as a single on/off switch and end up either too loose or too restrictive. This guide walks through every value as defined in the official codex-rs source, not from memory.

1. The four sandbox_mode values

The sandbox_mode key in config.toml maps to the SandboxPolicy enum in the source, which defines four serde values:

ValueDisk writesNetworkBest for
read-onlyEverything read-onlynetwork_access optional (off by default)Pure review — let Codex read code without touching it
workspace-writeCurrent workspace writablenetwork_access off by defaultDay-to-day coding
external-sandboxFull disknetwork_access controls egressProcess already inside a container/CI sandbox
danger-full-accessUnrestrictedOpenFully trusted environments only
# ~/.codex/config.toml
sandbox_mode = "workspace-write"

read-only is not "can do nothing" — Codex still reads code and runs read-only commands; it just cannot persist changes. Add network_access = true and you get a read-only reviewer that can look things up online. external-sandbox has special semantics: it declares that the disk boundary is guaranteed by an outer environment (a container), so disk access is open and only the network switch remains declarative.

2. workspace-write sub-options

The most-used level exposes four fields in the source:

  • writable_roots — extra writable directories beyond cwd and TMPDIR
  • network_access — defaults to false; set true to allow egress
  • exclude_tmpdir_env_var — true removes the per-user TMPDIR from default writable roots
  • exclude_slash_tmp — true removes /tmp from default writable roots on UNIX

One detail worth knowing: writable roots (WritableRoot) carry a read-only subpath list — .codex, .git and .git/hooks stay read-only even inside a writable root. The source comment states the motivation directly: files in those directories could be used to escalate the agent's privileges (for example, by writing commands into git hooks), so they are never writable under workspace-write.

3. approval_policy is a separate axis

The sandbox governs what the agent can touch; the approval policy governs whether it asks first. Current approval_policy values:

  • on-request — default; the model decides when to ask
  • on-failure — a serde alias of on-request; equivalent in config
  • granular — per-category control: allow one command class, auto-reject another instead of prompting
  • never — never ask; failures are returned to the model to handle

A common legacy trap: the old untrusted value is no longer supported — the source returns an explicit "no longer supported; remove this setting" error for it. Delete that line when upgrading.

4. Suggested combinations and common mistakes

Typical combinations:

# Interactive daily coding (default shape)
sandbox_mode = "workspace-write"
approval_policy = "on-request"

# CI / unattended
sandbox_mode = "workspace-write"
approval_policy = "never"

# Inside a container (disk boundary owned by the outer env)
sandbox_mode = "external-sandbox"

Two frequent mistakes: treating approval_policy = "never" as "safer" — it is the opposite, it removes every checkpoint, so pair it with a tighter sandbox; and reaching for danger-full-access in CI for convenience — the correct CI shape is workspace-write (or external-sandbox) plus never, with a dedicated git worktree collecting the diff.

On Windows there is a separate windows_sandbox_mode option that controls the Windows sandbox shape alongside sandbox_mode.

5. Next steps

Key points

  • sandbox_mode values: read-only, workspace-write, danger-full-access, external-sandbox
  • workspace-write opens cwd and TMPDIR by default; writable_roots adds dirs; network_access defaults off
  • Subpaths like .codex, .git, .git/hooks stay read-only inside writable roots — an anti-privilege-escalation design
  • approval_policy: on-request (default), on-failure (serde alias), granular, never; untrusted now errors
  • Windows has a separate windows_sandbox_mode option

Frequently asked questions

The SandboxPolicy enum in the source defines four serde values: read-only (network off by default), workspace-write (writable workspace), external-sandbox (declares the process already runs inside an external sandbox), and danger-full-access (unrestricted). The first three cover normal use; external-sandbox targets containerized runs.

Official references

Related articles

Subscribe to GPTMap Weekly

One email every Monday: curated OpenAI updates, deep dives, and best practices. No ads, unsubscribe anytime.

Submitting opens Buttondown in a new tab to confirm your subscription.

GPTMap EditorialPublished 2026-09-23 4 min read
Test environment (EEAT)
Last tested: 2026-09-23
Model used: gpt-6-astra