Skip to content

fix(codex): harden device-code and browser OAuth sign-in#107

Merged
Aayam Bansal (aayambansal) merged 1 commit into
mainfrom
fix/codex-oauth-hardening
Jul 6, 2026
Merged

fix(codex): harden device-code and browser OAuth sign-in#107
Aayam Bansal (aayambansal) merged 1 commit into
mainfrom
fix/codex-oauth-hardening

Conversation

@aayambansal

Copy link
Copy Markdown
Member

Part of making Codex (ChatGPT-subscription) sign-in 100% reliable. Three independent reliability gaps:

Device-code fetches had no timeout. The usercode init, the poll, and the token exchange each ran with no AbortSignal, so a hung auth.openai.com socket could wedge login past the DEVICE_TIMEOUT_MS deadline. Each is now bound by OAUTH_HTTP_TIMEOUT_MS.

A transient blip aborted the whole sign-in. The poll loop failed on any status other than 403/404, so a single 429/5xx (or a network blip) killed the login. It now keeps polling on pending (403/404) and transient (429/5xx / network error) statuses until the deadline — backing off on a 429 — and only stops on a genuine terminal status. Extracted classifyDevicePollStatus() (unit-tested).

The loopback listener leaked on failure. stopOAuthServer() ran only on the browser success path, so a CSRF/denied/timeout attempt left port 1455 bound for the life of the process and blocked the next browser sign-in. It's now stopped in a finally.

Follow-ups (separate PRs): 401-triggered refresh+retry on the request path, and the explicit ChatGPT-vs-API-key sign-in branch.

Tests

test/plugin/codex-device-poll.test.ts covers the pending/transient/fail classification; the existing codex-refresh test still passes.

Three reliability gaps in the Codex (ChatGPT subscription) sign-in:

- The device-code fetches (usercode init, poll, token exchange) had no
  per-request timeout, so a hung auth.openai.com socket could wedge login
  past the DEVICE_TIMEOUT_MS deadline. Bound each with OAUTH_HTTP_TIMEOUT_MS.
- The poll loop failed on ANY status other than 403/404, so a single
  transient 429/5xx (or a network blip) aborted the whole sign-in. Keep
  polling on pending (403/404) and transient (429/5xx / network) statuses
  to the deadline, backing off on a 429; only a genuine terminal status
  ends the login. Extracted classifyDevicePollStatus() for coverage.
- The browser loopback listener was stopped only on the success path, so a
  CSRF/denied/timeout attempt leaked port 1455 for the life of the process
  and blocked the next browser sign-in. Stop it in a finally.
@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openscience Ready Ready Preview, Comment Jul 6, 2026 3:31pm

Request Review

@aayambansal Aayam Bansal (aayambansal) merged commit 9d53d94 into main Jul 6, 2026
11 checks passed
@aayambansal Aayam Bansal (aayambansal) deleted the fix/codex-oauth-hardening branch July 6, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant