cheat sheet

Approvals & Sandboxing

Control what Codex CLI can do — approval policies (untrusted, on-request, never), sandbox modes (read-only, workspace-write, danger-full-access), OS-native sandbox mechanics, and --full-auto.

Approvals & Sandboxing

What it is

Codex CLI has a two-axis safety model: approval policy (when to ask you before executing a command) and sandbox mode (what the OS lets the agent do even if it tries). They compose independently — you can run full-auto with OS-level write isolation, or require explicit approval for every command in an unsandboxed session.


Approval policies

An approval policy is a session-wide rule that tells Codex when to pause and ask a human before running a command. It is enforced before the command is dispatched to the OS, sitting in front of the sandbox layer. The four built-in policies — untrusted, on-request, on-failure, never — trade off speed against safety; on-request is the sweet spot for most interactive work. Set globally in config.toml or per-run with -a / --ask-for-approval.

PolicyWhen Codex asks for approvalTypical use
untrustedEvery mutating command (writes, deletes, network calls)Reviewing unfamiliar code
on-requestOnly when sandbox escalation is neededDefault for interactive sessions
on-failureAfter a command failsDeprecated — avoid
neverNever — agent runs fully autonomouslyDefault for codex exec / CI

Set globally

toml
# ~/.codex/config.toml
approval_policy = "on-request"

Output: (none — config file)

Override per run

bash
codex --ask-for-approval untrusted
codex -a never

Output: (TUI opens with specified approval policy)

Approve or deny at runtime

When Codex requires approval, it pauses and shows the proposed command. Respond with:

  • y / Enter — allow this command
  • n — deny (agent sees a rejection signal and adjusts)
  • a — allow all remaining commands this session
  • e — edit the command before running
  • w — allow this command and all matching commands in this session (e.g., approve pytest once and Codex stops asking for pytest … for the rest of the session)

Example interactive approval prompt:

text
Agent wants to run: rm -rf node_modules/
Approve? [y/n/a/e/w]

Pre-approve commands via config (no prompt, even under on-request):

toml
[[auto_approve]]
matcher = "^(pytest|ruff|mypy)( |$)"

Output: (none — config file)


Sandbox modes

The sandbox is the OS-level enforcement layer — what the agent can do even when no approval is required. It composes independently with the approval policy: you can run read-only + on-request (read-only sandbox plus a prompt before any net-touching command), workspace-write + never (writes inside cwd only, no prompts), or any other pairing. The three modes — read-only, workspace-write, danger-full-access — map directly to OS sandbox primitives on macOS (Seatbelt) and Linux (bubblewrap + seccomp). Set globally in config.toml or per-run with -s / --sandbox.

ModeFilesystemNetworkUse case
read-onlyNo writes anywhereBlockedCode review, read-only analysis
workspace-writeWrites allowed only inside cwdBlocked by defaultNormal development (safe default)
danger-full-accessUnrestrictedUnrestrictedTrusted containers, CI with pre-reviewed code

Set globally

toml
sandbox_mode = "workspace-write"

Output: (none — config file)

Override per run

bash
codex --sandbox read-only "Summarise this codebase"
codex -s danger-full-access

Output: (TUI opens with specified sandbox)


Expanding the workspace-write boundary

workspace-write defaults to cwd; you can add read-only or read-write extension directories to the sandbox:

toml
[sandbox]
mode               = "workspace-write"
extra_read_dirs    = ["/usr/lib", "/opt/homebrew/share"]
extra_write_dirs   = ["/home/alice/scratch"]
allow_network      = false

Output: (none — config file)

Per-run additions via flag:

bash
codex -s workspace-write --add-write-dir /tmp/build "Build the artefact in /tmp/build"

Output: (TUI opens; /tmp/build is part of the writable sandbox)

Allowing network in workspace-write

Most projects don't need it, but npm install, pip install, and docker pull do. Toggle with:

toml
[sandbox]
mode          = "workspace-write"
allow_network = true

Or per-run:

bash
codex -s workspace-write --allow-network "Run npm install and report what failed"

Output: (TUI opens with network egress permitted)


--full-auto shorthand

--full-auto is the most common single flag in real Codex usage: a single token that means "give the agent a safe-default sandbox and only prompt me if it needs to escalate." It is functionally equivalent to --sandbox workspace-write --ask-for-approval on-request, but it is also documented as the recommended starting point for autonomous tasks. Combines workspace-write sandbox with on-request approval policy. The most common "hands-free" setup:

