Blog

Codex CLI Credentials: Login Modes, auth.json Storage, and Headless Setup

Codex CLI credential questions come in three shapes: which login mode you are using, where that credential is stored, and which one is active right now. Each answer changes billing, security, and troubleshooting.

Codex CLI Credentials: Login Modes, auth.json Storage, and Headless Setup

Every Codex CLI credential problem reduces to three questions. Which login mode are you using? Where is that credential stored? And which method is actually active right now? The answers decide how the work gets billed, what your security review should look like, and which troubleshooting path applies. The official authentication documentation lays out all three paths and their storage behavior, and this article organizes them into the practical picture. It is the deliberate counterpart to the Claude Code credential priorities we covered earlier; together the two pieces form the credential reference for a two-agent toolchain, and neither one repeats the other's mechanics. If you are setting up from scratch rather than auditing an existing machine, the tool setup guide is the better starting point.

The three sign-in paths

Codex supports two ways for a person to sign in when using OpenAI models: Sign in with ChatGPT for subscription access, and Sign in with an API key for usage-based access. Both are available in the desktop app, the CLI, and the IDE extension; Codex cloud requires signing in with ChatGPT. A third path exists for enterprise automation: Codex access tokens, covered below.

The choice is not cosmetic. According to the official authentication documentation, the sign-in method determines which admin controls and data-handling policies apply: ChatGPT sign-in follows your ChatGPT workspace permissions, role-based access control, and Enterprise retention and residency settings, while API key usage follows your API organization's retention and data-sharing settings instead. If your organization audits data flows, that single sentence decides which conversation you have with your compliance team.

The CLI default is the browser flow: run codex login and complete the browser step. When no valid session is available, this is the path Codex offers first.

Codex CLI API key login, and what it bills

The API key path is designed for machines and pipelines more than for humans. Rather than accepting the key as a command-line argument, where it would land in shell history and process lists, Codex reads it from standard input:

printenv OPENAI_API_KEY | codex login --with-api-key

This single command is the codex login with API key flow, and the billing implications are the part worth reading twice. OpenAI bills API key usage through your OpenAI Platform account at standard API rates, and Codex uses standard API pricing instead of included ChatGPT plan credits. In other words, signing in this way moves you from a subscription world into a metered world, with pricing details on the official pricing page rather than in this article. Feature coverage also shifts: the documentation notes that some features relying on ChatGPT workspace access or cloud services are limited or unavailable under API key authentication, and that certain plugins are unavailable because their connection flows require OAuth capabilities that this mode does not provide.

Where this mode shines is automation. The documentation says directly: use API key authentication for programmatic Codex CLI workflows, such as CI/CD jobs, and don't expose Codex execution in untrusted or public environments.

Codex CLI credentials on disk: four storage modes

Once you sign in, the credential is cached. The documentation is explicit that Codex caches login details locally in a plaintext file at ~/.codex/auth.json or in your operating system's credential store, and that the CLI and the IDE extension share the same cached login details. If you remember one sentence from this article, make it the documentation's own: if you use file-based storage, treat ~/.codex/auth.json like a password, because it contains access tokens. Don't commit it, paste it into tickets, or share it in chat.

Where the cache lands is configurable through cli_auth_credentials_store in the configuration. Four modes are documented:

  • file stores credentials in auth.json under CODEX_HOME, which defaults to ~/.codex.
  • keyring stores them in the operating system credential store, and fails if that store is unavailable, rather than silently falling back.
  • auto uses the OS credential store when available and otherwise falls back to auth.json.
  • ephemeral keeps credentials in memory only for the current process, which suits throwaway environments where nothing should persist to disk.

The complete schema lives in the configuration reference. One governance detail matters for managed fleets: administrators can enforce cli_auth_credentials_store through local authentication requirements, and users cannot override the enforced value via config.toml or CLI flags. If your platform team wants the OS credential store to be the only acceptable home for the Codex auth.json class of secrets, that switch exists, and it is not advisory.

Checking which login is active

Two commands answer the state question: codex login status reports the active authentication method, and codex logout clears stored credentials. In the desktop app and the IDE extension, the profile menu shows the active account or API key status.

The shared-cache behavior explains a whole genre of team confusion. Because the CLI and the extension share the cached login, a logout from either one means the next start of the other requires a fresh sign-in. When a colleague says "it works on my machine but not theirs," a recent logout on one surface is a first-class suspect, not an edge case.

One enterprise boundary from the documentation deserves its own line: when the process environment selects workload identity, Codex rejects both codex login and codex logout, because the surrounding environment controls authentication. In that setup, the login commands are not the interface you are looking for, and that is by design.

