How to log in to Codex on a headless server

Sign Codex CLI in on a server with no browser using device-code login, an SSH tunnel, a copied auth.json or an API key, and keep the login usable from your phone.

Based on
CLI
0.2.17
Preview ref
a2c45c8

TL;DR

codex login starts a small callback server on the box and expects your browser to come back to localhost. On a headless server, that browser is somewhere else. Your options, in a sensible order to try them:

  1. Device code: codex login --device-auth. Open the link on any device, enter the one-time code, done. It may need a switch turned on in your ChatGPT security settings first.
  2. SSH tunnel: forward port 1455 from your laptop, then run codex login and finish the normal browser flow.
  3. Copy auth.json: sign in on a computer with a browser and copy ~/.codex/auth.json to the server.
  4. API key: for scripts and CI, where per-token billing is what you want anyway.

Check the result with codex login status.

The problem

A common setup: Codex runs on a small Linux server so long tasks keep going when the laptop sleeps. The first codex login there prints a URL. You open it on your laptop, sign in, and the last redirect lands on localhost:1455 on the laptop. Nothing is listening there, so the sign-in goes nowhere.

The fix is easy once you know which of the paths fits your account. The awkward part is that the shortest one, the device code, is off for some accounts until you change a setting.

Option 1: Log in to Codex with codex login --device-auth

On the server:

codex login --device-auth

Codex prints a link and a one-time code. Open the link in a browser on your laptop or phone, sign in to ChatGPT, and enter the code. The terminal finishes on its own. Nothing has to connect back to the server, which is why this works behind NAT and in containers.

Things to know:

  • The switch. Device-code login may need to be enabled in your ChatGPT security settings, or by an admin in the workspace settings. If the command fails right away, check that first.
  • The code is short-lived. If you get distracted, start again rather than reusing an old code.
  • Only enter codes your own terminal printed. A device code signs in whichever terminal requested it. A code someone sends you is a request to sign their computer in to your account.

Option 2: Tunnel the Codex login callback over SSH

If device codes are off and you can't change that, keep the normal browser flow and carry the callback over SSH. From your laptop:

ssh -L 1455:localhost:1455 you@server

Inside that SSH session, run codex login and open the printed URL in your laptop's browser. When the sign-in redirects to localhost:1455, the tunnel delivers it to the Codex process on the server.

If it fails:

  • Make sure nothing else on your laptop already uses port 1455.
  • Kill old codex login processes on the server before starting a new one. A stale one can hold the port.
  • codex login writes a codex-login.log file in your Codex log directory. Read it when the browser step and the terminal disagree.

Option 3: Copy Codex auth.json from a computer that has a browser

Sign in on your laptop with codex login, then copy the credentials file:

scp ~/.codex/auth.json you@server:~/.codex/auth.json

OpenAI documents this as a fallback, and it's handy for a box you rebuild often. Treat that file like a password. It signs whoever holds it in to your ChatGPT account.

If your laptop keeps Codex credentials in the OS keyring instead of auth.json, there's no file to copy. OpenAI's docs explain how to switch to file storage with cli_auth_credentials_store.

Option 4: Use an OpenAI API key for scripts and CI

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

API-key auth bills at standard API rates through your OpenAI Platform account, separate from a ChatGPT subscription. OpenAI recommends it for programmatic workflows such as CI jobs, and some ChatGPT workspace features aren't available with it.

Keep the Codex login usable from your phone

Signing in once is the easy part. The harder part is a login that expires on the server while you're away, and only finding out when a session started from your phone sits there doing nothing.

If you want to start Codex sessions on the server from your phone, see their state and approve commands without opening an SSH app, Happier is an open-source app that lets you run and orchestrate Codex, Claude Code and other agents cross-device, from your phone, desktop or the web.

The agents run on your own computers, and the phone, desktop and web apps connect to them. Run Happier from your phone covers the setup. It's on GitHub, you can download it here, and there's a Discord.

1) Install Happier on the server and pair it with your phone

curl -fsSL https://happier.dev/install | bash
happier auth login --method mobile

Scan the QR code with the Happier app on your phone and approve. The server shows up as a computer (a machine in Happier) you can start sessions on.

2) Check and refresh the Codex login from the Happier app

Open Settings → AI & Agents → AI backends → Codex, pick the server in the context bar, and read the Authentication section. It shows whether Codex is logged in on that computer and by which method.

Log in or Reauthenticate opens a Provider login terminal on the server that runs codex login. Check now refreshes the status after you've logged in some other way, for example with codex login --device-auth over SSH.

3) Store the Codex login in Happier as a connected service

Happier can also store your Codex subscription login as a connected service. It is encrypted in your Happier account and decrypted only on your own devices, so sessions on any of your computers can use it:

happier connect codex --device    # device-code flow, for a headless box
happier connect codex --paste     # fallback: paste the final redirect URL
happier connect codex --api-key   # store an OpenAI API key instead

--device uses the same device-code sign-in as option 1, so the same ChatGPT setting applies. --paste is the no-tunnel version of option 2: you sign in on your laptop, copy the URL the browser ends on, and paste it into the terminal. The account then appears under Settings → Connected services, and you can choose it when you start a Codex session.

The limit, stated once: the server still has to be on and online. Happier makes the login visible and fixable from the phone. It doesn't keep a powered-off box signed in.

Troubleshooting

codex login --device-auth fails right away

Device-code login is probably off for your account. Turn it on in your ChatGPT security settings, or ask your workspace admin. If that isn't possible, use the SSH tunnel or copy auth.json.

The Codex login browser tab can't reach localhost:1455

That's the callback trying to reach your laptop. Either open an SSH tunnel and retry, or use happier connect codex --paste and paste the URL from the address bar.

codex login status says logged in, but Codex sessions from a service fail

The service may run as a different user or with a different home directory, so it reads a different ~/.codex. Log in as the user the service runs as, or store the login as a connected service so the session receives it at start.

Codex remote control says it requires ChatGPT authentication

You're signed in with an API key. Remote control needs a ChatGPT sign-in, so use option 1, 2 or 3.

FAQ

Can I log in to Codex with no browser anywhere?

Only with an API key. Every ChatGPT sign-in path uses a browser on some device, but it can be your phone.

Is copying auth.json safe?

It works, and it's as sensitive as a password. Keep it readable only by your user, and don't commit it or bake it into a shared image.

Does device-code login work in Docker?

Yes. Because nothing calls back into the container, it fits well there.

Which subscriptions work?

A ChatGPT subscription that includes Codex, or an OpenAI API key. OpenAI's pricing page lists which subscriptions include Codex.

Get Happier

Happier is an open-source app that lets you run and orchestrate Claude Code, Codex and other agents cross-device, from your phone, desktop or the web.

codexsshlinuxheadlessself-host
Last updated: 2026-10-26