Skip to main content
OpenAIbeginner

codex config.toml: Location, Keys & Precedence

Where Codex CLI stores config.toml on macOS, Linux and Windows, an annotated example file, the six-level precedence order, and how to check which config is actually in effect.

10 min readUpdated August 2026

Want us to handle this for you?

Get expert help →

The Codex CLI reads its settings from config.toml. This page gives you the exact path on each platform, an annotated example of the file, the order in which Codex resolves competing files, and how to confirm which one is actually in effect.

Where config.toml Lives

ScopePathNotes
User~/.codex/config.tomlThe one most people mean. Same path on macOS, Linux and Windows.
System/etc/codex/config.tomlUnix only. For machine-wide defaults set by an administrator.
Project<project>/.codex/config.tomlLoaded only when the project is trusted.
Profile~/.codex/<profile-name>.config.tomlSelected with --profile <profile-name>.

On Windows, ~/.codex/config.toml resolves to %USERPROFILE%\.codex\config.toml - typically C:\Users\YourName\.codex\config.toml.

The file does not exist until you create it. Codex runs happily on built-in defaults, so a missing config.toml is not an error and there is nothing to regenerate:

mkdir -p ~/.codex
$EDITOR ~/.codex/config.toml

To move the whole configuration directory, set CODEX_HOME. It overrides the home directory Codex uses for config resolution:

export CODEX_HOME="$HOME/dotfiles/codex"
# user config is now $HOME/dotfiles/codex/config.toml

An Annotated config.toml

Everything below uses verified key names. TOML is order-sensitive only in that a bare key must appear before the first [table] header - put your top-level settings at the top.

# ---- Model ----------------------------------------------------------------
model = "gpt-5.6"
model_reasoning_effort = "high"        # "low" | "medium" | "high"

# ---- Permissions ----------------------------------------------------------
# What Codex may touch, and when it stops to ask.
sandbox_mode    = "workspace-write"    # "read-only" | "workspace-write" | "danger-full-access"
approval_policy = "on-request"         # "untrusted" | "on-request" | "never"

# ---- Behaviour ------------------------------------------------------------
web_search  = "cached"                 # "cached" | "indexed" | "live" | "disabled"
personality = "pragmatic"              # "friendly" | "pragmatic" | "none"
log_dir     = "/Users/you/.codex/logs" # absolute path

# ---- Sandbox detail -------------------------------------------------------
# Applies when sandbox_mode = "workspace-write".
[sandbox_workspace_write]
writable_roots = ["/Users/you/.pyenv/shims"]  # extra dirs Codex may write to
network_access = false                        # default is false

# ---- Model providers ------------------------------------------------------
# Only needed for a proxy or a self-hosted endpoint.
model_provider = "proxy"

[model_providers.proxy]
base_url = "http://proxy.example.com"
env_key  = "OPENAI_API_KEY"

# ---- MCP servers ----------------------------------------------------------
[mcp_servers.example_server]
command = "/path/to/server"
args    = ["--flag", "value"]

# ---- Feature flags --------------------------------------------------------
[features]
hooks       = true
memories    = false
multi_agent = false

A few other tables exist and are worth knowing by name rather than by heart:

  • [permissions.<name>] - custom permission profiles. Three are built in: :read-only, :workspace, :danger-full-access.
  • [shell_environment_policy] - controls which environment variables reach spawned commands, including ignore_default_excludes and a [shell_environment_policy.filters] sub-table.
  • [windows] - Windows sandbox behaviour, with sandbox = "elevated" or "unelevated".
  • [tui.keymap.global], [tui.keymap.composer], [tui.keymap.chat] - key bindings mapped to action names.
  • [projects] - per-project entries recording trust.
  • project_doc_fallback_filenames - alternative filenames to look for when a project has no AGENTS.md.

The two permission keys are the ones people change most often, and they are covered in depth in Codex CLI auto mode and sandbox settings.

Precedence: Which File Wins

Codex resolves each value independently, highest precedence first:

  1. CLI flags and --config overrides
  2. Project config files - .codex/config.toml, ordered from repository root down to your working directory, closest wins, trusted projects only
  3. Profile files - ~/.codex/<profile-name>.config.toml
  4. User config - ~/.codex/config.toml
  5. System config - /etc/codex/config.toml on Unix
  6. Built-in defaults

This is per-key, not per-file. A project config that sets only model does not discard your user config's sandbox_mode; it replaces the one value and leaves the rest intact.

Two consequences catch people out:

Project config is ignored until the project is trusted. If your repository's .codex/config.toml appears to do nothing, this is almost always why. Codex skips the entire project layer for untrusted projects, which is deliberate - a cloned repository should not be able to hand itself broader permissions just by shipping a config file.

A CLI flag beats everything. Anything set with -c or a dedicated flag overrides all four file layers, so a wrapper script or shell alias carrying -c is a common reason a file edit seems to have no effect.

Overriding Settings Without Editing the File

Use -c (or --config) with a key=value pair. It is repeatable:

codex -c model_reasoning_effort=high
codex --config log_dir=./.codex-log
codex -c sandbox_mode='"read-only"' -c approval_policy='"untrusted"'

