Codex CLI login: ChatGPT account or API key

Codex has exactly one active credential at a time, and you choose it explicitly. That is a change worth knowing if you learned the old behavior, where an API key sitting in your environment could quietly take over the billing.

By the Continuum team. We build a workbench that runs Claude Code, Codex, and their peers, so the model rates quoted here are the ones our own cost analytics ship with.

The short version

Run codex login for the ChatGPT browser flow, which bills against your ChatGPT plan. Run printenv OPENAI_API_KEY | codex login --with-api-key to sign in with a key and pay API rates. codex login status shows which is active, codex logout clears both. On a headless box use codex login --device-auth. Checked against OpenAI docs in August 2026.

What you need to know
  • codex login uses your ChatGPT plan. It is the default path.
  • An API key is a deliberate sign-in: printenv OPENAI_API_KEY | codex login --with-api-key.
  • codex login status tells you which credential is active, and exits 0 when one exists.
  • Credentials cache to ~/.codex/auth.json or your OS credential store.
  • The CLI and the IDE extension share one cached login. Logging out of one logs out both.
  • Headless: codex login --device-auth first, SSH port forward second.

Signing in

The ChatGPT path. This is what most people want.
codex login          # opens a browser, sign in with ChatGPT
codex login status   # confirm what you actually got
codex logout         # clears BOTH ChatGPT and API-key credentials
The API-key path. Note that you pipe the key in; nothing is read implicitly.
printenv OPENAI_API_KEY | codex login --with-api-key

What each credential buys and costs, checked August 2026.

Sign-inBills asCommandCloud features
ChatGPT accountYour ChatGPT plan allowancecodex loginYes
API keyStandard API rates, per tokencodex login --with-api-keyNo
Codex access tokenWorkspace entitlementcodex login --with-access-tokenEnterprise automation

Where the credential is actually kept

Codex caches your login and reuses it. For a ChatGPT sign-in it refreshes the token automatically during use, so an active session usually keeps working without another browser round trip.

~/.codex/config.toml
# file | keyring | auto
cli_auth_credentials_store = "keyring"
ValueStores the credential in
fileauth.json under CODEX_HOME, which defaults to ~/.codex
keyringYour operating system credential store
autoThe OS store when available, otherwise auth.json
CODEX_HOME moves everything, which is how you keep two accounts apart.
mkdir -p ~/.codex-work
CODEX_HOME=~/.codex-work codex login
CODEX_HOME=~/.codex-work codex

# the directory must already exist; Codex will not create it

Everything Codex keeps lives under that root: config.toml, the cached credential, session transcripts under sessions/, skills, rules and logs. Pointing CODEX_HOME at a second directory is the supported way to run a second account, and it is what the multi-account tooling below does under the hood.

Two sign-in commands feeding one cached credential slot, which the CLI, the IDE extension and the SDK all share, with Codex cloud available only to the ChatGPT sign-in ONE ACTIVE CREDENTIAL codex login signs in with ChatGPT bills your ChatGPT plan codex login --with-api-key signs in with a key bills per token one credential ~/.codex/auth.json or the OS keyring SHARED BY CLI IDE extension SDK Codex cloud ChatGPT sign-in only codex login status says which one is active. Logging out clears both.

Signing in without a browser

The default flow opens a browser and waits for a callback on localhost:1455. Two things break that: no browser, or a network configuration that blocks the loopback callback. There are four documented answers, in order.

01

Device code, the preferred route

codex login --device-auth

Beta as of August 2026. Turn on device-code login in your ChatGPT security settings for a personal account, or in workspace permissions if an admin owns the workspace. Then open the printed link on any device and enter the one-time code. You can also pick Sign in with Device Code in the interactive login screen.

02

Forward the callback over SSH

ssh -L 1455:localhost:1455 user@remote
# then, inside that SSH session
codex login

The normal browser flow now works: the tunnel carries the callback back to the machine that has the browser.

03

Copy a credential you already have

# to a remote host
ssh user@remote 'mkdir -p ~/.codex && cat > ~/.codex/auth.json' < ~/.codex/auth.json

# into a container
CONTAINER_HOME=$(docker exec MY_CONTAINER printenv HOME)
docker exec MY_CONTAINER mkdir -p "$CONTAINER_HOME/.codex"
docker cp ~/.codex/auth.json MY_CONTAINER:"$CONTAINER_HOME/.codex/auth.json"

