Skip to content

Comprehensive Guide to config.toml Configurations: Controlling All Knobs with One File

📚 Series Navigation: The previous article [17 Computer Use and Browser (Computer Use)] gave Codex hands—enabling it to look at the screen, click the desktop, and open the browser. This article shifts from graphical interfaces back to a simple text file—config.toml. You have seen it scatteredly several times in the first dozen articles (configuring sandboxes, enabling Memory, selecting models). This article explains it systematically: where this file goes, what it looks like, which key controls what, and who overrides whom when multiple files stack up.

They say configuration files are "things you worry about after installation" and "don't touch if they run"—to be honest, this saying is exactly the opposite for Codex.

Here is my own experience: when I first got started in March 2026, I hadn't touched config.toml at all. Every time I started Codex, I manually switched models with /model, adjusted permissions with /permissions, and temporarily typed --search to enable network access. I ended up repeating these actions seven or eight times a day. Until one day I counted—I manually typed the combination of "switch to powerful model + release workspace write permission" no fewer than thirty times that week. Only at that moment did it click: I had turned a 'write once, take effect permanently' task into 'starting over every time'.

The value of config.toml lies precisely here—it is not for advanced users to show off; it is to save trouble for everyone who hates trouble. The less you want to configure it every time, the more you should spend ten minutes writing it down clearly.

More importantly, it hides a pitfall that beginners are most likely to fall into: the exact same configuration block, written in your home directory versus inside a project, might have completely different effects—or the project one might not even take effect. This article breaks down the rules of "where files go and who overrides whom" so you can write configurations with confidence.

