Skip to main content

Codex config.toml Explained — Safe Defaults

Calculating read time…

config.toml is the single settings file (~/.codex/config.toml for your user account, or .codex/config.toml inside a repo for project-level overrides) that controls everything about how OpenAI's Codex CLI behaves — which model answers your prompts, whether it edits files without asking, and how far outside your project folder it's allowed to reach. 🗂️

Here's why that matters more than it sounds: Codex is an agent that can run shell commands and rewrite files on your machine. Two settings in this file — approval_policy and sandbox_mode — are the entire difference between "an assistant that explains code" and "a process that can silently delete a production config." Get them backwards, or copy a stale example from an old blog post, and you either get interrupted every three seconds or you get an agent with more autonomy than you meant to grant it. ⚠️

Diagram showing approval_policy (when Codex asks) and sandbox_mode (what Codex can touch) as two independent config.toml settings

🔀 Quick Comparison — the settings people touch first
Setting Values Controls Good default
model e.g. gpt-5.5, gpt-5.4, gpt-5.4-mini Which model answers gpt-5.5 (falls back to gpt-5.4)
approval_policy untrusted / on-request / never / granular When Codex must stop and ask you on-request
sandbox_mode read-only / workspace-write / danger-full-access What Codex can technically do workspace-write
sandbox_workspace_write.network_access true / false Outbound network from spawned commands false, enable per task

1. What config.toml actually is, and where it lives

Codex reads a plain TOML file for its settings. Your personal defaults live at ~/.codex/config.toml (%USERPROFILE%\.codex\config.toml on Windows). Drop a .codex/config.toml inside a repository and Codex applies it as a project-level override — but only for projects you've explicitly trusted, since an untrusted repo could otherwise ship a config that quietly loosens your safety settings the moment you open it. There's also an optional system-wide file at /etc/codex/config.toml on Unix for machine-level defaults.

💡 Why it matters: because project configs are only trusted for projects you've marked trusted, a malicious open-source repo can't automatically hijack your approval or sandbox settings just because you cloned it and ran codex inside the folder.

2. Configuration precedence: which file wins

When the same key is set in more than one place, Codex resolves it in this order, highest priority first:

  1. CLI flags and one-off --config / -c overrides
  2. Project config files (.codex/config.toml) — trusted projects only, closest to your working directory wins
  3. Profile files selected with --profile name (~/.codex/name.config.toml)
  4. User config (~/.codex/config.toml)
  5. System config (/etc/codex/config.toml, if present)
  6. Built-in defaults

In practice: put shared defaults in your user config.toml, and use profile files only for the handful of values that actually change between contexts (like a stricter sandbox for reviewing unfamiliar code).

3. Selecting the right model for a task

The model key sets which model answers by default:

model = "gpt-5.5"

At the time of writing, gpt-5.5 is OpenAI's recommended default for complex coding, computer use, and research-style workflows in Codex, with an automatic fallback to gpt-5.4 if gpt-5.5 isn't yet available on your account. gpt-5.4-mini trades some depth for speed and is a sensible choice for lightweight tasks or subagents; gpt-5.3-codex-spark is a text-only, near-instant research-preview model for ChatGPT Pro users who want tight iteration loops. You can override the model per session with /model or codex -m gpt-5.4-mini "task" without touching the file at all.

Model names and availability change frequently — always check the current model picker or the official model list before committing a name to a shared config.

🎯 Use this when: you want a stable, repo-wide default without re-typing -m on every invocation.

4. approval_policy: when Codex has to ask you first

approval_policy answers one question only: at what point does Codex pause and wait for a human? It does not, by itself, decide what Codex is capable of doing — that's the sandbox's job, covered next.

  • "untrusted" — the most conservative setting. Codex runs only commands it can classify as clearly safe reads automatically; anything that could mutate state (including destructive git operations) requires your approval.
  • "on-request" — Codex acts freely inside the boundary the sandbox already allows, and asks only when it needs to step outside that boundary (editing outside the workspace, or reaching the network).
  • "never" — Codex never stops to ask. This does not mean unlimited power; the sandbox still constrains what commands can actually do. "Never ask" plus "read-only" simply means Codex silently fails or refuses when it tries to write, rather than prompting you.
  • A granular object — approval_policy = { granular = { sandbox_approval = true, rules = true, mcp_elicitations = true, request_permissions = false, skill_approval = false } } — lets you keep some categories of prompts interactive (like sandbox escalations) while auto-resolving others (like skill-script approvals).
✅ Worked example: a solo developer reviewing a pull request sets approval_policy = "on-request" with sandbox_mode = "workspace-write". Codex edits files and runs tests freely inside the repo, and only stops to ask when it wants to reach outside the project directory or hit the network — the "Auto" preset Codex recommends for version-controlled folders.

5. sandbox_mode: what Codex can technically touch

sandbox_mode is enforced at the operating-system level (Seatbelt on macOS, bwrap plus seccomp on Linux, a native Windows sandbox on Windows) — it isn't just a polite convention the model follows, it's a real OS-level restriction on the process Codex spawns.

  • "read-only" — Codex can inspect files and explain code, but the sandbox itself blocks every write. No approval setting can make a read-only sandbox accept a file edit; the write simply can't happen at the OS level.
  • "workspace-write" — Codex can read and edit inside the active workspace (your project directory plus temp locations like /tmp; run /status to see the exact list). Network access is off by default even in this mode, unless you explicitly add [sandbox_workspace_write] network_access = true.
  • "danger-full-access" — no sandbox boundary at all. Reserved for disposable containers or CI runners you already trust completely.

Even inside workspace-write, certain paths stay protected and read-only no matter what: .git, .agents, and .codex directories (and everything recursively under them). That protection exists specifically so an agent editing your code can't quietly rewrite its own history or its own permission files.