Codex headless login: device code and fallbacks

Browser-based login assumes a browser and a working local callback. On remote or headless machines, or when local networking blocks the localhost callback that returns the OAuth token to the CLI, that assumption breaks. The documentation's preferred answer is device code authentication, currently labeled beta:

  1. Enable device code login in your ChatGPT security settings for a personal account, or in workspace permissions if an administrator manages the workspace.
  2. In the terminal running Codex, pick Sign in with Device Code in the interactive login UI, or run the dedicated command directly: codex login --device-auth.
  3. Open the printed link in a browser, sign in, and enter the one-time code.

If device code login is not available in your environment, two fallbacks are documented. The first is to authenticate on a machine that has a browser and copy the cached credentials to the headless host, via scp or directly into a container; the documentation repeats the password-grade warning for the copied file, and notes this method may not apply when your OS stores credentials in a credential store instead of the file. The second is to forward the CLI's local callback port over SSH and run the standard browser flow through the tunnel. Both procedures are documented with exact steps, and both are worth re-reading on the current page before you wire them into an automated setup, since the beta status and UI wording can change.

CI/CD and automation

For pipelines, the documented default is API key authentication, with the accompanying warning not to expose Codex execution in untrusted or public environments. That maps cleanly onto the guardrail habits from the CI guide: inject credentials through the secret store, expose them only to the step that needs them, and keep them out of logs and artifacts.

There is an advanced pattern for teams that need the ChatGPT-side session in automation: a dedicated guide covers maintaining account authentication on trusted CI/CD runners, including letting Codex refresh the auth cache during normal runs and keeping the updated file for the next job. The documentation is candid that API keys remain the recommended default for automation; the advanced route exists for narrower cases, not as the easy path. If credentials rotate on a schedule in your organization, the mechanical checklist for changing them without downtime is in the provider switching guide.

Codex access tokens, mentioned earlier, are the third path: in ChatGPT Enterprise workspaces, administrators can grant the access token permission so members can create tokens for trusted, non-interactive workflows. Tokens are intended for trusted scripts, schedulers, and private CI runners, and the documentation's boundary is crisp: for general OpenAI API calls, continue to use Platform API keys.

Team-managed restrictions

Managed environments can constrain authentication at the configuration level. Two documented settings do the heavy lifting: forced_login_method accepts a value that allows only ChatGPT login or only API key login, and forced_chatgpt_workspace_id pins ChatGPT sign-ins to a specific workspace. The enforcement model is strict: if the active credentials do not match the configured restrictions, Codex logs the user out and exits. These can be supplied through legacy managed configuration as well, so on a well-run fleet the question "why did the CLI log me out at startup" may have a policy answer rather than a bug answer.

One more boundary, from the Work Cloud side: API keys and Codex access tokens do not enable Local computer access with Work Cloud. That capability rides on a ChatGPT sign-in to an eligible workspace, and no amount of token plumbing substitutes for it.

Login diagnostics

When browser login or device-code authentication fails, Codex writes a dedicated codex-login.log file under the configured log directory, and that file is what the documentation recommends for login-specific debugging, including requests from support. Before escalating, collect it; it is the difference between "login doesn't work" and a report someone can act on.

Two adjacent details save time. First, on corporate networks with a TLS proxy or private root CA, set CODEX_CA_CERTIFICATE to a PEM bundle before logging in; when it is unset, Codex falls back to SSL_CERT_FILE. The same custom CA settings apply to login, normal requests, and secure WebSocket connections, so a login failure on such a network is often the same root cause as later request failures. Second, for the error-code layer of authentication problems, the general error code guide covers the 401 family and when not to retry.

The quick reference and the security list

| Scenario | Suggested path | Where the credential lives |
| :- | :- | :- |
| Local single machine | ChatGPT login (default) | OS credential store or ~/.codex/auth.json |
| Local with API billing | API key via stdin login | Same storage, API key credential |
| Shared multi-user machine | API key with per-user CODEX_HOME, or keyring mode | User-scoped store only |
| Headless server | Device code login (beta) or documented fallbacks | File cache, password-grade |
| CI/CD | API key authentication | CI secret store, injected per step |
| Managed team | Whatever forced_login_method allows | Enforced by managed config |

Five security actions worth engraving: treat ~/.codex/auth.json like a password wherever it exists; never commit it, paste it into tickets, or share it in chat; prefer the OS credential store where policy allows; scope CI secrets to the step that needs them and avoid untrusted environments entirely; and remember that a logout on either the CLI or the extension ripples to the other. Finally, since UI wording and the beta label on device code can change, confirm details against the official authentication page and the platform's own documentation before encoding them into runbooks.