Skip to content

bug: Codex API-key auth is inert — every turn 401s because nothing writes $CODEX_HOME/auth.json #2208

Description

@vybe

Summary

Trinity's Codex runtime resolves an OpenAI API key and passes it to codex exec
via the environment only. That is no longer sufficient: current Codex CLI
authenticates its wss://api.openai.com/v1/responses transport from
$CODEX_HOME/auth.json, and with only OPENAI_API_KEY set every turn fails with
repeated 401 Unauthorized and a non-zero exit.

Net effect: an API-key Codex agent cannot complete a single turn. Only
subscription agents (which already ship an auth.json, #1971) work.

Evidence

Same key, same prompt, same image, both CLI versions — reproduced while
validating #2207:

Setup Result
-e OPENAI_API_KEY=…, codex 0.139.0 (current pin) exit=1, 7x 401 Unauthorized
-e OPENAI_API_KEY=…, codex 0.147.0 exit=1, 7x 401 Unauthorized
printenv OPENAI_API_KEY | codex login --with-api-key first, then same turn exit=0, result PONG, 0x 401
ERROR codex_api::endpoint::responses_websocket: failed to connect to websocket:
HTTP error: 401 Unauthorized, url: wss://api.openai.com/v1/responses

The key itself is fine — GET /v1/models, POST /v1/responses and
POST /v1/chat/completions all return 200 with it. The failure is specific to
the CLI's websocket transport, which reads auth.json.

Not a regression from the #2207 CLI bump — 0.139.0 and 0.147.0 fail
identically, so this predates it.

Why it was invisible

  • _codex_auth_ready() accepts either an API key or an auth.json, so the
    pre-flight gate passes and the failure surfaces later as a CLI auth error.
  • responses_websockets / responses_websockets_v2 are listed as removed
    in codex features list, i.e. the transport is no longer toggleable — there
    is no flag to fall back to the HTTP path that does accept a bare env key.
  • Nothing in startup.sh or codex_runtime.py ever runs codex login
    (grep -rn "codex login" → no hits).

Proposed fix

Materialise the resolved key into $CODEX_HOME/auth.json before the first
codex exec, e.g. run codex login --with-api-key (key on stdin — the
--api-key flag is removed in current versions) once at agent start or lazily on
first use, keeping the existing subscription-auth.json path untouched and
taking precedence per #1971.

Care needed:

  • Do not clobber an existing subscription auth.json.
  • The key must reach the CLI on stdin, never argv (process listing).
  • CODEX_HOME is under $TMPDIR and wiped on recreate, so this must be
    idempotent per container start.

Acceptance Criteria

  • An agent with only OPENAI_API_KEY in its .env completes a real chat and
    task turn (currently: 401 on every turn).
  • A subscription agent with an existing auth.json is unaffected.
  • The key never appears in argv, logs, or an error body.
  • Regression test covering "env key present, no auth.json" reaching a
    successful turn.

Technical Notes

  • docker/base-image/agent_server/services/codex_runtime.py
    _load_api_key_with_source, _codex_auth_ready, _codex_home, _execute_codex
  • docker/base-image/startup.sh — the other candidate home for the login step

Found while verifying #2207 (AC #10); that issue is scoped to model/pricing and
deliberately does not fix this.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions