Who this is for
This is for readers who already run Codex and want to manage several setups: a review profile, a different model provider, a local model, or stricter approvals. By the end you can organize your config into profiles, override settings for one run, add a custom provider, and understand how project files interact with your user config.
Where the config lives
Codex keeps local state under CODEX_HOME, which defaults to ~/.codex. The main file is config.toml. You may also see auth.json if file-based credential storage is used.[1] For authentication details and the full key list, use the official pages.[1]
Profiles: switch between setups
A profile is a named layer. Running with --profile profile-name loads ~/.codex/config.toml first, then overlays ~/.codex/profile-name.config.toml.[1] Names can use letters, numbers, hyphens and underscores. Write each profile as its own file with top-level keys, not as a [profiles.profile-name] table.[1] A profile sits above your base config and below project and CLI settings, so it only needs the values that differ.[1]
Here is an example profile for a deep review. The example uses a model that requires access on your account. If you do not have it, pick a model you can use.[1]
# ~/.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"Run it like this:[1]
codex --profile deep-review
codex exec --profile deep-review "review this change"Starting with Codex 0.134.0, --profile no longer reads [profiles.profile-name] from config.toml, and the top-level profile = "profile-name" selector is no longer supported. If you have older profile tables, move them into the profile file and delete the old table and selector.[1]
One-off overrides
For a single run, use a dedicated flag if one exists, such as --model. For any other key, use -c or --config. Values are parsed as TOML. If a value cannot be parsed, Codex treats it as a string.[1] Keys can use dot notation for nested values, such as mcp_servers.context7.enabled=false.[1]
Project config and trust
Codex also reads .codex/config.toml files inside your repository. It walks from the project root down to the current directory and loads each file it finds.[1] Project config is used only when the project is trusted. In an untrusted project, Codex ignores the .codex/ layers, including project-local hooks and rules.[1]
Some keys belong only in your user config. Codex ignores model_provider, model_providers, notify, profile, profiles, otel, openai_base_url and chatgpt_base_url in project files, and prints a warning at startup.[1] By default, a directory with .git is the project root. project_root_markers changes which markers count.[1]
Connect a custom model provider
A provider defines the base URL, the wire API, authentication and optional headers. A custom provider needs its own unique ID. Codex reserves built-in IDs such as openai, ollama and lmstudio.[1] Define providers as tables and point model_provider at one of them:[1]
model = "gpt-6.1-sol"
model_provider = "proxy"
[model_providers.proxy]
name = "OpenAI using LLM proxy"
base_url = "http://proxy.example.com"
env_key = "OPENAI_API_KEY"
[model_providers.local_ollama]
name = "Ollama"
base_url = "http://localhost:11434/v1"
[model_providers.mistral]
name = "Mistral"
base_url = "https://api.mistral.ai/v1"
env_key = "MISTRAL_API_KEY"env_key names the environment variable that holds the provider's key.[1] To change the base URL of the built-in openai provider, set openai_base_url instead of creating [model_providers.openai], because built-in IDs cannot be overridden.[1]
model_verbosity only affects providers that use the Responses API. Chat Completions providers ignore it.[1]
Local models with --oss
Run codex --oss to use a local provider such as Ollama or LM Studio. Pick one for a run with --local-provider, or set a default with oss_provider.[1] If neither is set, the interactive CLI asks you to choose, and codex exec exits with an error.[1]
Approvals and sandbox
Approval policy controls when Codex pauses. The sandbox controls file and network access. The example sets approval_policy to on-request, routes approvals to the user, and uses workspace-write:[1]
approval_policy = "on-request" # Other options: never or { granular = { ... } }
approvals_reviewer = "user" # Or "auto_review" for Auto-review
sandbox_mode = "workspace-write"
allow_login_shell = false # Optional hardening: disallow login shells for shell toolsapproval_policy takes on-request, never, or a granular table. Codex and ChatGPT Work no longer accept "untrusted".[1] With approvals_reviewer = "auto_review", eligible requests go through Auto-review.[1]
In workspace-write mode, some environments keep .git/, .agents/, .codex/ and .aws/ read-only. So a command such as git commit may still need approval to run outside the sandbox.[1] The network_access key in this table opts in to outbound network access:[1]
[sandbox_workspace_write]
exclude_tmpdir_env_var = false # Allow $TMPDIR
exclude_slash_tmp = false # Allow /tmp
writable_roots = ["/Users/YOU/.pyenv/shims"]
network_access = false # Opt in to outbound networksandbox_mode = "danger-full-access" turns sandboxing off entirely. The docs say to use it only when your environment already isolates processes.[1]
Layer order and troubleshooting
Your user config.toml is the base layer. A profile file passed with --profile sits above it, and project .codex/config.toml files and CLI overrides sit above the profile.[1] So a profile only needs the values that differ, and a --config override on the command line wins over the layers below it.[1]
When a setting seems to be ignored, check three things. First, whether the project is trusted, because an untrusted project's .codex/ layers are ignored.[1] Second, where the key lives. Keys such as model_provider and profile are ignored in project files, and Codex prints a warning at startup, so move them to ~/.codex/config.toml.[1] Third, older profile tables. From Codex 0.134.0, [profiles.profile-name] is no longer read.[1]
Next steps
Start with one profile and one override. Once they work, add a provider. The full list of keys and requirement constraints is in the Configuration Reference.[1]
Sources
- 1Advanced ConfigurationOpenAI Codex docs
Cite this page: Advanced Codex configuration: profiles, models and providers. TellWorld, https://www.tellworld.net/practice/practice-codex-config-advanced. Updated 2026-11-14