This only works with file-based storage. If your machine is using the OS credential store, set cli_auth_credentials_store = "file" first or there is nothing to copy.

04

Use a key or an access token for anything unattended

# API key, the normal answer for CI
printenv OPENAI_API_KEY | codex login --with-api-key

# ChatGPT Enterprise access token, for trusted workspace automation
printenv CODEX_ACCESS_TOKEN | codex login --with-access-token

A ChatGPT plan is licensed for interactive use by a person. Automation should hold its own credential regardless of how convenient the alternative looks.

Automation, keys, and the leak nobody expects

CODEX_API_KEY supplies a key for one non-interactive run.
CODEX_API_KEY="sk-..." codex exec --sandbox read-only "review the diff on this branch"

The three credential-carrying variables and what each is for.

VariableRead byUse for
CODEX_API_KEYcodex exec onlyA single non-interactive run
CODEX_ACCESS_TOKENCLI, app server, trusted automationEnterprise workspace automation
CODEX_CA_CERTIFICATEHTTPS, login and WebSocket clientsCorporate TLS interception; falls back to SSL_CERT_FILE
Behind a corporate proxy, this is usually the whole fix.
export CODEX_CA_CERTIFICATE=/path/to/corporate-root-ca.pem
codex login

When login fails

Ranked by how often it is actually the cause.

SymptomCauseFix
Browser never returns to the CLINo browser, or the loopback callback is blockedcodex login --device-auth, or forward port 1455
Works locally, fails over SSHNo browser on the remote hostDevice code, tunnel, or an API key
Asked to sign in on every launch~/.codex is not writable by your userls -ld ~/.codex, then fix ownership
Signed out of the CLI after using the IDE extensionThey share one cached loginExpected. Sign in again in either one
TLS or certificate errors during loginCorporate proxy or private root CASet CODEX_CA_CERTIFICATE to a PEM bundle
Logged out immediately at start-upforced_login_method or a workspace restriction does not matchSign in with the method your admin requires
Cloud features missingYou signed in with an API keySign in with ChatGPT; API keys have no Codex cloud
Two diagnostics that answer most of the above.
codex login status   # which credential is active
codex doctor         # installation, config, auth, runtime, git, terminal

A direct codex login run also writes codex-login.log under your configured log directory. That is the file to attach when a browser or device-code flow fails in a way the terminal output does not explain.

Managed workspaces

What an administrator can pin, usually through managed configuration.
# Only allow ChatGPT login, or only allow API key login.
forced_login_method = "chatgpt"   # or "api"

# Restrict ChatGPT logins to one workspace.
forced_chatgpt_workspace_id = "00000000-0000-0000-0000-000000000000"

If the active credential does not match those restrictions, Codex logs you out and exits. That is the intended behavior, not a bug, and it is why a fresh laptop at a managed company can refuse a login that worked at home.

Questions people ask

Run codex login. It opens a browser for the ChatGPT sign-in flow and then caches the credential, so Codex uses your existing ChatGPT plan rather than metered billing.

Pipe it in: printenv OPENAI_API_KEY | codex login --with-api-key. That stores the key as the active credential and bills at standard API rates. It is a deliberate sign-in, not something that happens because the variable is set.

Run codex login status. It reports the active authentication method and exits 0 when credentials are present, which makes it usable as a guard in scripts. Inside a session, /status shows the same context alongside the model and sandbox.

In ~/.codex/auth.json by default, or in your operating system credential store. Choose with cli_auth_credentials_store in config.toml: file, keyring, or auto. CODEX_HOME moves the whole directory.

Use codex login --device-auth, which is in beta and needs device-code login enabled on your account or workspace. Otherwise forward the callback with ssh -L 1455:localhost:1455, copy an existing auth.json, or sign in with an API key.

codex logout then codex login replaces the credential. To keep both at once, point CODEX_HOME at a second directory and sign in there, so each account has its own config root, credential and session history.

They share one cached login. Logging out from either the CLI or the extension means the next launch of the other one needs a fresh sign-in.

No. An API key covers the CLI, the SDK and the IDE extension, but not Codex cloud or the cloud-attached features such as GitHub code review and the Slack integration.

Sources

Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.

  1. Codex authentication
  2. Codex environment variables
  3. OpenAI Codex documentation
  4. ChatGPT plans and pricing
Try it

Two accounts,
side by side.

Continuum runs several ChatGPT and Claude accounts at once, each isolated, each with its own gauge.

free app · your subscriptions · local-first