Skip to content

fix(codex): the RC pane drives sign-in and pairing itself - #180

Merged
defangdevs merged 1 commit into
masterfrom
fix/codex-pane-drives-auth
Aug 4, 2026
Merged

fix(codex): the RC pane drives sign-in and pairing itself#180
defangdevs merged 1 commit into
masterfrom
fix/codex-pane-drives-auth

Conversation

@defangdevs

Copy link
Copy Markdown
Owner

Motivation

A codex session with remoteControl = true printed the two onboarding commands and told the user to run them from "any other shell on the box — open another terminal tab, or agent-box-session add sh --agent shell". Needing a second session to get the first one working is the onboarding problem; the pane is the only thing a fresh box hands you. Follow-on to #159 (items 1 and 5), which #161 only partly addressed by making the pane report state.

What changed

codexRemoteControl now drives the flow in the pane it already owns:

  • Logged out → runs codex login --device-auth in the pane. The verification URL and one-time code print there; the command blocks polling until the browser side finishes, which is exactly the foreground behaviour the pane wants.
  • Signed in → mints and prints the pairing code for the Codex apps.
  • Enter re-runs whichever step is outstanding — normally a fresh pairing code, since codes expire quickly.
  • Typing login drops the stored credentials and re-authenticates. This is the one state Enter cannot fix: with a stale token or the wrong account, codex login status still succeeds while pairing keeps failing, and the device-auth guard (correctly) declines to run.

Supporting fixes in the same wrapper:

  • The 5s daemon health probe became a read timeout, so the pane accepts keys without dropping supervision. It exits 0 when the daemon dies exactly as before, so the reconcile loop still respawns it.
  • Reading is skipped where there is no terminal, and abandoned on EOF (Ctrl-D). Either would have spun the health loop at full tilt.
  • Pairing is retried twice (re-enabling Remote Control before the last try) instead of surfacing the enrollment race a cold daemon start loses: timed out waiting for remoteControl/pairing/start response, or pairing is unavailable until enrollment completes.

Security / safety effects

codex login --device-auth removes ~/.codex/auth.json as it starts and does not put it back if the flow is abandoned — verified on a live box, which is how the deployed box briefly lost its login during this work (restored from a backup). So it is called only behind a login status guard, never on a box that is already signed in, and the destructive re-auth path sits behind a typed word rather than the Enter that mints pairing codes. Pairing codes are short-lived and only ever printed to a pane that already requires the box's web password.

No new privileges, no new sudo rules, no network surface, no AWS/IAM/cost impact.

Checks run

Native aarch64-linux (this box), all passing:

  • nix run .#assemble (regenerated module committed)
  • nix build -L .#checks.aarch64-linux.{module-generated-up-to-date,module-single-file,multi-user,download-route,webhook-route}
  • cfn-lint aws/template.yaml (clean)

Behaviour was exercised end to end by extracting the generated wrapper and running it in a real tmux pane:

  • logged out, throwaway CODEX_HOME, real codex → pane printed the device-auth URL + code itself
  • signed in (stubbed codex) → pairing code on start; Enter minted a fresh one each time; a failing first pair was retried transparently
  • stale credentials (stubbed) → typing login dropped them, re-ran device auth, then paired
  • daemon death → wrapper exits 0 (respawn contract intact); Ctrl-D → no spin (one probe per 5s)

The sessions VM test gained a regression assertion (pane drives sign-in; no copy-paste command list, no "open a shell session" advice). It is x86_64-linux-only, so CI runs it, not this box — a NixOS test needs a same-arch KVM guest.

Still open from #159

The RC-codex singleton guard (item 4) and the initialPrompt-is-discarded caveat (item 6) are untouched.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN

A codex Remote Control session printed two commands and told the user to
open a second (shell) session to paste them. That second session is the
onboarding problem, not the fix for it: the pane is the only thing a new
box hands you, and it was a read-only status view.

The supervisor wrapper now runs the flow in the pane it already owns:
`codex login --device-auth` when the box is logged out (URL + one-time
code print right there), then `codex remote-control pair` once it isn't.
Enter re-runs whichever step is outstanding — normally minting a fresh
pairing code, since codes expire quickly.

Details worth knowing:

- `codex login --device-auth` REMOVES ~/.codex/auth.json as it starts and
  does not restore it if the flow is abandoned, so it runs only behind a
  `login status` guard. Verified on a live box: an aborted run leaves it
  logged out.
- Typing `login` is the escape hatch Enter can't be: with a stale token
  `login status` still succeeds while pairing keeps failing, so it drops
  the credentials first and re-authenticates.
- The first pairing call after a cold daemon start races enrollment
  ("timed out waiting for remoteControl/pairing/start response", or
  "pairing is unavailable until enrollment completes"); it is retried
  twice, re-enabling Remote Control before the last try, instead of
  surfacing a transient error.
- The 5s daemon health probe is now a `read` timeout, so the pane takes
  keys without dropping supervision. Reading is skipped where there is no
  terminal, and abandoned on EOF (Ctrl-D) — either would spin the loop.

Refs #159 (items 1 and 5 for codex); the RC-singleton guard and the
initialPrompt caveat there are still open.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PsqGhkpjsb4kKAdVz25xKN
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.

2 participants