Skip to content

Codex authenticates with either a ChatGPT sign-in, which draws on a ChatGPT plan’s Codex allowance and is required for Codex cloud, or an OpenAI API key, which bills per token and suits local and CI work. The Codex CLI stores the credential in ~/.codex/auth.json by default, and codex login status and codex doctor confirm which method is active.

You installed Codex, ran codex, and the sign-in screen offers ChatGPT, a device code, and an API key. On your laptop the choice takes a second. On a build server with no browser, in a Docker container, or in a GitHub Actions job, the wrong choice shows up later as a CI step that says “Not logged in” while the agent runs fine, or as codex cloud refusing to start.

This page is for the developer setting up Codex on a laptop, a remote box, or a CI runner, and for the tech lead who wants every machine on the team signed in the same, checkable way. Every command and message below was checked against Codex CLI 0.157.1 on 2026-09-26. Install Codex first with the installation guide.

  • A decision on ChatGPT sign-in versus API key, made on billing and on the features each one unlocks.
  • Credentials stored where your security policy wants them: a file, the OS keyring, or memory only.
  • A working sign-in on machines without a browser: SSH sessions, containers, and CI runners.
  • A two-command check that proves which method is active, so nobody has to guess.
  • A team-wide rule that pins the login method and the ChatGPT workspace.

Which Codex sign-in method should you choose?

Section titled “Which Codex sign-in method should you choose?”

Pick by who pays and which features you need. The sign-in screen in 0.157.1 offers Sign in with ChatGPT, Sign in with Device Code, Provide your own API key, and Amazon Bedrock for organizations that route Codex through AWS.

SituationUseWhy
You have a ChatGPT Plus, Pro, Business, Edu, or Enterprise planChatGPT sign-inCodex usage comes out of the plan’s allowance, and cloud tasks, /usage, and remote control work
A machine with no browser, and you want your ChatGPT planDevice codeSame account as ChatGPT sign-in; you finish the sign-in on any other device
A CI job or script calling codex execAPI key in CODEX_API_KEYUsage-based billing on your OpenAI Platform account, no personal session on a shared runner
You want Codex costs separate from any ChatGPT planAPI keyOne bill per API organization and its policies
Your company runs models through AWSAmazon BedrockSee the enterprise governance guide

OpenAI’s pricing page (read 2026-10-12) also lists Free and Go plans, for which it names only “GPT-6 Luna at Standard speed in the desktop app, subject to rollout”; the plan table on Codex credits, usage limits and cost optimization lists every plan and what it includes. For an API key, the page says “No cloud-based features”. Since 0.161.0 (2026-10-07), API-key model discovery is on by default (api_key_model_discovery is stable and on in 0.162.1), so a pipeline that logs in with an API key can behave differently from an older pin; re-run its smoke test after you upgrade.

An API key does not unlock everything. In Codex CLI 0.157.1, these features refuse API-key auth and ask for a ChatGPT sign-in:

  • codex cloud (“Not signed in. Please run ‘codex login’ to sign in with ChatGPT”).
  • Remote control (“remote control requires ChatGPT authentication; API key auth is not supported”).
  • The remote plugin catalog and shared plugins.
  • /usage and rate-limit readouts in the terminal UI.

The model you get depends on the plan or API organization, not on the sign-in screen. The models hub lists what Codex runs by default and what each model costs.

Run this in a terminal on a machine with a browser:

Terminal window
codex login

Codex starts a local callback server on 127.0.0.1:1455, opens the browser, and stores the returned tokens when you finish signing in. Running codex with no credentials shows the same choice in the terminal UI.

The desktop app and the IDE extension offer sign-in on their own screens. The CLI and the IDE extension read credentials from the same CODEX_HOME directory (default ~/.codex), so one sign-in serves both as long as CODEX_HOME matches.

Now check the result instead of assuming it:

  1. Ask Codex which method it holds. The exit code is 0 when signed in and 1 when not, so scripts can branch on it:

    Terminal window
    codex login status

    Expect Logged in using ChatGPT, or Logged in using an API key - followed by the key with its middle masked. The message goes to stderr, so redirect with 2>&1 when you capture it.

  2. Run the diagnosis. The auth row names the source of the credentials, including keys that come from the environment, which codex login status does not see:

    Terminal window
    codex doctor --summary
  3. For an onboarding ticket or a support case, save the redacted report and attach it:

    Terminal window
    codex doctor --json > codex-doctor.json
  4. If you chose ChatGPT sign-in and need cloud tasks, confirm them from the terminal. codex cloud list prints your cloud tasks without opening the TUI, and a task list, even an empty one, proves the cloud side accepts your account:

    Terminal window
    codex cloud list

The tech lead signs off on the codex doctor --json file, not on a screenshot of a sign-in page: the auth row and the version are in it, and the report redacts secrets.

The cli_auth_credentials_store key in ~/.codex/config.toml decides. The default is file.

~/.codex/config.toml
cli_auth_credentials_store = "auto"
ValueWhere credentials liveUse it when
file (default)$CODEX_HOME/auth.jsonYou need the credential to survive reboots on a machine without a keyring
keyringmacOS Keychain, Windows Credential Manager, or Linux Secret ServiceYour laptop has an unlocked keyring and you want no token file on disk. Codex fails if the keyring is unavailable
autoKeyring when available, otherwise auth.jsonMost laptops: the keyring where it works, a file where it does not
ephemeralMemory, for the current process onlyShared or short-lived machines where nothing may be written to disk

Sign in to Codex over SSH, in a container, or on a headless server

Section titled “Sign in to Codex over SSH, in a container, or on a headless server”

The browser sign-in needs the browser to reach Codex’s callback server on localhost:1455. On a remote machine it cannot, so use one of these.

Run this on the remote machine:

Terminal window
codex login --device-auth

Codex prints a URL and a one-time code. Open the URL on any device, sign in, and enter the code. The device code expires after 15 minutes. If Codex reports that device code login is not enabled, use SSH port forwarding instead.

Authenticate Codex in CI without a personal session

Section titled “Authenticate Codex in CI without a personal session”

A CI runner must never hold a developer’s ChatGPT session. Give codex exec an API key through the CODEX_API_KEY environment variable, read from the CI platform’s secret store, and keep nothing on disk. The Codex CI/CD guide covers the openai/codex-action GitHub Action; this is the shell-level pattern it builds on.

.github/workflows/codex-check.yml
name: codex-check
on: pull_request
permissions:
contents: read
jobs:
codex:
# Skip pull requests from forks: they get no secrets
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
persist-credentials: false
- run: npm install -g @openai/codex@0.157.1
- name: Check Codex sees a credential
env:
CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }}
run: |
codex doctor --summary --no-color > doctor.txt || true
grep -E '✓ auth' doctor.txt
- name: Read-only review
env:
CODEX_API_KEY: ${{ secrets.CODEX_API_KEY }}
run: |
codex -c cli_auth_credentials_store=ephemeral \
-c default_permissions=":read-only" \
exec --ephemeral \
"Summarize the risk in this pull request's diff against origin/main. Do not modify files."

on: pull_request does not pass repository secrets to pull requests from forks, which is what you want: a fork’s code never runs next to your key. The if: line skips fork pull requests outright, so the job runs only for branches pushed by people who already have write access. Do not switch it to pull_request_target to get secrets for forks. The job trusts branches from people with write access; a branch can still change project .codex/ config and AGENTS.md, so keep the agent step read-only and require review before merging workflow or .codex/ changes. --ephemeral keeps the session off the runner’s disk, and cli_auth_credentials_store=ephemeral keeps any credential in memory. The doctor step ignores the command’s exit code because other rows, such as network reachability, can fail on a runner while auth is fine. Use codex doctor, not codex login status, to check a key supplied this way: codex login status reports Not logged in for keys that come from the environment, while the doctor auth row reports auth is provided by environment. The auth row confirms a key is present, not that OpenAI accepts it; the exec step is what fails on a revoked or mistyped key. The agent step selects the built-in :read-only permission profile (beta), which OpenAI prefers over the legacy --sandbox flag; do not add --sandbox next to it, because the two systems do not compose. See Codex configuration.

The requirement list at the end is your acceptance check: each requirement maps to a line, so you check seven lines, not the whole file.

For a single machine or a shared base config, pin the method and the workspace in config.toml:

# ~/.codex/config.toml, or a config your team distributes
forced_login_method = "chatgpt" # or "api"
forced_chatgpt_workspace_id = "00000000-0000-0000-0000-000000000000"

If the stored credential does not match, Codex logs the user out and says why, for example “ChatGPT login is required, but an API key is currently being used. Logging out.” A user can edit their own config.toml, so for organization-wide rules, administrators set allowed_login_methods and allowed_chatgpt_workspaces in the managed requirements.toml. The enterprise governance guide covers managed configuration.

The browser never returns to the terminal (WSL, SSH, containers). The browser cannot reach localhost:1455 on the machine running Codex. Cancel, then use codex login --device-auth or the SSH forwarding above.

“Port … is already in use”. Both callback ports, 1455 and the fallback 1457, are taken, usually by stale codex login processes. Codex has already tried to cancel the previous sign-in. Close terminals still running a sign-in (or kill the process holding the port) and run codex login again.

“device code login is not enabled for this Codex server”. Device-code sign-in is off for this account or server. Use SSH port forwarding, or ask your workspace admin whether the setting is available to you.

“device auth timed out after 15 minutes”. Run codex login --device-auth again and enter the new code promptly.

“Your access token could not be refreshed”. The session expired, or you signed in to another account elsewhere. Run codex logout, then codex login.

Codex logs you out on start with “ChatGPT login is required, but an API key is currently being used”. A forced_login_method rule does not match your credential. Sign in with the method the rule asks for. Change the rule only if you own it.

“API key login is disabled by this workspace”. Your admin allows only ChatGPT sign-in. Run codex login and choose ChatGPT.

keyring storage fails on a headless Linux box. No Secret Service is running, and keyring fails rather than falling back. Set cli_auth_credentials_store = "auto", or "ephemeral" on shared machines.

Signed in in one terminal, “Not logged in” in another. The two shells use different CODEX_HOME values. Run echo "$CODEX_HOME" in both and make them match, or unset it to use ~/.codex.

codex login status fails in CI although the job works. The key comes from CODEX_API_KEY, which login status does not report. Check with codex doctor --summary as in the CI example.

codex cloud says “Not signed in” while local work runs. You are on an API key. Cloud tasks need ChatGPT sign-in: run codex login and choose ChatGPT.

For errors after sign-in, such as rate limits or sandbox denials, see Codex error recovery.

Did this guide help you?

One tap, no sign-in.

not at all a lot