Codex reads only a handful of environment variables. The important ones are CODEX_HOME (where Codex keeps its config and state, ~/.codex by default), CODEX_API_KEY (an API key for non-interactive runs), CODEX_ACCESS_TOKEN (a ChatGPT or Codex token for trusted automation) and RUST_LOG (log verbosity). Durable settings such as the model, sandbox and approvals belong in config.toml, not in the environment.
OpenAI's environment variables page puts it plainly: "Codex uses config.toml for durable settings. Use environment variables for shell-scoped overrides, automation secrets, installer behavior, or diagnostics." This guide lists every variable on that page, read on 26 October 2026 (latest CLI release on GitHub: 0.164.0), plus the config keys that control which variables reach the commands Codex runs.
Which environment variables does Codex read?
Here is the full documented list. The Group column is ours; OpenAI's page uses four sections: core locations, installer variables, authentication and network, and diagnostics.
| Variable | Group | Default | What it does |
|---|---|---|---|
CODEX_HOME |
Locations | ~/.codex |
Root folder for config, auth, logs, sessions, skills and package metadata |
CODEX_SQLITE_HOME |
Locations | CODEX_HOME |
Where SQLite-backed state is stored |
CODEX_NON_INTERACTIVE |
Installer | false |
1, true or yes skips installer prompts |
CODEX_INSTALL_DIR |
Installer | ~/.local/bin (macOS, Linux) |
Where the visible codex command is installed |
CODEX_API_KEY |
Auth | none | API key for a non-interactive Codex process |
CODEX_ACCESS_TOKEN |
Auth | none | ChatGPT or Codex access token for trusted automation |
OPENAI_FEDERATION_RULE_ID |
Workload identity | none | Selects the federation rule for the workload |
OPENAI_IDENTITY_TOKEN_FILE |
Workload identity | none | Absolute path to the current OIDC token or SPIFFE JWT-SVID |
OPENAI_WORKLOAD_IDENTITY_CONTEXT |
Workload identity | none | Optional JSON identifiers for audit attribution only |
CODEX_CA_CERTIFICATE |
Network | none | PEM CA bundle for corporate TLS interception; wins over SSL_CERT_FILE |
SSL_CERT_FILE |
Network | none | Fallback PEM CA bundle |
RUST_LOG |
Diagnostics | error for codex exec |
Log filtering and verbosity |
On Windows, CODEX_INSTALL_DIR defaults to %LOCALAPPDATA%\Programs\OpenAI\Codex\bin. The page also says what it leaves out: internal development variables, test variables, and provider key names you pick yourself with env_key.
What does CODEX_HOME control?
CODEX_HOME is the one variable most people end up setting. In OpenAI's words it "Sets the root for Codex state, including config, auth, logs, sessions, skills, and standalone package metadata. If you set it, the directory must already exist." The CLI, IDE extension, app-server and installers all read it.
Under that folder you will find config.toml, auth.json (when you use file-based credential storage), history.jsonl (when history is on), logs and caches. Profile files live there too, as $CODEX_HOME/<name>.config.toml, which the Codex profiles guide covers.
mkdir -p ~/codex-work
CODEX_HOME=~/codex-work codex
Tip (our inference, not a documented feature): because config, history and file-based credentials all live under CODEX_HOME, pointing it at another existing folder is a simple way to keep a second, separate setup. A profile, by contrast, only layers settings on top of config.toml. If you just want to skip your user config for one scripted run, codex exec --ignore-user-config does that, and the docs note that "Authentication still uses CODEX_HOME."
CODEX_SQLITE_HOME moves only the SQLite state. The sqlite_home key in config.toml takes precedence over it, and relative paths resolve from the current working directory.
How do you authenticate Codex with environment variables?
There are two documented auth variables, and they serve different jobs.
CODEX_API_KEY gives an API key to a non-interactive process. The non-interactive mode page says you can use it with codex exec, codex review, the TypeScript SDK and codex exec-server --remote. Set it inline, on the one command that needs it:
CODEX_API_KEY=<api-key> codex exec --json "triage open bug reports"
CODEX_ACCESS_TOKEN carries a ChatGPT or Codex access token. In ChatGPT Enterprise workspaces, admins can let permitted members create these tokens for trusted scripts, schedulers and private CI runners. To save the login instead of passing it every time, pipe it in:
printenv CODEX_ACCESS_TOKEN | codex login --with-access-token
printenv OPENAI_API_KEY | codex login --with-api-key
OPENAI_API_KEY is not on OpenAI's list of variables Codex reads directly; the second line just uses your shell's copy to feed codex login. The authentication page notes that signing in with an API key uses standard API pricing instead of included ChatGPT plan credits.
The security warning matters. OpenAI says: "Do not set OPENAI_API_KEY or CODEX_API_KEY as a job-level environment variable in workflows that check out or run repository-controlled code." Build scripts, tests and dependency hooks in the same job can read them. On GitHub Actions, the Codex GitHub Action starts a Responses API proxy to reduce API key exposure.
The three OPENAI_* variables are for workload identity setups, where the workload presents an OIDC token or SPIFFE JWT-SVID file. When the process selects workload identity, codex login and codex logout are rejected because the environment controls auth.
How do you use API keys for other providers?
There is no fixed variable name for a third-party or proxy provider. You choose one in config.toml with env_key, and Codex reads whatever variable that names:
model_provider = "proxy"
[model_providers.proxy]
name = "OpenAI using LLM proxy"
base_url = "http://proxy.example.com"
env_key = "OPENAI_API_KEY"
The same pattern appears elsewhere in the configuration reference: model_providers.<id>.env_http_headers fills HTTP headers from environment variables, mcp_servers.<id>.bearer_token_env_var names the variable holding an MCP server's bearer token, and mcp_servers.<id>.env_http_headers does the header trick for MCP over HTTP. Keeping secrets in variables and only their names in config means the file is safe to share.
Which variables reach the commands Codex runs?
This is the part people usually mean when they search for Codex environment variables: when Codex runs npm test or pytest, which of your variables does that process see? The [shell_environment_policy] table decides.
[shell_environment_policy]
inherit = "core" # all | core | none
set = { MY_FLAG = "1" } # fixed values added after exclusions
ignore_default_excludes = false # strip names containing KEY, SECRET, TOKEN
[shell_environment_policy.filters]
"AWS_*" = "exclude"
"AZURE_*" = "exclude"
The rules, from the advanced config page:
inheritsets the starting point: everything (all), a trimmed set (core) or an empty environment (none).ignore_default_excludesdefaults totrue, so Codex does not strip names containingKEY,SECRETorTOKENunless you set it tofalse.- Filter patterns are case-insensitive and accept
*and?. If any pattern saysinclude, only matching names survive. - Order: automatic exclusions, then your exclusions, then
set, then the include allowlist. Sosetcan restore an excluded name, and an include list can still remove it. - The older
excludeandinclude_onlyarrays still work, but do not mix them withfiltersin the same layer.
For a one-off run you can override it from the command line:
codex -c 'shell_environment_policy.include_only=["PATH","HOME"]'
MCP servers are separate. A stdio server gets mcp_servers.<id>.env for fixed values and mcp_servers.<id>.env_vars to pass through named variables from your shell.
Internal and undocumented: the openai/codex source also sets two variables in commands Codex spawns. They are not on OpenAI's documented list, and the source comments say they may change, so do not build on them: CODEX_SANDBOX_NETWORK_DISABLED is set to 1 when network access is restricted for that command, and CODEX_SANDBOX is set to seatbelt under the macOS sandbox.
How do you install Codex without prompts?
The standalone installers at chatgpt.com/codex/install.sh and install.ps1 read CODEX_NON_INTERACTIVE and CODEX_INSTALL_DIR. Set them on the shell that runs the installer:
curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh
$env:CODEX_NON_INTERACTIVE=1; irm https://chatgpt.com/codex/install.ps1 | iex
Prompts take their default answer, so OpenAI recommends this for scripted installs and updates, not first-run setup. Changing CODEX_INSTALL_DIR moves only the visible codex command; the package cache stays under CODEX_HOME/packages/standalone.
How do you debug Codex with RUST_LOG?
RUST_LOG accepts error, warn, info, debug and trace, or targeted filters such as codex_core=debug,codex_tui=debug. The plaintext TUI log is opt-in, so pair it with log_dir:
RUST_LOG=debug codex -c log_dir=./.codex-log
tail -F ./.codex-log/codex-tui.log
codex exec defaults to error output and prints messages inline rather than writing a separate log. Behind a corporate proxy that intercepts TLS, set CODEX_CA_CERTIFICATE to your PEM bundle before you chase other errors; it takes precedence over SSL_CERT_FILE.
Two editor variables matter in the terminal UI too. Pressing Ctrl+G opens the editor named in VISUAL, or EDITOR when VISUAL is unset, so you can write a long prompt there, as the CLI customization page describes.
How do environment variables work in Codex Cloud?
Cloud tasks do not see your laptop's environment. In a cloud environment's settings, select Manage beside Environment variables or Network secrets. Per the cloud environments page, an environment variable is "Passed directly to programs in the environment," while for a network secret "Programs receive a placeholder; the proxy substitutes the real value for allowed destinations." Substitution works for HTTPS on port 443.
You can also keep personal values in Settings > Codex Cloud > Personal vault and apply them to all or selected environments. A shared environment can request values that each person supplies, so sharing the environment does not share your credentials. In the legacy cloud setup, secrets are only available to setup scripts and are removed before the agent phase starts.
Keep variables out of your prompts
A tidy setup keeps secrets in the environment, settings in config.toml, and instructions in skills and AGENTS.md. For the last part, Kipt keeps prompts and Agent Skills as Markdown in a private GitHub repo you own and installs every skill into Codex with one command, npx skills add https://github.com/<you>/<repo>.git --all -g. For everything else on the settings side, see the Codex config.toml guide and the Codex cheat sheet.