LIVE|CLI v0.144.0·model GPT-5.6 Sol·verified 2026-07-09
Codex Insider
The unofficial wire for OpenAI Codex.
config.toml key

model_providers.<id>.env_key

default: unset

Published Jul 15, 2026 · Verified against the official config docs

What it does

env_key names the environment variable Codex reads to get the API key for a custom model provider. It holds the variable name, not the secret itself. Codex looks that variable up when it starts and uses whatever value it finds. Pair it with env_key_instructions to print a setup hint when the variable is missing. Default is unset, so any custom provider needs env_key or a command-backed auth block.

When you point Codex at a provider that isn’t the built-in OpenAI one, you have to tell it where to find the API key. env_key is how. You give it the name of an environment variable, and Codex reads the actual key out of that variable at launch. The key never touches your config file, which is the whole point.

Values

env_key takes a string that is the name of an env var, like "OPENAI_API_KEY" or "DEEPSEEK_API_KEY". No default, so on a custom provider block it’s blank until you set it.

Key What it holds Default
env_key Name of the env var that holds the API key (a string) unset
env_key_instructions Message Codex shows when that variable is missing unset
experimental_bearer_token The token written straight into config (experimental, discouraged) unset

When to change it

  • You’re wiring up any custom provider (a local gateway, DeepSeek, Azure, an OpenRouter proxy). Set env_key to whatever variable you export for that provider’s key.
  • You want the secret out of the config file so it doesn’t land in git. env_key keeps the config holding only the variable name.
  • You’re handing the config to a teammate. Set env_key_instructions so they see a setup hint the moment the var is empty instead of a raw auth error.

Gotchas

Codex reads the variable from the process environment at launch. If you export it in .zshrc but start Codex from a GUI or an IDE that never sources that file, the variable comes back empty and you get an auth failure. Export it in the same shell you actually run codex from.

Setting env_key alone does not route you to the new provider. In issue #987 the request kept hitting OpenAI’s endpoint with the wrong key because the provider wasn’t fully switched over. You also need base_url on the block and the provider actually selected.

For rotating or short-lived tokens, skip experimental_bearer_token (it’s discouraged and puts the raw token in the file) and use the command-backed auth block. auth.command prints a fresh token to stdout, refreshed every auth.refresh_interval_ms (default 300000; set 0 to refresh only on a failed retry), with auth.timeout_ms (default 5000) capping the command.

[model_providers.custom-provider]
name = "My Custom Provider"
base_url = "https://api.example.com/v1"
env_key = "MY_PROVIDER_API_KEY"
env_key_instructions = "Obtain your API key from https://example.com/keys"

env_key_instructions and experimental_bearer_token live on the same provider block and are covered above. base_url is the other half of a working custom provider, so set it in the same table. For dynamic credentials, the auth.command / auth.args / auth.cwd group replaces env_key entirely. Full field list is in the official config reference.

Sources