bash
codex --full-auto
codex --full-auto "Add unit tests for all public functions"

Output: (TUI opens; agent runs autonomously, prompts only for sandbox escalation)

In config.toml you can achieve the same default:

toml
approval_policy = "on-request"
sandbox_mode    = "workspace-write"

Output: (none — config file)


Platform sandbox mechanics

The sandbox is enforced by the host OS, not by Codex itself. Codex's job is to describe the policy ("writes restricted to cwd, no network") and ask the kernel to enforce it. The mechanism differs per platform but the rules are the same. Read this section if you need to debug a sandbox denial or understand exactly what the agent can and cannot do.

macOS — Apple Seatbelt

Codex uses sandbox-exec with a Seatbelt policy. The policy:

  • Allows reads everywhere
  • Restricts writes to the working directory subtree
  • Blocks outgoing network by default (workspace-write)
  • Escalates to full access under danger-full-access

Sandbox violation log (visible when --debug is passed):

bash
codex --debug "Write to /etc/hosts"

Output:

text
[sandbox] denied: write /etc/hosts — outside workspace

Print the active Seatbelt policy:

bash
codex sandbox print-policy

Output:

text
(version 1)
(deny default)
(allow file-read*)
(allow file-write* (subpath "/home/alice/myproject"))
(deny network*)

Linux — bwrap + seccomp

Codex uses bubblewrap to create a user namespace with:

  • Bind-mount of the working directory (read-write)
  • Read-only bind-mounts for system paths
  • seccomp filter to block dangerous syscalls

Requires bwrap to be installed (usually available in distribution packages as bubblewrap).

Verify bwrap is available:

bash
bwrap --version

Output:

text
0.8.0

Inspect the generated bwrap arguments (debug-only):

bash
CODEX_LOG_LEVEL=debug codex --sandbox workspace-write "echo hi" 2>&1 | rg bwrap

Output:

text
[debug] bwrap --unshare-all --share-net=false --bind /home/alice/work /home/alice/work --ro-bind /usr /usr --proc /proc --dev /dev --seccomp 3 …

Windows

Two modes depending on privilege:

  • Elevated — runs with current token; sandbox is permission-prompt-only
  • Unelevated — restricted process token limits write scope

WSL2 environments inherit Linux (bwrap+seccomp) semantics when running inside WSL.


Docker / disposable containers

When danger-full-access is the only practical option (e.g., system-level testing), the recommended pattern is to run Codex itself inside a disposable container so that the worst-case blast radius is the container, not the host.

bash
docker run --rm -it \
  -v "$PWD":/workspace -w /workspace \
  -e OPENAI_API_KEY \
  ghcr.io/openai/codex:latest \
  codex --sandbox danger-full-access --ask-for-approval never "Run the full build pipeline"

Output:

text
[agent runs unsandboxed inside the container; host filesystem is unaffected]

Per-command escalation

With approval_policy = "on-request", Codex automatically detects when an action would require sandbox escalation (e.g., writing outside cwd) and pauses to ask:

css
Agent wants to write to /etc/profile.d/codex.sh
This requires elevated sandbox permissions.
Allow? [y/n/a/e]

When the user denies an escalation, Codex receives a structured rejection in the agent loop and typically replans the next step. The agent does not see why the user denied — only that the operation was refused.


Practical examples

Read-only code review

bash
codex --sandbox read-only --ask-for-approval never \
  "Find all potential SQL injection vectors in this codebase"

Output: (agent analyses and reports; no writes permitted)

Safe refactor with auto-approvals

bash
codex --full-auto "Rename all snake_case variables to camelCase in src/"

Output: (agent edits files in cwd; prompts only if it tries to go outside)

Strict interactive review

bash
codex -s workspace-write -a untrusted "Update dependencies"

Output: (TUI opens; Codex asks before every write/delete)

CI pipeline (no approvals, confined)

bash
codex exec --sandbox workspace-write --ask-for-approval never \
  "Run the test suite and fix any type errors"

Output:

text
[agent output; edits committed within workspace]

Summary matrix

ConfigSandboxApprovalRecommended for
Default interactiveworkspace-writeon-requestDay-to-day coding
--full-autoworkspace-writeon-requestLonger autonomous tasks
--sandbox read-only -a neverread-onlyneverAnalysis, summaries, reviews
-s danger-full-access -a neverunrestrictedneverTrusted CI containers only
-s workspace-write -a untrustedworkspace-writealwaysLearning / reviewing unfamiliar repos

Sandbox violation log

