The short version
- Codex reads settings from several layers. From highest to lowest: CLI flags, project files, the selected profile, your user file, cloud-managed defaults, system config, built-in defaults.
- A profile is its own file, ~/.codex/<name>.config.toml, with top-level keys. From Codex 0.134.0 the old [profiles.name] table and the profile = selector are no longer supported.
- A repo can ship .codex/config.toml, but Codex loads it only when the project is trusted, and it ignores provider, notification and telemetry keys set there.
- Use -c or --config for one-off overrides, and keep shared defaults in config.toml so profiles hold only what differs.
On this page
- The short version
- Where does Codex read its configuration from?
- Which setting wins? The precedence order
- The four keys most teams set first
- How do Codex profiles work now?
- How do I set up a project config for a team repo?
- How do I override one setting for a single run?
- A layout that works
- Conclusion
- Questions people ask
Codex reads its settings from more than one place, and the place that wins is not always the one you edited last. The short rule: command-line flags beat project files, project files beat a profile you select, a profile beats your personal ~/.codex/config.toml, and everything else is a default. This guide shows how to set up each layer so a team repo behaves the same for everyone and a one-off run does not need a file edit.
Everything below comes from OpenAI's Codex configuration docs. Where the docs do not say something, this article does not either.
Where does Codex read its configuration from?
These are the layers you can meet:
- User config:
~/.codex/config.toml. Your personal defaults. - Project config: a
.codex/config.tomlinside a repo or subfolder. It scopes settings to that project. - Profile files:
~/.codex/<profile-name>.config.toml, picked with--profile. - System config:
/etc/codex/config.tomlon Unix. - Cloud-managed defaults: a
config.tomldelivered for the signed-in workspace, when one exists.
Managed-device and workspace requirements exist as well. The configuration docs only point to a separate managed-configuration page for them, so check that page if your organization enforces settings.
Which setting wins? The precedence order
From highest to lowest:
- CLI flags and
--configoverrides - Project config files, from the project root down to the current directory (closest wins; trusted projects only)
- The profile file chosen with
--profile - User config (
~/.codex/config.toml) - Cloud-managed
config.tomldefaults, when delivered for the signed-in workspace - System config (
/etc/codex/config.tomlon Unix) - Built-in defaults
Two consequences are easy to miss. First, a project file overrides a profile. If your profile sets model and the repo's .codex/config.toml also sets it, the repo wins. Second, there is one documented exception: for model_catalog_json, when both a profile and the project set it, Codex uses the profile value.
The four keys most teams set first
The docs show these as the basic block:
model = "gpt-6.1-sol"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
model_reasoning_effort = "medium"What they do, and what values the reference page allows:
modelsets the default model. The docs say to pick one available to your signed-in account or workspace, and usegpt-6.1-solonly as an example. Check which models you actually have.approval_policycontrols when Codex pauses to ask before running commands. Allowed values areon-request,never, or agranulartable. The reference saysuntrustedis no longer supported andon-failureis deprecated; useon-requestfor interactive runs orneverfor non-interactive ones. Old configs that use the retired values need updating.sandbox_modeisread-only,workspace-writeordanger-full-access. It sets filesystem and network access while commands run.model_reasoning_effortsets reasoning effort when the model supports it. The docs list low, medium, high, xhigh, max and ultra as examples and say the available levels depend on the model and client. Do not assume every model accepts every level.
How do Codex profiles work now?
A profile is a separate file. --profile deep-review loads ~/.codex/config.toml first, then overlays ~/.codex/deep-review.config.toml on top.
Rules from the docs:
- Names can use letters, numbers, hyphens and underscores.
- Use top-level keys in the profile file. Do not nest them under
[profiles.deep-review]. - Keep shared defaults in
config.tomland use profiles only for values that differ.
An example profile for careful reviews:
# ~/.codex/deep-review.config.toml
model = "gpt-6.1-sol"
model_reasoning_effort = "medium"
approval_policy = "on-request"
model_catalog_json = "/Users/me/.codex/model-catalogs/deep-review.json"Use it with the interactive command:
codex --profile deep-reviewThe profile mechanism is the same for any Codex run, so it gives you a simple way to keep different defaults for different jobs, such as careful review versus quick edits, without separate scripts.
Migrating old profiles (Codex 0.134.0 and later)
This is the change most likely to bite. From 0.134.0, --profile no longer reads [profiles.profile-name] tables from config.toml, and the top-level profile = "profile-name" selector is no longer supported. To migrate:
- Create
~/.codex/profile-name.config.toml. - Move the keys from the old table into it as top-level keys.
- Remove the old table and the selector from
config.toml.
If a profile seems to have no effect after an upgrade, check for the old format first. The docs do not describe what Codex prints in that case, so verify by running with the profile and checking behavior.
How do I set up a project config for a team repo?
Commit a .codex/config.toml at the repo root. Codex walks from the project root down to your working directory and loads each .codex/config.toml it finds. If several files define the same key, the one closest to your working directory wins. That lets a monorepo set a default at the root and a stricter one inside a package.
A conservative starting file:
# .codex/config.toml (committed)
sandbox_mode = "workspace-write"
approval_policy = "on-request"Details that matter:
- Trust gate. Project layers load only when the project is trusted. In an untrusted project Codex skips project-scoped layers, including project-local config, hooks and rules. User and system config still load.
- Relative paths. Relative paths in a project file resolve against the
.codex/folder that contains theconfig.toml, so committed paths work on every machine. - Project root. A directory containing
.gitis the root by default. Change the markers withproject_root_markers. An empty list treats the current working directory as the root.
What a project file cannot set
A repo you cloned should not be able to redirect your traffic or turn on telemetry. So Codex ignores these keys in project files and prints a startup warning: openai_base_url, chatgpt_base_url, apps_mcp_product_sku, model_provider, model_providers, notify, profile, profiles, experimental_realtime_ws_base_url and otel.
Put these in ~/.codex/config.toml instead, and choose profiles with --profile. This is a useful property when you open unfamiliar repos. It is still worth reading the .codex/ folder, including its hooks and rules, before you trust a repo, because the trust decision is what turns those project layers on.
How do I override one setting for a single run?
Use -c or --config. Prefer a dedicated flag such as --model when one exists.
codex --model gpt-6.1-sol
codex --config model='"gpt-6.1-sol"'
codex --config sandbox_workspace_write.network_access=true
codex --config 'shell_environment_policy.include_only=["PATH","HOME"]'Notes from the docs:
- Values are parsed as TOML. If parsing fails, Codex treats the value as a string.
- Nested keys use dot notation, for example
mcp_servers.context7.enabled=false. - Quote anything with spaces or special characters so the shell does not split it.
sandbox_workspace_write.network_accessis a boolean. Setting it totrueallows outbound network access inside the workspace-write sandbox, so it is safer to turn it on per run than in a committed file.include_onlyis a legacy array. It still works, but you cannot combine it with the newer[shell_environment_policy.filters]table in the same layer.
Because CLI overrides sit at the top, they are the right tool for a script that must force a setting no matter what the repo says.
A layout that works
~/.codex/config.toml: your model, effort and personal defaults, plus provider, notification and telemetry settings.~/.codex/deep-review.config.tomland similar: only the keys that differ..codex/config.tomlin the repo: sandbox and approval defaults the whole team shares.--configin scripts: one-off, visible overrides.
Conclusion
Think of Codex configuration as a stack: CLI flags on top, then the repo, then your profile, then your user file. Keep shared defaults in the base file, put only differences in profile files, commit conservative project settings, and use --config for exceptions. If you upgraded recently, migrate any [profiles.*] tables first, since Codex 0.134.0 and later no longer read them.
Questions people ask
Where is the Codex config.toml file?
Your personal file is ~/.codex/config.toml. A repo can add a .codex/config.toml, which Codex loads only if you trust the project. On Unix there is also a system file at /etc/codex/config.toml.
Does a project config override a Codex profile?
Yes. Project config files rank above a profile chosen with --profile, and CLI flags rank above both. The docs list one exception: if both a profile and the project set model_catalog_json, the profile value is used.
Why does my Codex profile stop working after an update?
From Codex 0.134.0, --profile no longer reads [profiles.name] tables from config.toml, and the top-level profile = selector is no longer supported. Move the settings into ~/.codex/name.config.toml as top-level keys and remove the old table.
How do I change one Codex setting for a single run?
Pass --config key=value (or -c). Values are parsed as TOML, nested keys use dots, and a dedicated flag like --model is preferred when it exists.
Can a repo change my Codex model provider or telemetry?
No. Codex ignores keys such as model_provider, model_providers, notify and otel in project files and prints a startup warning. Set them in your own ~/.codex/config.toml.
Sources
Researched and drafted with Claude, then checked against the sources above. Atlas is an independent product, not affiliated with Anthropic or OpenAI. Claude and Claude Code are trademarks of Anthropic; Codex is a product of OpenAI.