By reading this article, you will get:

  • An explanation of what config.toml is and how it divides labor with AGENTS.md (don't mix them up anymore)
  • Where the user-level ~/.codex/config.toml and project-level .codex/config.toml reside, what they govern, and what should be written in them
  • A priority table of "who overrides whom," plus a security restriction that beginners always trip over (some keys written in project configs are simply ignored)
  • What the seven or eight configuration options you will modify most often do and their defaults (model, approval_policy, sandbox_mode, web_search, [features]...)
  • A minimal configuration you can copy directly + a command to temporarily modify options with -c + a hands-on exercise switching multiple configurations with --profile, which you can verify immediately after running

01 Understand First: What config.toml Is, and How It Divides Labor with AGENTS.md

The bottom line: config.toml is the 'control panel' of Codex—using the TOML format to manage tool behaviors like models, approvals, sandboxes, MCP, and feature switches; it is a separate system from AGENTS.md, where one governs 'how to work' and the other governs 'what to remember'.

Many people mix these two up right from the start. You spent the whole of 11 AGENTS.md writing project instructions, and configured sandboxes in 15 Permissions, Sandbox, and Approvalthe former goes into AGENTS.md, while the latter goes into config.toml, containing entirely different contents.

Analogy: A car's 'owner's manual' vs. 'dashboard knobs'. AGENTS.md is like the owner's manual in the glove compartment—written in natural language for humans (for Codex) to read as background context whenever it starts working, like "this car uses 95 octane fuel" or "warm up the engine before driving in winter." config.toml is different; it is the row of physical knobs on the dashboard—what temperature the air conditioning should be, whether seat heating is turned on, and whether to default to sport mode or eco mode—clear switches executed directly by the machine. The manual is "words spoken to it," while the knobs are "actions locked down for it."

TOML (Tom's Obvious Minimal Language, a configuration file format designed to be easily read and written by humans) is the format of this file. It looks like this: the top level is key = value, and grouping uses [table_name]. Let's take a quick look:

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

The official docs define its position clearly:

Codex stores user-level configuration at ~/.codex/config.toml.

In the real-world scenarios you will encounter, config.toml manages these kinds of things:

  • "I want to use a specific model every time, don't make me switch manually"—write model
  • "On this machine, default to giving me workspace write permissions + asking only for out-of-bounds operations"—write sandbox_mode + approval_policy
  • "I want real-time network searches, don't use the cache"—write web_search
  • "Enable / disable this experimental feature for me"—write [features]

None of these are "words spoken to Codex," but rather knobs that change its execution behavior for real. This is the fundamental division of labor between config.toml and AGENTS.md.

💡 Summary in one sentence: AGENTS.md is "natural language instructions spoken to Codex," while config.toml is the "control panel locking down machine behaviors"—the former manages what to remember, and the latter manages how to work; do not mix them up.


02 Where Files Go: User-level and Project-level

The first thing to understand about config.toml is not which keys exist, but rather that it has at least two locations: one in your home directory (for global settings) and one that can be placed inside a project (only for that project). The pitfall mentioned at the beginning is rooted in not distinguishing between these two locations.

Analogy: A home's main breaker box vs. wall switches in a room. Your house has a main breaker box (usually in the hallway) that governs default behaviors for the whole house—like "limit current at night." Each room also has its own switches on the wall, which only govern that room and have higher priority—if you want to turn on the main light in the study, just press the switch on the study wall; it won't affect other rooms. config.toml has these two layers: the home directory one is the main breaker box (across all projects), and the project-level one is the room switch (only for this project, overriding the main breaker).

The locations defined officially are shown in this table:

LevelFile LocationScope of ImpactWhat to place insideA Prerequisite
User-level (User)~/.codex/config.tomlYou, across all your projectsPersonal defaults: preferred model, default permissions, MCP, notificationsNone
Project-level (Project)<repo>/.codex/config.tomlWhen working in this repositoryProject-specific: model for this project, sandbox level for this projectProject must be trusted to load

Here are three points beginners must memorize:

First, the path of the user-level one in the home directory is fixed: ~/.codex/config.toml. This ~/.codex directory is called CODEX_HOME, which is where Codex stores all local assets (configurations, login credentials, history, logs) and defaults to your home directory. If the file does not exist, create it yourself; Codex will read it.

Second, the project-level one should be placed in the .codex/ subdirectory of the repository (note that it is .codex/config.toml, a hidden directory with a dot, matching the name of the home directory one but in a different location). It only stacks on top when you are working in this project.

Third, and most easily overlooked—project-level configurations are only loaded if the "project is trusted." This is a safety design in Codex: it prevents a random repository you clone from secretly granting itself permissions via .codex/config.toml. The official documentation states:

If you mark a project as untrusted, Codex skips project-scoped .codex/ layers, including project-local config, hooks, and rules.

In other words: if you write .codex/config.toml in an untrusted project, none of its lines will take effect—but the user-level one in your home directory will load normally. If you write project-level settings for the first time and find "nothing happens," check if you trusted the project (trust is what Codex asks you the first time you enter a new project).

How to Divide in Practice: Where a Configuration Should Go

To decide whether a configuration should go to the home directory or the project directory, ask yourself: "Is this setting related only to me as a person, or to this project?"

  • "I want this across all projects" → User-level (~/.codex/config.toml). For example, "I prefer using gpt-5.5 by default," "my MCP servers," or "desktop notification scripts." Configure it once, and it is active for any project.
  • "Only this project should do this" → Project-level (<repo>/.codex/config.toml). For example, "this legacy project must use a specific model," or "this project defaults to read-only." It follows the repository; once committed to Git, teammates pulling it will share the same settings (provided they also trust the project).

My own division is simple: I write "my personal habits" in the home directory one, and leave the project one empty—unless a project has specific needs (like a client codebase that I only allow read-only access to, with no modifications). In that case, I write a single line sandbox_mode = "read-only" in its .codex/config.toml as a safety net. This avoids having to restrict permissions manually every time and prevents this restriction from leaking to other projects.

💡 Summary in one sentence: User-level ~/.codex/config.toml (in CODEX_HOME, governing all your projects) and project-level <repo>/.codex/config.toml (governing only this project, loading only if the project is trusted); memorize the rule "follows me vs. follows this project."


03 Who Overrides Whom: Priorities, and a Security Restriction Beginners Always Trip Over

You can write the same key in both places. So the question is: if the user-level says to use gpt-5.5 and the project-level says to use something else, who wins? This is what "precedence" governs, and it is where config.toml is most likely to confuse people.

In fact, there are more than two layers—adding command-line temporary arguments, profiles selected with --profile (named configuration files), and system-level configurations, there are six layers in total. Here is the complete priority ranking from the official docs, from highest to lowest (higher overrides lower):

PrioritySourceExplanation
1 (Highest)Command-line arguments / --configYour temporary decisions for this run, governing only this execution
2Project-level <repo>/.codex/config.tomlSettings for this project (trusted ones, from the root directory to the current directory—closer wins)
3--profile named configuration ~/.codex/<name>.config.tomlThe specific named configuration set you switched to
4User-level ~/.codex/config.tomlYour global defaults
5System-level /etc/codex/config.toml (Unix, if present)Set by administrators for the entire machine
6 (Lowest)Built-in default valuesWhat Codex comes with when you write nothing

This "highest-to-lowest" override relationship is illustrated below—upper layers cover the parts of identical keys written in lower layers:

Config Precedence Stack

This diagram stacks the six configuration layers from highest priority (top) to lowest (bottom): the top layer, "Command-line arguments / --config", is the most specific and overrides everything else. Below it are project-level settings, --profile named configurations, user-level settings, and system-level settings, with the built-in defaults at the very bottom. Upper layers override matching keys in lower layers, meaning the more specific and immediate the setting, the more authority it has.

Memorize the order: the more specific and immediate, the higher the priority; the more global and default, the lower the priority. Command line (this run only) overrides project (this project only), project overrides named profile, named profile overrides user global, user global overrides system, and system overrides built-in defaults. The official docs highlight a practical pattern:

Use that precedence to set shared defaults in config.toml and keep profile files focused on the values that differ.

In other words: write "what I do most of the time" in the home directory, write "differences I occasionally switch to" in profiles, and use the command line for "one-off exceptions." This answers the teaser from the end of the last article: if you want a preference to be active from startup, write it in config.toml (most likely the user-level one).

The Security Restriction Beginners Always Trip Over: Some Keys Cannot Be Set in Project Configs

We established that project-level configs override user-level ones. But there is a class of keys that are exceptions—if you write them in a project-level .codex/config.toml, Codex will ignore them and print a warning at startup. This is a security red line deliberately drawn by Codex, and beginners trip over it frequently.

Why restrict them? Think about it: if an unfamiliar repository's .codex/config.toml could secretly modify the model service URL you connect to, change your authentication, or run arbitrary notification commands on your machine—that would be extremely dangerous. Therefore, the system restricts keys that affect machine-level security to user-level configurations only. The official documentation states:

Codex ignores openai_base_url, chatgpt_base_url, apps_mcp_product_sku, model_provider, model_providers, notify, profile, profiles, experimental_realtime_ws_base_url, and otel when they appear in a project-local .codex/config.toml.

In plain terms, these keys are ignored in project-level configs and must go to the user-level config:

These KeysWhat they governWhy restricted to user-level
model_provider / model_providersModel providers, API endpointsPrevents untrusted repositories from routing your requests elsewhere
openai_base_url / chatgpt_base_urlBase URLs of built-in servicesSame as above; changing URLs changes where data goes
notifyExternal commands run when a task finishesPrevents repositories from running commands on your machine
otelTelemetry / log exportsPrevents exfiltration of execution logs
profile / profilesSelecting configuration profilesProfiles must be selected via command line --profile, preventing repositories from selecting them for you

Remember: keys related to model services, notifications, telemetry, and selecting profiles are "machine-level" keys and must go into the home directory config; project-level configs should only define keys like model, sandbox_mode, and approval_policy which govern "how to work locally on this project." If you write model_providers in a project config and find it doesn't take effect, it's not a syntax error—it was blocked by security design.

💡 Summary in one sentence: Precedence rule: "the more specific and immediate, the higher the priority" (Command line > Project > Profile > User > System > Built-in defaults); however, project-level configs cannot modify machine-level keys like model_provider, notify, otel, and profile—writing them is ignored and raises warnings; they are only recognized at the user-level.


04 Common Configuration Keys: Roles and Defaults

Now that we have sorted out the levels and priorities, let's look at the keys you are most likely to modify. Codex supports hundreds of keys (the complete list is in the official Config Reference), but 90% of developers only interact with a few. I have highlighted them here, explaining what they do and their defaults—knowing the defaults is particularly important so you know what you don't need to write.

Config KeyWhat it doesDefault Value (Subject to official docs)Common Writing
modelDefault model to useFollows Codex built-in defaultmodel = "gpt-5.5"
approval_policyWhen to stop and ask youon-requestapproval_policy = "on-request"
sandbox_modeSandbox scope (files / network)workspace-write (for Git repos, see note)sandbox_mode = "workspace-write"
model_reasoning_effortReasoning effort levelFollows model / presetmodel_reasoning_effort = "high"
web_searchWeb search modecached (cache)web_search = "live"
personalityCommunication stylefriendly (example value)personality = "pragmatic"
file_openerEditor to open file referencesvscodefile_opener = "cursor"

Clarification on the default sandbox_mode: Running codex directly defaults to the Auto preset—workspace-write in Git repositories (allowing read/write access to workspace files), and read-only in non-Git directories. The official docs call workspace-write the "default sandbox mode," referring to this most common Git repository scenario.

Details you should know about these keys:

model / model_reasoning_effort / approval_policy / sandbox_mode

These four are the highlights, but they have been covered in detail in previous articles and won't be repeated here: model selection was covered in 05 Third-party Models, and approval policy (approval_policy) and sandbox mode (sandbox_mode) were covered in 15 Permissions, Sandbox, and Approval. Here, you just need to know: they have corresponding keys in config.toml, and writing them defines those behaviors as defaults so you don't have to adjust them manually with /model or --sandbox every time.

model_reasoning_effort controls reasoning intensity. The official levels are minimal | low | medium | high | xhigh (provided the model supports xhigh). Lower settings save time and token limits for simple tasks, while high is for complex challenges.

web_search: Web search, default is "cached" rather than "real-time"

This key has a counter-intuitive default that I tripped over on my first day. Codex enables web search by default, but it uses the cached mode—searching a web index maintained by OpenAI, returning pre-collected results rather than scraping live web pages on the spot. The official docs explain this is to reduce prompt injection risks: cached content is safer than arbitrary live pages.

Last year I asked Codex to "look up the latest version number of a library" and it returned an outdated number—it took me a while to realize it was using cached index. To search in real-time, you must change it explicitly:

toml
web_search = "live"   # Real-time scraping, equivalent to command line --search
# web_search = "cached"   # Default: use cached index
# web_search = "disabled" # Turn off search tool completely

An exception to note: if you use --yolo or other full-access sandboxes, web_search automatically becomes live.

personality: Changing Codex's conversational style

personality adjusts the communication style. The official options are none | friendly | pragmatic. It can also be switched temporarily with /personality in the session. I keep mine at pragmatic—it skips small talk and goes straight to conclusions, which is more convenient for experienced developers.

file_opener: Opening referenced files

Codex output often includes references like some_file.py:42. file_opener determines which editor opens them on click. The default is vscode, with options like vscode-insiders | windsurf | cursor | none. Setting it to cursor turns references into clickable links that jump directly to that line in Cursor.

A TOML Pitfall: Root Keys Must Precede Tables

This is the most common syntax error when writing config.toml. TOML rules state: all top-level key = value entries (root keys) must appear before any [table] blocks. The official example config file specifically reminds us of this:

Root keys must appear before tables in TOML.

What does this mean? Let's look at the correct and incorrect examples:

❌ Incorrect (Root key mixed after table)✅ Correct (Root keys first, tables last)
[features]
hooks = true
model = "gpt-5.5" ← Error
model = "gpt-5.5"
[features]
hooks = true

Rule of thumb: write all keys without [] (like model, approval_policy...) first, then write the [table] sections. Reversing this order throws TOML parsing errors, and the error messages are often confusing to beginners.

💡 Summary in one sentence: The high-frequency keys are model, approval_policy, sandbox_mode, model_reasoning_effort, web_search (default is cached, not live!), personality, and file_opener; understand the defaults and don't write them unless you have special requirements; and remember the TOML rule: root keys must appear before tables.


05 [features]: Switches for Experimental and Optional Features

One configuration table deserves special mention—the [features] table, which acts as the control board for all optional / experimental features in Codex. Whether features mentioned in previous articles (Memory, hooks, subagent collaboration) are enabled or disabled is decided here.

Analogy: The 'developer options / labs' menu in phone settings. Stable system features are enabled by default, but there is a "Labs" section with switches you can toggle manually—some default to on, others to off. Toggling them turns a feature on or off. [features] is Codex's Labs section: each feature has a boolean switch, set to true to enable, false to disable, and left out to use its default.

Write it as a [features] table followed by the feature keys:

toml
[features]
memories = true          # Enable Memory
shell_snapshot = true    # Snapshot shell environment to speed up repeated commands
hooks = false            # Disable lifecycle hooks

Here are some feature switches you might toggle (defaults are subject to official docs):

Feature KeyDefaultMaturityWhat it does
hookstrueStableLifecycle hooks (scripts triggered by events)
multi_agenttrueStableSubagent collaboration tools
shell_snapshottrueStableSnapshots shell environment to speed up repeated commands
fast_modetrueStableFast response mode (reduces wait times)
shell_tooltrueStableBuilt-in shell tool (executes terminal commands)
personalitytrueStableCommunication style selector controls
memoriesfalseStableMemory (memory system, covered in the next article)
codex_git_commitfalseExperimentalLet Codex automatically generate git commit messages
appsfalseExperimentalChatGPT Apps / connectors support
undofalseStableUndo support using git ghost snapshots
...See official Config Reference for more keys

⚠️ Experimental features, subject to change. The defaults and maturity of keys marked "Experimental" (and others not listed here) may change. Check the official Config Reference and your local installation before enabling them.

Note a common pitfall: some legacy styles (like using codex_hooks = true inside [features] to enable hooks) are outdated—the official standardized key name is hooks, and codex_hooks is a deprecated alias. Use the current official key names instead of copying from old guides.

The official docs offer three ways to toggle switches:

  • In config.toml: write feature_name = true (or false) under [features].
  • Temporarily via command line: run codex --enable feature_name, or specify multiple with --enable a --enable b.
  • Disabling: set the key to false in [features].

My suggestion: beginners should not enable all experimental features at once. If you want to try Memory (covered in Article 19), enable it with memories = true, and leave the rest default. Enabling too many experimental features makes it hard to identify the cause when issues arise.

💡 Summary in one sentence: [features] is the optional/experimental feature switchboard, where each feature has a boolean value (set true/false to toggle, leave empty for defaults like hooks/multi_agent/shell_snapshot defaulting to on, and memories/apps to off); temporarily enable via command line with --enable; ensure key names follow the current official guidelines as old styles like codex_hooks are deprecated.


06 Temporary Overrides vs. Switching Profiles: -c and --profile

Two common needs cannot be met simply by modifying the configuration file: modifying a single key for a single run and reverting it, and switching between multiple configuration sets. Codex provides two tools for these tasks.

Temporary Overrides: -c / --config (Without Modifying Files)

If you don't want to edit files just to test a configuration key, override it directly in the command line:

bash
# Prefer dedicated flags (if available)
codex --model gpt-5.4

# For keys without dedicated flags, use -c / --config (values use TOML syntax, not JSON)
codex --config model='"gpt-5.4"'
codex -c log_dir=./.codex-log

Two details you should watch out for, as warned by the official docs:

  • -c values are parsed as TOML, not JSON. Thus, string values must be quoted (like model='"gpt-5.4"' with single quotes for the shell and double quotes for TOML). Quote the entire value if unsure, preventing the shell from splitting it by spaces.
  • Nested keys use dot notation, like codex -c mcp_servers.context7.enabled=false.

This is perfect for "testing if a value works"—if you like it, write it to the file; if not, just exit and the file remains untouched.

Switching Profiles: --profile (Named Configurations)

Article 15 introduced profiles. Here we cover their mechanism in full. A profile is a separate file under CODEX_HOME, named <profile_name>.config.toml:

toml
# ~/.codex/deep-review.config.toml
model = "gpt-5.5"
model_reasoning_effort = "xhigh"
approval_policy = "on-request"

Select it using --profile:

bash
codex --profile deep-review
codex exec --profile deep-review "review this change"

The mechanism is: Codex reads your user-level ~/.codex/config.toml first, then applies ~/.codex/deep-review.config.toml on top of it. Therefore, profile files only need to define keys that differ from your base configuration; matching keys do not need to be repeated.

Here is a version change warning you should note:

⚠️ Version differences apply. Official statement: In Codex 0.134.0 and later, --profile no longer reads [profiles.profile_name] blocks inside config.toml, and the top-level profile = "profile_name" selector is no longer supported. Legacy configurations must move [profiles.x] blocks to separate ~/.codex/x.config.toml files. Your installed version might behave differently; always refer to your local version and the official documentation.

I maintain two profiles: quick (light model + read-only, for browsing code) and build (powerful model + workspace-write, for actual work). Running codex --profile build starts the correct settings directly, saving me from adjusting multiple keys manually—this is the cure for the "manual setup thirty times a week" issue I faced when starting out.

💡 Summary in one sentence: Temporarily modify a single key using -c key=value (values parse as TOML, strings require quotes, nested keys use dot notation) without changing the file; to switch configuration sets, write the differences to ~/.codex/<name>.config.toml and select with --profile <name>note that version 0.134.0+ no longer supports the [profiles.x] syntax, subject to change.


07 Hands-on: Write a Config → Override Temporarily → Switch Profiles

Practice makes perfect. The steps below guide you through the process of "writing a configuration → temporary override → switching profiles." This is a minimal example that does not rely on any complex setup. Command parameters follow official documentation. I use gpt-5.5 as a placeholder model name; replace it with the model you actually have access to.

Step 1: Check where your user-level config is (in your terminal)

bash
ls -la ~/.codex/config.toml

Expected: Lists the file, or reports that it does not exist. If it does not exist, create it in the next step.

Step 2: Write a minimal user-level configuration

Save the block below into ~/.codex/config.toml (note root keys are first, [table] is last):

toml
# ~/.codex/config.toml
model = "gpt-5.5"
approval_policy = "on-request"
web_search = "cached"

[features]
memories = false

Expected: Once saved, this file becomes your global default. Verify it is loaded in the next step.

Step 3: Enter the session and use /status to confirm configurations are active

Run:

bash
codex

In the session, type:

text
/status

Expected: In the displayed status info, verify the model and approval policy match what you just wrote—showing config.toml was loaded successfully. (We saw /status in Article 12; it is the command to check the current session state.)

Step 4: Use -c to temporarily override a key without changing the file

Exit the session, and start again by temporarily changing search to live:

bash
codex -c web_search='"live"'

Run /status in the session again.

Expected: The search mode for this session is live, but the line web_search = "cached" in your configuration file remains unchanged. Exiting and running codex normally returns it to cached. Verifying this "temporary change, automatic revert" confirms the priority rule of "command line overrides configuration file for this run only."

Step 5: Create a profile to experience switching sets

Create a new file ~/.codex/quick.config.toml (defining only differences from the base configuration):

toml
# ~/.codex/quick.config.toml
model = "gpt-5.5"
sandbox_mode = "read-only"
approval_policy = "untrusted"

Start with it:

bash
codex --profile quick

Run /status to confirm.

Expected: The sandbox for this session is read-only and the approval is untrusted (stricter than your home directory defaults)—because the profile stacks on top of the user-level config. Verifying this stricter configuration confirms that profiles are separate files selected with --profile. Running codex without --profile returns to your user-level defaults.

Running these five steps lets you verify the core capabilities of config.toml yourself: writing files to set defaults, verifying loads with /status, temporary overrides with -c, and switching sets with --profile. The process is the same for configuring other keys and levels.

💡 Summary in one sentence: Practice by running the sequence: "write user-level config → verify load with /status → override temporarily with -c keeping the file intact → switch to a stricter named profile with --profile"; running this flow resolves the three tasks of "saving defaults, temporary overrides, and profile switching" at once.


08 Summary

We have thoroughly explored the config.toml control panel—covering what it is, where it goes, priority overrides, common keys, temporary overrides, and profile switching, helping you manage settings systematically.

Let's review the key points:

ObjectiveAnswerKey Takeaway
Relationship with AGENTS.mdSeparate systemsAGENTS.md manages "what to remember", config.toml manages "how to work"
File LocationsTwo locationsUser-level ~/.codex/config.toml, project-level <repo>/.codex/config.toml (loads only if trusted)
Overriding conflictsStated priorityCommand line > Project > Profile > User > System > Built-in defaults
Security RestrictionsProject-level restrictionsKeys like model_provider/notify/otel/profile are restricted to user-level
Common keysSeven or eight keysmodel/approval_policy/sandbox_mode/web_search (defaults to cached)/[features], etc.
Temporary vs. Profiles-c / --profile-c overrides once keeping files intact, --profile switches named configurations

You should now be able to: distinguish between config.toml and AGENTS.md roles; decide if a setting should go to user-level or project-level; understand the six-layer priority stack and the security restriction preventing project-level overrides on machine-level keys; identify common configurations (model, approval_policy, sandbox_mode, web_search, [features]) and their default values; and use -c for temporary overrides and --profile for switching sets. This ability to manage settings in one place is your wrench for customizing Codex to fit your habits right from startup.

The manual configurations I had to repeat thirty times a week were rooted in a simple mistake—I failed to write once in config.toml. This article helps you avoid that detour: when you find yourself repeating configuration commands, stop and think: "should this be saved to the configuration file, and does it belong to the user-level or project-level?"


The next article [19 Memory System (Memories and Chronicle)]—you saw the default-disabled memories switch in the [features] table; remember? The next article covers it specifically: how to let Codex "remember" your habits and project structures, turning it from a fresh assistant every session into a long-term partner who knows your workflow. A quick thought: in the previous article, it gained "eyes to see the screen"; in this article, it gains a "brain to remember details"—how does an assistant that can see and remember differ from what you are using right now?