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
| Scope | Path | Notes |
|---|---|---|
| User | ~/.codex/config.toml | The one most people mean. Same path on macOS, Linux and Windows. |
| System | /etc/codex/config.toml | Unix only. For machine-wide defaults set by an administrator. |
| Project | <project>/.codex/config.toml | Loaded only when the project is trusted. |
| Profile | ~/.codex/<profile-name>.config.toml | Selected 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, includingignore_default_excludesand a[shell_environment_policy.filters]sub-table.[windows]- Windows sandbox behaviour, withsandbox = "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 noAGENTS.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:
- CLI flags and
--configoverrides - Project config files -
.codex/config.toml, ordered from repository root down to your working directory, closest wins, trusted projects only - Profile files -
~/.codex/<profile-name>.config.toml - User config -
~/.codex/config.toml - System config -
/etc/codex/config.tomlon Unix - 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:
| File | Purpose |
|---|---|
~/.codex/auth.json | Credentials, when not held in the system keyring |
~/.codex/history.jsonl | Prompt history across sessions |
~/.codex/sessions/ | Session transcripts, organised by date |
~/.codex/<name>.config.toml | Profile 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
- Set permissions properly in Codex CLI auto mode and sandbox settings
- Add tooling with How to Set Up MCP Servers
- Start from the beginning with How to Install OpenAI Codex CLI
- Read the official Codex configuration documentation
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.