💡 Contrasting example — the case that trips people up: approval_policy = "never" with sandbox_mode = "read-only". This is exactly the combination you gave in your notes, and here's precisely what it means: Codex can inspect and explain your code but cannot modify files at all — not because it's being polite and asking permission (it isn't asking anything), but because the OS-level sandbox physically will not allow the write. It's a strict "look, don't touch" mode, useful for a code-review or Q&A session where you never want any file to change, even accidentally.

6. Every practical approval + sandbox combination

Because the two settings are independent axes, it helps to see them laid out together. These are the combinations Codex itself documents and recommends:

Intent Config Effect
Auto (recommended default) approval_policy = "on-request"
sandbox_mode = "workspace-write"
Reads, edits, and runs commands inside the workspace freely; asks before leaving it or touching the network.
Safe read-only browsing approval_policy = "on-request"
sandbox_mode = "read-only"
Codex can read and answer questions; needs approval for any edit, command, or network call.
Read-only, non-interactive (CI) approval_policy = "never"
sandbox_mode = "read-only"
Pure inspection: Codex can only read, and never pauses to ask — ideal for automated code-explanation or audit jobs.
Edit freely, gate risky commands approval_policy = "untrusted"
sandbox_mode = "workspace-write"
Codex reads and edits files without asking, but stops for approval before running commands it can't classify as safe.
Unattended automation approval_policy = "never"
sandbox_mode = "workspace-write"
Runs end-to-end with no prompts, but still can't leave the workspace — a common CI/non-interactive setup.
Dangerous full access --dangerously-bypass-approvals-and-sandbox (alias --yolo) No sandbox, no approvals. Documented as an elevated-risk option — not recommended outside disposable, fully trusted environments.

🎯 Use this when: you're deciding a default for a new machine or a new project — pick the row that matches how much you trust the environment, not just how fast you want Codex to move.

7. Profiles: switching setups without editing config.toml

Rather than hand-editing config.toml every time you switch contexts, Codex supports named profile files at ~/.codex/<name>.config.toml, selected with codex --profile <name>. A typical layout:

# ~/.codex/config.toml (shared defaults)
model = "gpt-5.5"
approval_policy = "on-request"
sandbox_mode = "workspace-write"

# ~/.codex/readonly_quiet.config.toml
approval_policy = "never"
sandbox_mode = "read-only"

# ~/.codex/full_auto.config.toml
approval_policy = "on-request"
sandbox_mode = "workspace-write"

Run codex --profile readonly_quiet "explain this module" for a strict, no-prompt walkthrough, and switch to a different profile the moment you actually need Codex to make changes.

8. Enterprise rollout at scale

Rolling Codex out to a team introduces a governance question a solo setup doesn't have: what stops one engineer from quietly setting sandbox_mode = "danger-full-access" on a shared build server? OpenAI's answer is admin-enforced requirements.toml under managed configuration — organizations can explicitly disallow values like approval_policy = "never" or sandbox_mode = "danger-full-access" at the fleet level, regardless of what an individual user's config.toml says.

Two other pieces matter at scale:

  1. Auto-review. Setting approvals_reviewer = "auto_review" routes eligible approval requests through a reviewer agent that checks for data exfiltration, credential probing, and destructive actions before Codex proceeds — useful when a human reviewer isn't realistically watching every prompt.
  2. Telemetry. Opt-in OpenTelemetry export ([otel], off by default) lets teams log conversation starts, tool approval decisions, and tool results to their own collector for audit purposes, with prompt text redacted by default (log_user_prompt = false).
✅ Rollout pattern that scales: ship a locked-down requirements.toml that bans danger-full-access and approval_policy = "never" fleet-wide, let individual engineers layer their own profile files on top for day-to-day speed, and turn on OTel export (with prompts redacted) so security can audit approval/sandbox changes after the fact.

9. Common mistakes

  • Assuming approval_policy = "never" means "unlimited power." It only removes prompts; the sandbox still decides what's physically possible. Pairing it with read-only is a legitimate, safe pattern — not a contradiction.
  • Copying old [[approval_policy]] table examples from outdated posts. Some community write-ups use a table-style rule syntax that isn't part of the current schema; pasting it into config.toml silently does nothing useful. Check the current official config reference before trusting a copy-pasted block.
  • Forgetting that project config only loads for trusted projects. If a .codex/config.toml "isn't working," the project may not be marked trusted — check before assuming the file is malformed.
  • Turning on network access without scoping it. Enabling sandbox_workspace_write.network_access = true opens outbound access broadly; pair it with the network-proxy domain allowlist if the task only needs one or two hosts.
  • Reaching for --yolo for convenience. It's documented as elevated risk for a reason — no sandbox and no approvals together means a single bad model action, or a prompt-injected instruction from untrusted content, can execute with full system access.

❓ FAQ

Q: Does approval_policy = "never" mean Codex can do anything it wants?
A: No. It only removes the "may I?" prompt. What Codex can physically do is still bounded by sandbox_mode — pair "never" with "read-only" for a fully hands-off, look-but-don't-touch session.
Q: What's the safest starting configuration for a new machine?
A: approval_policy = "on-request" with sandbox_mode = "workspace-write" — Codex's own recommended "Auto" default for version-controlled folders.
Q: Is network access on by default in workspace-write mode?
A: No. Network access defaults to off even in workspace-write; you enable it explicitly with [sandbox_workspace_write] network_access = true.
Q: Can Codex edit its own .git history or config while in workspace-write mode?
A: No. .git, .agents, and .codex directories stay protected as read-only even inside a writable workspace.
Q: Should a whole team rely on individual engineers setting these values correctly?
A: Not for the highest-risk settings. Enterprises should enforce hard limits (like banning danger-full-access) centrally through managed requirements.toml, letting individuals customize everything else.
🔗 References & Further Reading

Codex and OpenAI are trademarks of OpenAI. This post explains and synthesizes publicly available documentation in its own words; it does not reproduce OpenAI's documentation verbatim. Model names, defaults, and available settings change frequently — verify against the live docs before applying any config in production.

📝 Summary

  • config.toml lives at ~/.codex/config.toml, with optional trusted-project overrides in .codex/config.toml.
  • CLI flags beat project config, which beats profiles, which beats user config, which beats system config, which beats built-in defaults.
  • model picks the brain (default recommendation: gpt-5.5, falling back to gpt-5.4).
  • approval_policy controls when Codex asks; it never expands what Codex can technically do.
  • sandbox_mode controls what Codex can technically touch, enforced by the OS itself.
  • Combine them deliberately — the six combinations above cover nearly every real workflow.
  • Profiles let you switch setups with a flag instead of hand-editing the file.
  • At team scale, lock the highest-risk settings centrally via requirements.toml and audit with opt-in telemetry.
  • The most common mistake is treating "never ask" as "no limits" — it isn't.

That's the whole picture: two small keys, one big safety decision. Configure deliberately, and Codex stays a fast collaborator instead of a surprise. 🚀

Comments