A Codex CLI setting that "does not work" is almost always a layer problem, not a syntax problem. The same key can be written in several places, and the effective value is decided by a documented order rather than by whichever file you edited last. The official config documentation defines that order as seven layers, highest precedence first, plus one security gate that quietly disables an entire layer when a project is not trusted. Those three pieces of information are enough to explain most configuration surprises: the order, the trust gate, and the habit of locating the winning layer before changing anything.
The order and quotes below come from the official config basics page, with field-level background in the Codex manual. Verify against the current pages when you build.
The seven layers, in the documented order
Codex lists the resolution order explicitly, highest precedence first. The list is reproduced here in order, without merging any levels:
- CLI flags and
--configoverrides. Values passed on the command line for that invocation. - Project config files.
.codex/config.toml, ordered from the project root down to your current working directory, where the closest file wins, for trusted projects only. - Profile files selected with
--profile profile-name, stored as~/.codex/profile-name.config.toml. - User config at
~/.codex/config.toml. - Cloud-managed
config.tomldefaults, when delivered for the signed-in workspace. - System config, if present:
/etc/codex/config.tomlon Unix. - Built-in defaults.
Two details in that list are easy to skim past. The project layer is not a single file: Codex walks from the repository root toward the directory you are working in, and the closest file wins, which is how a monorepo can give one subdirectory different settings without duplicating everything. And the profile layer sits above the user config, not below it, which means a profile can override a key that your personal config already sets.
A useful mental model is a stack of overrides rather than a set of files: each layer contributes only the keys it actually sets, and the first layer that mentions a key decides that key's value. A layer that stays silent on a key contributes nothing to it.
The trust gate on the project layer
The sentence that explains the most "why is my project config ignored" reports is in the introduction to the same page:
For security, Codex loads project .codex/ layers only when you trust the project.The precedence table repeats the constraint in its parenthetical: trusted projects only. The page spells out the consequence for untrusted projects as well: Codex skips project-scoped .codex/ layers, including project-local config, hooks, and rules, while user and system config still load, including user and global hooks and rules.
This is a security boundary, not a bug. A repository you cloned should not be able to change how your agent behaves just because it contains a directory, so the project layer stays off until you say otherwise. If a setting in .codex/config.toml appears to have no effect, checking the trust state of the project is the first move, ahead of any TOML debugging.
Policy is not a layer you can override
There is a second mechanism that looks like precedence but is not: managed requirements. The documentation states the division plainly:
Requirements constrain behavior; configuration values provide defaults.
Configuration layers decide which default applies; requirements decide what is allowed at all. On managed machines, an organization can enforce constraints such as disallowing a particular approval policy or sandbox mode through requirements.toml. Reaching for a higher-precedence config layer will not beat a requirement, because the requirement is not competing on the same ladder. When a value refuses to change on a managed device, the question to ask is whether a requirement is holding it, not which config file you have not edited yet.
Where a setting belongs
Once the order is clear, the practical question becomes placement. The documentation's own guidance is compact: use the precedence to set shared defaults in config.toml and keep profile files focused on the values that differ.
| Situation | Layer to use |
| --- | --- |
| Team-wide shared defaults | User config, ~/.codex/config.toml |
| Repository-specific behavior | .codex/config.toml in the repo, with the trust requirement kept in mind |
| Environment or role differences | A profile file plus --profile profile-name |
| One-off or scripted invocation | --config overrides on the command line |
| Machine-wide policy-free defaults | /etc/codex/config.toml on Unix |
The semantics of the keys themselves, including provider fields and their defaults, are covered in the custom provider guide. One related boundary is worth keeping straight: where a credential comes from is its own subject, not a config layer, and the storage modes are in the credentials guide.
The CI trade-off
Continuous integration makes the layering visible, because a CI runner is exactly the kind of environment where the project layer cannot be assumed. The trust state of a checkout is not something a pipeline should depend on, and the machine's user config may not be yours at all. Two habits follow. For values that differ per environment, --profile keeps a small set of named configurations; for values that differ per invocation, --config passes them explicitly. In both cases the important values are stated in the pipeline rather than inherited from a layer nobody audited. The broader patterns for running coding agents in pipelines are in the CI guide.
If the setting in question is a certificate bundle or a proxy configuration on a managed network, it belongs to the enterprise environment story rather than to layer shopping; the corporate network guide covers it.
Debugging a value that will not stick
Work the layers from the top, and stop at the first one that supplies the value:
- Trust state. Is the project trusted at all? If not, stop here: the project layer is not in play.
- Command line. Did the invocation carry
--configor a flag that sets this key? - Project layer. For a trusted project, is there a
.codex/config.tomlcloser to the working directory than the one you edited? - Profile. Is a
--profileactive, and does that profile file set the same key? - User config. Is the value in
~/.codex/config.toml, possibly older than you remember? - Cloud-managed defaults. Is a signed-in workspace delivering a managed
config.tomldefault? - System config and built-in defaults. Finally, check
/etc/codex/config.tomlon Unix, then the built-in default the documentation lists.
This order is also the fastest way to test a hypothesis: set the value once with --config for the current invocation. If the behavior changes, the key is right and the question is placement; if it does not, the key or the requirement layer is the problem. Record the layer you changed and the layer that won; that pair is the only durable note of a configuration decision, and it saves the next person the same walk.
CLI and IDE share the same layers
The documentation notes that the CLI and the IDE extension share the same configuration layers. Editing the user config from either surface changes behavior for both, which is convenient until someone edits a project file expecting it to affect only the IDE. The documented paths to open the file are short: in the IDE extension, select the gear icon in the top-right corner, then Codex Settings > Open config.toml. In the ChatGPT desktop app, the same file opens through Settings > Configuration > Open config.toml, per the manual. The same layers, viewed from either tool, resolve in the same order.
The checklist
- Confirm the project's trust state before debugging any project-layer value.
- Reproduce the effective value with a one-off
--configoverride. - Keep shared defaults in the user config, not scattered across project files.
- Put repository-specific values in
.codex/config.toml, and remember the trust gate. - Keep profiles focused on values that differ, selected with
--profile. - State critical values explicitly in CI instead of relying on the project layer.
- When a managed machine refuses a change, check requirements before config layers.
- Walk the seven layers top-down, and write the team's placement convention down once.
Seven layers, one trust gate, and a policy mechanism that sits outside the ladder. Most configuration mysteries collapse into a single question: which layer is allowed to speak here, and which one is speaking. Endpoint-level specifics for the compatible service this site documents live in its documentation, and the four-tool setup that first put these layers in context is in the shared-key guide. As always, verify the order and the quotes against the official pages current at build time.