When a sandboxed agent attempts a denied operation, Codex prints a clear violation line and the agent receives a structured error in its tool result. Enable verbose logging to see every denial.

bash
CODEX_LOG_LEVEL=debug codex --sandbox workspace-write "Write to /etc/hosts"

Output:

text
[sandbox] denied: write /etc/hosts (outside workspace, mode=workspace-write)
[agent] Tool call failed: PermissionDenied. Trying a different approach.

Persist sandbox violations to a log file:

toml
[sandbox]
log_violations_to = "~/.codex/logs/sandbox.log"
bash
tail -F ~/.codex/logs/sandbox.log

Output:

text
2026-05-25T14:02:01Z denied write=/etc/hosts mode=workspace-write turn=t_01abc
2026-05-25T14:03:11Z denied connect=8.8.8.8:443 mode=workspace-write turn=t_01abc

Common pitfalls

  1. workspace-write blocks network — and most builds need it. npm install, pip install, cargo build, go mod download all need outbound HTTPS. Either set allow_network = true in [sandbox], run those steps yourself before invoking Codex, or use danger-full-access inside a container.

  2. The sandbox only sees the current process's syscalls. Spawning a long-running daemon (e.g., python -m http.server &) puts the daemon outside Codex's sandbox once Codex's session exits. Use bg + disown carefully.

  3. --full-auto is workspace-write + on-request, not "never ask." Many people assume --full-auto means "never prompt me." It doesn't — it still asks for sandbox escalation. Use -a never if you want truly silent automation.

  4. macOS Seatbelt can deny mkdir inside cwd due to ACLs. Some directories (e.g., iCloud-synced folders) carry inherited Apple ACLs that the sandbox sees as out-of-policy. Move the project out of iCloud-Sync or set extra_write_dirs.

  5. WSL2 inherits Linux sandbox semantics, not Windows. If you're running Codex inside a WSL2 distro, you need bubblewrap installed inside WSL — the Windows-side mechanism does not apply.

  6. danger-full-access does NOT disable approvals. It only widens the sandbox. The approval policy still governs whether commands run. If you want no prompts AND no sandbox, use -s danger-full-access -a never (and only inside a disposable container).

  7. on-failure is deprecated. It existed early on as a "let the agent try, ask only if it fails" mode but produced confusing UX. Use on-request instead — it has the same low-friction feel without the surprise.

  8. A pre-approved matcher applies to the entire command, not arguments. ^pytest matches pytest -x src/test_foo.py AND pytest && rm -rf /. Anchor your matchers carefully — favour ^pytest( |$) over ^pytest.


Real-world recipes

Quick read-only review of a fork

Clone someone else's PR locally and review it without giving Codex permission to write anything.

bash
gh pr checkout 123
codex --sandbox read-only --ask-for-approval never \
  "Review this PR for correctness and security. List concerns as bullets."

Output:

text
- src/auth.py:42 — token compared with `==` instead of `secrets.compare_digest`
- src/db.py:17 — SQL query interpolated; vulnerable to injection
- tests/test_auth.py:88 — test depends on global state

Autonomous fix loop with safety net

Run the agent in full-auto but auto-revert if any test fails afterwards.

bash
git stash || true
codex exec --full-auto "Fix all ruff and mypy errors in src/" && \
  (pytest -x || git checkout -- .)

Output:

text
[agent fixes 12 ruff issues + 3 mypy errors]
142 tests passed.

Inspect what was denied during a session

After a session, look at the sandbox log for denied operations — useful for tightening or widening the sandbox.

bash
grep "$(date +%F)" ~/.codex/logs/sandbox.log | sort -u

Output:

text
2026-05-25T14:02:01Z denied write=/etc/hosts mode=workspace-write turn=t_01abc
2026-05-25T14:11:55Z denied connect=registry.npmjs.org:443 mode=workspace-write

CI sandbox preflight check

Verify bwrap is installed in the CI image before invoking Codex, so failures are loud and early.

bash
which bwrap || { echo "bubblewrap missing; install with: apt-get install bubblewrap" >&2; exit 1; }
codex exec --full-auto -p ci "Run the test suite and fix any failures."

Output:

text
/usr/bin/bwrap
[agent output]

Per-tool approval matcher for git operations

Auto-approve safe git inspection commands but prompt for mutating ones.

toml
[[auto_approve]]
matcher = "^git (status|log|diff|show|blame|branch( --list)?$)"

[[deny_approve]]
matcher = "^git (push|reset --hard|clean -f)"

Output: (none — config file)