Values follow TOML quoting rules, which is why the string examples carry inner quotes: TOML strings are quoted, and the shell strips the outer layer.

Select a profile with --profile:

codex --profile strict
# reads ~/.codex/strict.config.toml

Point Codex at a different working directory with --cd / -C, which changes which project config layer applies:

codex --cd ~/work/api-service

How to Tell Which Config Is Actually Being Read

There is no single command that prints the merged result, so work through the layers in order.

1. Confirm the home directory. Everything else depends on it:

echo "${CODEX_HOME:-$HOME/.codex}"

2. List every candidate file, highest precedence first:

# project layer (from repo root down to cwd)
find . -maxdepth 3 -path '*/.codex/config.toml' -print

# profile, user, system
ls -l ~/.codex/*.config.toml 2>/dev/null
ls -l "${CODEX_HOME:-$HOME/.codex}/config.toml"
ls -l /etc/codex/config.toml 2>/dev/null

3. Validate the syntax. Run with --strict-config, which surfaces parse errors and unrecognised keys instead of silently ignoring them. This is the fastest way to catch a misspelled key - by default a key Codex does not recognise simply does nothing, which looks identical to a setting that is being overridden:

codex --strict-config

4. Check the effective permissions with the /permissions command inside a session. It shows what Codex is currently allowed to do, which is the merged result of every layer for the two keys most worth confirming.

5. Test the precedence directly. Override the value on the command line and see whether behaviour changes. If -c changes it but the file does not, a higher layer - usually a project config or a flag in a wrapper script - is winning.

Other Files in ~/.codex

config.toml is the file you edit; these are the ones Codex manages:

FilePurpose
~/.codex/auth.jsonCredentials, when not held in the system keyring
~/.codex/history.jsonlPrompt history across sessions
~/.codex/sessions/Session transcripts, organised by date
~/.codex/<name>.config.tomlProfile files

Log output goes wherever log_dir points.

AGENTS.md is discovered separately from configuration: Codex walks up from your working directory toward the project root and includes a limited amount of that guidance in the first turn. Use project_doc_fallback_filenames if your project keeps its instructions under a different name, and /init to generate a starting AGENTS.md.

Backup and Version Control

The settings are plain text and belong in your dotfiles. Credentials do not:

cd ~/.codex
git init
printf 'auth.json\nsessions/\nhistory.jsonl\nlogs/\n' > .gitignore
git add config.toml .gitignore
git commit -m "Codex CLI configuration"

For a full backup including session transcripts:

tar -czvf codex-backup-$(date +%Y%m%d).tar.gz ~/.codex/

On a new machine, restore the archive and sign in again - credentials in the system keyring do not travel with the directory.

Keep API keys in environment variables (OPENAI_API_KEY) or the keyring rather than in config.toml, so that a committed or shared config file never carries a secret.

Next Steps

Configuration in other AI coding CLIs

Comparing how each tool stores its settings? See where Claude Code, Gemini CLI, and GitHub Copilot CLI keep their config files.

Shipping code with AI?

Get alerted when it breaks

AI assistants ship code you didn't write line-by-line. GlitchReplay gives you error tracking plus session replay — so when AI-generated code breaks in production, you see the exact stack trace and the user's screen. Sentry-SDK compatible, flat-rate pricing.

Try GlitchReplay free

Frequently Asked Questions

Find answers to common questions

The user-level file is ~/.codex/config.toml on macOS, Linux and Windows. On Windows that path resolves to %USERPROFILE%.codex\config.toml. There is also an optional system-level /etc/codex/config.toml on Unix, and a project-level .codex/config.toml inside a repository.

No. Codex runs on built-in defaults and only reads the file if it is there. Create ~/.codex/config.toml yourself the first time you want to change a setting - there is nothing to reset or regenerate.

Highest to lowest: CLI flags and --config overrides, project config files, profile files, the user config at ~/.codex/config.toml, the system config, then built-in defaults. Closest project config to your working directory wins among project files.

Codex loads project-scoped config only when the project is trusted. If the project has not been trusted, the entire .codex/ layer is skipped - which is a deliberate safeguard against a cloned repository shipping its own permissive settings.

Set the CODEX_HOME environment variable. It overrides the home directory Codex uses to resolve configuration, so CODEX_HOME=/opt/codex makes the user config /opt/codex/config.toml.

Use -c or --config with a key=value pair, for example 'codex -c model_reasoning_effort=high'. The flag is repeatable and follows TOML quoting rules, so string values need quotes inside the shell argument.

A profile is a separate file at ~/.codex/profile-name.config.toml selected with --profile profile-name. It sits above your user config but below project config in precedence, which makes it a clean way to keep a stricter or looser set of settings for particular kinds of work.

Set sandbox_mode to read-only, workspace-write or danger-full-access, and approval_policy to untrusted, on-request or never. The combination of workspace-write and on-request is what the CLI presents as Auto mode.

Run Codex with --strict-config. It surfaces parse errors and unrecognised keys instead of silently ignoring them, which is the fastest way to find a misspelled key name.

The settings themselves are fine to commit, and a project-level .codex/config.toml is designed for exactly that. Never commit ~/.codex/auth.json or anything containing an API key - keep credentials in environment variables or the system keyring.