openclaw - ✅(Solved) Fix [Bug]: models auth login --provider openai-codex swallows the device-pairing code that upstream codex login prints to the terminal [2 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#74212Fetched 2026-04-30 06:27:14
View on GitHub
Comments
2
Participants
2
Timeline
13
Reactions
2
Author
Timeline (top)
cross-referenced ×3mentioned ×3subscribed ×3commented ×2

openclaw models auth login --provider openai-codex with Device Pairing Auth selected does not surface the device-pairing code in an SSH session, whereas running upstream codex login directly in the same SSH session prints it correctly.

<img width="1048" height="520" alt="Image" src="https://github.com/user-attachments/assets/f0e905f1-9fbb-4ad1-89d2-aa5c2dcc738b" />

Root Cause

  • Affected users/systems: anyone using openclaw models auth login --provider openai-codex over SSH and selecting the OpenAI Codex Device Pairing auth method on OpenClaw 2026.4.23 (only
    environment observed).
    • Severity: blocks workflow — the codex provider cannot be authenticated through this path because the pairing code is unrecoverable from the SSH session.
    • Frequency: always reproduces under the steps above on the observed setup.
    • Consequence: failed onboarding for the openai-codex provider via the Device Pairing path; the only way to complete authentication is to fall back to a different auth method or run upstream
      codex login directly.

Fix Action

Fixed

PR fix notes

PR #74221: fix(openai-codex): show device-pairing code in SSH (#74212)

Description (problem / solution / changelog)

Closes #74212.

Bug

openclaw models auth login --provider openai-codex → "OpenAI Codex Device Pairing" over SSH renders the prompt as:

Code: [shown on the local device only]

…and prints only the URL to the terminal. The user has nowhere to see the code, so the flow is unrecoverable. Upstream codex login run in the same SSH session prints the code correctly.

Root cause

extensions/openai/openai-codex-provider.ts:355 had:

const codeLine = ctx.isRemote
  ? "Code: [shown on the local device only]"
  : `Code: ${userCode}`;

The intent appears to have been "don't echo a sensitive code over an SSH wire," but OAuth device flow requires the user to see the code — that's the whole point: they read it from the device-without-a-browser and type it into the verification URL on a device-with-a-browser. In an SSH session the terminal is the only place the user sees output; there is no "local device" to fall back to. Hiding the code makes the flow unusable.

The runtime-log fallback for isRemote also only printed the URL, not the code.

Fix

  • Always include Code: <userCode> in the prompter note (drop the isRemote branch on the code line).
  • Append Code: <userCode> to the runtime.log fallback alongside the verification URL.

Behaviour now matches upstream codex login in SSH sessions.

await ctx.prompter.note(
  [
    ctx.isRemote
      ? "Open this URL in your LOCAL browser and enter the code below."
      : "Open this URL in your browser and enter the code below.",
    `URL: ${verificationUrl}`,
    `Code: ${userCode}`,
    `Code expires in ${expiresInMinutes} minutes. Never share it.`,
  ].join("\n"),
  "OpenAI Codex device code",
);
if (ctx.isRemote) {
  ctx.runtime.log(
    `\nOpen this URL in your LOCAL browser:\n\n${verificationUrl}\n\nCode: ${userCode}\n`,
  );
  return;
}

Security note

The pairing code is short-lived (~15 min), single-use, and useless without the user-controlled verification URL flow. Not exposing it is what blocks legitimate use; it doesn't add meaningful security. Same posture upstream codex login ships with.

Test

Existing test does not log the device pairing code in remote mode asserted the broken behaviour (note must contain [shown on the local device only], runtime.log must NOT contain the code). Renamed and inverted to:

surfaces the device pairing code in remote (SSH) mode (#74212)

Asserts:

  • runtime.log contains the verification URL and CODE-12345
  • prompter.note contains Code: CODE-12345
  • prompter.note does not contain [shown on the local device only]
$ npx vitest run extensions/openai/openai-codex-provider.test.ts
✓ extension-provider-openai .../openai-codex-provider.test.ts (28 tests)
Test Files 1 passed (1) | Tests 28 passed (28)

28/28, no regressions.

Changed files

  • extensions/openai/openai-codex-provider.test.ts (modified, +9/-4)
  • extensions/openai/openai-codex-provider.ts (modified, +10/-5)

PR #74258: fix(openai-codex): surface device-pairing code without logging it (#74212)

Description (problem / solution / changelog)

Summary

  • Problem: openclaw models auth login --provider openai-codex (Device Pairing auth) renders the device code as Code: [shown on the local device only] in the prompter note, which makes the OAuth flow unrecoverable in any session that has no other surface — over SSH, the SSH terminal is the local device, so there is nowhere else for the code to appear.
  • Why it matters: this is the only auth path for the openai-codex provider for users who don't ship an OPENAI_API_KEY (e.g. ChatGPT subscription users on a remote/headless host).
  • What changed: in extensions/openai/openai-codex-provider.ts, the prompter.note payload now always includes Code: ${userCode} regardless of ctx.isRemote. The note is the user-facing TTY surface — the same surface upstream codex login writes to in the same SSH session.
  • What did NOT change (scope boundary): the ctx.runtime.log(...) line in the isRemote branch is left exactly as it was — it still emits only the verification URL, never the user code. runtime.log is the persistent diagnostic logger; device codes must not land there. The "LOCAL browser" intro copy in the note is unchanged.

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • Auth / tokens

Linked Issue/PR

  • Closes #74212
  • Related #74221 — alternative fix for the same symptom that adds the user code to ctx.runtime.log(...), which regresses the existing does not log the device pairing code in remote mode assertion. This PR keeps that boundary intact.
  • This PR fixes a bug or regression

Root Cause

  • Root cause: extensions/openai/openai-codex-provider.ts:355-357 masked the device code in the prompter.note payload whenever ctx.isRemote was true. The intent appears to have been "don't echo a sensitive code over an SSH wire," but OAuth device flow requires the user to read the code from the same device that initiated the flow — over SSH, that device is the SSH terminal. Hiding the code there makes the flow unusable, with no fallback surface.
  • Missing detection / guardrail: there was no test asserting the prompter note actually contains the user code in remote mode. The existing test only asserted the inverse (that runtime.log does not contain the code) — a security guard that this PR preserves.
  • Contributing context: upstream codex login prints the code in the terminal in the same SSH session correctly; only OpenClaw's wrapper masks it.

Regression Test Plan

  • Coverage level: [x] Unit test
  • Target test or file: extensions/openai/openai-codex-provider.test.ts
  • Scenario the test should lock in: in isRemote: true mode, the prompter note must contain the literal Code: <userCode> (no masking placeholder), AND the runtime log must not contain the user code.
  • Why this is the smallest reliable guardrail: both invariants are verifiable via the existing loginOpenAICodexDeviceCode mock; a unit test is the same level of coverage the previous (broken) behavior was already specified at.
  • The previous single test does not log the device pairing code in remote mode was split into two focused tests so the prompter and the log are guarded independently:
    • surfaces the device pairing code via the prompter note in remote (SSH) mode (#74212)
    • does not write the device pairing code to the runtime log in remote mode

User-visible / Behavior Changes

When running openclaw models auth login --provider openai-codex and selecting OpenAI Codex Device Pairing in remote mode (e.g. SSH), the device code is now printed in the prompter note (the terminal). Previously the code field was masked as [shown on the local device only]. The runtime log surface is unchanged and continues to print only the verification URL.

Diagram

Before (remote mode, e.g. SSH):
  prompter.note → URL: <url>, Code: [shown on the local device only]
  runtime.log   → URL: <url>
  → user has no surface from which to retrieve the code

After (remote mode, e.g. SSH):
  prompter.note → URL: <url>, Code: <userCode>
  runtime.log   → URL: <url>                ← intentionally unchanged
  → user reads the code from the same terminal upstream `codex login` writes to

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No — the device code is short-lived (~15 min), single-use, and the only change in handling is to surface it on the existing user-facing TTY surface (not on a persistent surface). The persistent runtime.log surface is intentionally untouched and a dedicated test now guards that boundary.
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Debian GNU/Linux 12 (bookworm) on the host where the bug was filed
  • Runtime/container: OpenClaw 2026.4.23, npm global install
  • Model/provider: openai-codex
  • Integration/channel: N/A
  • Relevant config: default (no OPENAI_API_KEY in env)

Steps

  1. SSH into a host running OpenClaw.
  2. Run openclaw models auth login --provider openai-codex.
  3. Select OpenAI Codex Device Pairing.

Expected

  • The prompter note prints both the verification URL and the device code; the user can complete the flow over SSH the same way upstream codex login allows.

Actual (without this PR, on main)

  • The prompter note prints Code: [shown on the local device only] and the user has no other surface to retrieve the code from.

Evidence

  • Failing → passing test: the previous test does not log the device pairing code in remote mode asserted note was called with [shown on the local device only]. Replaced with surfaces the device pairing code via the prompter note in remote (SSH) mode (#74212) which asserts the inverse and now passes after the source change. The log-hygiene assertions remain in a separate test that passes both before and after.
  • pnpm test:extension openai → 22 test files, 204 tests, all passing.
  • pnpm build → clean.
  • pnpm check (lint + policy guards + cycle check) → exit 0.

Human Verification (required)

  • Verified scenarios:
    • pnpm test:extension openai locally, both new tests reported .
    • Inspected extensions/openai/openai-codex-provider.ts:348-379 after the change: the only modified surface is the prompter.note payload; the ctx.runtime.log(...) calls are byte-identical to main.
    • Confirmed the LOCAL/non-LOCAL browser intro copy on the note is untouched.
  • Edge cases checked: the local (non-isRemote) branch was not modified — its behavior is preserved. The split tests share a runRemoteDeviceCodeAuthFlow helper so both exercise the exact same call path.
  • What I did not verify:
    • End-to-end against a real ChatGPT subscription account — codex auth is the subject of the bug, so no live codex login was performed from this environment.
    • codex review --base origin/main (recommended by CONTRIBUTING) for the same reason; happy to run it once Codex auth is available.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes — same auth flow surfaces, same data shape, same persisted credentials.
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: a future change adds the user code to a persistent surface (e.g. runtime.log), reintroducing the boundary issue.
    • Mitigation: the second new test (does not write the device pairing code to the runtime log in remote mode) and its accompanying comment explicitly guard this invariant.

AI-assisted disclosure (per CONTRIBUTING §"AI/Vibe-Coded PRs Welcome"):

  • Marked AI-assisted: this PR was authored with assistance from Claude (Anthropic).
  • Degree of testing: fully tested locally — pnpm test:extension openai, pnpm build, pnpm check all pass.
  • I confirm I understand what the code does.
  • codex review --base origin/main was not run locally — codex auth itself is the subject of the bug being fixed, and no codex auth is set up in this environment. Happy to re-run if a maintainer can point me at an alternative.

Changed files

  • extensions/openai/openai-codex-provider.test.ts (modified, +21/-6)
  • extensions/openai/openai-codex-provider.ts (modified, +4/-4)
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

openclaw models auth login --provider openai-codex with Device Pairing Auth selected does not surface the device-pairing code in an SSH session, whereas running upstream codex login directly in the same SSH session prints it correctly.

<img width="1048" height="520" alt="Image" src="https://github.com/user-attachments/assets/f0e905f1-9fbb-4ad1-89d2-aa5c2dcc738b" />

Steps to reproduce

  1. SSH into a remote host running OpenClaw 2026.4.23.
  2. Run openclaw models auth login --provider openai-codex and select OpenAI Codex Device Pairing.
  3. Observe the Code: field renders as [shown on the local device only] with no code printed anywhere in the SSH session (see attached screenshot).

Expected behavior

Running codex login directly in the same SSH session prints the device-pairing code in the terminal, so the openclaw wrapper is expected to surface it the same way (or otherwise make it retrievable in the SSH session).

Actual behavior

The Code: field in the device-pairing prompt renders as the literal string [shown on the local device only] and no code is printed elsewhere in the SSH session output (see attached screenshot); the flow then proceeds to Waiting for device authorization… with no recoverable code.

<img width="1048" height="520" alt="Image" src="https://github.com/user-attachments/assets/8f3cdf1e-c000-4b4a-b453-0da6435c422a" />

OpenClaw version

2026.4.23

Operating system

Debian GNU/Linux 12 (bookworm)

Install method

npm global

Model

codex/gpt-5.4

Provider / routing chain

openclaw -> codex harness

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

  • Affected users/systems: anyone using openclaw models auth login --provider openai-codex over SSH and selecting the OpenAI Codex Device Pairing auth method on OpenClaw 2026.4.23 (only
    environment observed).
    • Severity: blocks workflow — the codex provider cannot be authenticated through this path because the pairing code is unrecoverable from the SSH session.
    • Frequency: always reproduces under the steps above on the observed setup.
    • Consequence: failed onboarding for the openai-codex provider via the Device Pairing path; the only way to complete authentication is to fall back to a different auth method or run upstream
      codex login directly.

Additional information

No response

extent analysis

TL;DR

The issue can be worked around by running the codex login command directly in the SSH session to print the device-pairing code.

Guidance

  • The problem seems to be related to the OpenClaw wrapper not surfacing the device-pairing code in the SSH session, while running codex login directly works as expected.
  • To verify the issue, try running codex login directly in the SSH session and check if the device-pairing code is printed.
  • As a temporary workaround, users can run codex login directly in the SSH session to obtain the device-pairing code.
  • The OpenClaw wrapper may need to be modified to handle the device-pairing code correctly in SSH sessions.

Notes

The issue appears to be specific to OpenClaw version 2026.4.23 and the openclaw models auth login --provider openai-codex command with Device Pairing Auth selected.

Recommendation

Apply workaround: run codex login directly in the SSH session to obtain the device-pairing code, as this allows users to complete the authentication process despite the issue with the OpenClaw wrapper.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Running codex login directly in the same SSH session prints the device-pairing code in the terminal, so the openclaw wrapper is expected to surface it the same way (or otherwise make it retrievable in the SSH session).

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: models auth login --provider openai-codex swallows the device-pairing code that upstream codex login prints to the terminal [2 pull requests, 2 comments, 2 participants]