You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reauthenticate the native Codex App login (__main__, $CODEX_HOME/auth.json) from the OpenCodex WebUI on a headless hub (Docker/k3s, no local Codex App, oauthOpenBrowser: false).
This is not client pairing (ocx connect / pairing grant). Pairing only attaches a client to the hub. The native ChatGPT/Codex grant on the hub itself can become unusable for WHAM quota (token_revoked) even after a successful stored-token refresh, and an operator then needs a new device login that writes the native main slot — the same way pool rows already work after #3366/#3369/#3385.
What prevents this today?
On Codex Auth the main card is a locked App login identity. When reauth is needed it only shows codexAuth.mainTokenExpired ("Token expired — sign in again via Codex App login"). There is no Re-login / device-code control on that card (gui/src/components/codex-account-pool-main-card.tsx).
The WebUI device flow (POST /api/codex-auth/login with device: true) is pool-only:
{ id: "__main__", reauth: true, device: true } → 400 Invalid account id format
{ id: "main", reauth: true, device: true } → 404 Unknown pool account for reauth
{ reauth: true, device: true } → 400 id required for reauth
{ device: true } with no id → starts a new pool account add
Pool rows can Re-login through the same modal (gui/src/components/use-add-codex-account-oauth.ts). That is the correct tool for extra ChatGPT accounts, not for replacing native __main__.
The documented native path is ocx account main add / /api/native-main-profiles/*, which launches official codex login in a staging home and needs the OS keyring. On the published hub image that path is not usable: codex is not on PATH, and GET /api/native-main-profiles/doctor reports keyStore: unavailable, vaultStatus: missing, profileCount: 0.
#3417 tracks exposing native-main profiles in the WebUI (list/register/switch/recover). That issue explicitly says a browser cannot run official codex login itself, and new-profile enrollment is a follow-up. It does not cover deviceauth reauth of the existing __main__ grant on a container hub that has no Codex App and no codex binary.
#3366 closed the pool deviceauth gap. Native main was left on "use Codex App".
What should OpenCodex do?
Give the Codex Auth main card a device-login reauth that overwrites native __main__ / $CODEX_HOME/auth.json, visually separate from pool Add / pool Re-login.
Suggested contract:
Reuse the existing OpenAI deviceauth grant already used for pool add (loginChatGPTDevice / auth.openai.com/codex/device).
Persist tokens to the native main slot, not as a 13th pool account.
Refuse to treat __main__ as a pool id in /api/codex-auth/login (keep that 400), and instead add an explicit native-main device reauth route or a documented ocx account main reauth --device that the GUI can start/poll/cancel.
Do not require official codex on PATH or an OS keyring for this one operation on runtimeRole=hub.
Keep tokens, emails, and raw account ids out of GUI payloads/logs; show only URL + device code + status.
Until that exists, headless operators have no first-party way to recover a WHAM-revoked native grant without adding a pool account by mistake or copying auth.json from a workstation.
Example usage or interface
Codex Auth
Main account (App login)
[Re-login with device code] ← missing today
copy: open https://auth.openai.com/codex/device and enter ABCD-12345
Account pool
[Add] ← exists; must stay a new pool row
row → [Re-login] ← exists; must not target __main__
Live check: stored refresh grant still produces a fresh access JWT via getValidMainAccountToken(); WHAM GET https://chatgpt.com/backend-api/wham/usage then returns HTTP 401 token_revoked. A paused pool account on the same process/proxy/headers returns WHAM 200, so this is grant invalidation, not a broken quota probe.
Area
Dashboard / Authentication and account pool
What are you trying to accomplish?
Reauthenticate the native Codex App login (
__main__,$CODEX_HOME/auth.json) from the OpenCodex WebUI on a headless hub (Docker/k3s, no local Codex App,oauthOpenBrowser: false).This is not client pairing (
ocx connect/ pairing grant). Pairing only attaches a client to the hub. The native ChatGPT/Codex grant on the hub itself can become unusable for WHAM quota (token_revoked) even after a successful stored-token refresh, and an operator then needs a new device login that writes the native main slot — the same way pool rows already work after #3366/#3369/#3385.What prevents this today?
On Codex Auth the main card is a locked App login identity. When reauth is needed it only shows
codexAuth.mainTokenExpired("Token expired — sign in again via Codex App login"). There is no Re-login / device-code control on that card (gui/src/components/codex-account-pool-main-card.tsx).The WebUI device flow (
POST /api/codex-auth/loginwithdevice: true) is pool-only:{ id: "__main__", reauth: true, device: true }→400 Invalid account id format{ id: "main", reauth: true, device: true }→404 Unknown pool account for reauth{ reauth: true, device: true }→400 id required for reauth{ device: true }with no id → starts a new pool account addPool rows can Re-login through the same modal (
gui/src/components/use-add-codex-account-oauth.ts). That is the correct tool for extra ChatGPT accounts, not for replacing native__main__.The documented native path is
ocx account main add//api/native-main-profiles/*, which launches officialcodex loginin a staging home and needs the OS keyring. On the published hub image that path is not usable:codexis not onPATH, andGET /api/native-main-profiles/doctorreportskeyStore: unavailable,vaultStatus: missing,profileCount: 0.#3417 tracks exposing native-main profiles in the WebUI (list/register/switch/recover). That issue explicitly says a browser cannot run official
codex loginitself, and new-profile enrollment is a follow-up. It does not cover deviceauth reauth of the existing__main__grant on a container hub that has no Codex App and nocodexbinary.#3366 closed the pool deviceauth gap. Native main was left on "use Codex App".
What should OpenCodex do?
Give the Codex Auth main card a device-login reauth that overwrites native
__main__/$CODEX_HOME/auth.json, visually separate from pool Add / pool Re-login.Suggested contract:
loginChatGPTDevice/auth.openai.com/codex/device).__main__as a poolidin/api/codex-auth/login(keep that 400), and instead add an explicit native-main device reauth route or a documentedocx account main reauth --devicethat the GUI can start/poll/cancel.codexon PATH or an OS keyring for this one operation onruntimeRole=hub.Until that exists, headless operators have no first-party way to recover a WHAM-revoked native grant without adding a pool account by mistake or copying
auth.jsonfrom a workstation.Example usage or interface
Alternatives or workarounds
__main__.ocx account main add: requires official Codex CLI + keyring; not present on the hub image.auth.jsoninto the hub volume: works, but fights hub-owned credentials and is easy to get wrong.Additional context
runtimeRole=hub,oauthOpenBrowser: false).getValidMainAccountToken(); WHAMGET https://chatgpt.com/backend-api/wham/usagethen returns HTTP 401token_revoked. A paused pool account on the same process/proxy/headers returns WHAM 200, so this is grant invalidation, not a broken quota probe.Checks