Codex mobile remote access can reuse revoked enrollment and connect to the wrong Mac

Open 💬 3 comments Opened May 18, 2026 by Shijie-Hotone
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

Codex mobile remote access can enter a cross-host stale state with two Macs on the same ChatGPT account/workspace:

  • Mac A shows Codex mobile / remote access as connected or successfully set up.
  • The iPhone ChatGPT app shows or connects to Mac B instead.
  • Re-running mobile setup / scanning a new QR code on Mac A does not replace the stale enrollment.
  • Codex Desktop keeps reusing a revoked remote-control client and repeatedly reconnects to the wrong remote-control host.

This makes Mac A impossible to pair from the UI even though setup appears successful.

Environment

  • Codex App for macOS: 26.513.31313
  • macOS: 26.5, build 25F71
  • ChatGPT mobile: latest available from App Store as of 2026-05-19
  • Account/workspace: same ChatGPT account and workspace on both Macs and the iPhone
  • Setup: two Mac hosts, both used with Codex mobile remote access

Expected behavior

Each Mac should have an independent Codex mobile remote-control enrollment / host identity.

When setting up mobile access on Mac A:

  • Mac A should generate or use an enrollment for Mac A.
  • The iPhone should show Mac A as the connected host.
  • If a previous enrollment is revoked, Codex should discard it and force a fresh setup.
  • A stale or revoked enrollment from Mac B should not make Mac A appear connected.

Actual behavior

Mac A shows mobile access as connected / set up, but the iPhone shows the connected host as Mac B.

Mac A repeatedly tries to use a stale enrollment and wrong remote-control:<env> host. The local state had:

  • electron-remote-control-client-enrollments
  • added-remote-control-env-ids
  • selected-remote-host-id
  • remote-connection-auto-connect-by-host-id
  • remote-projects
  • codex-mobile-has-connected-device
  • electron-local-remote-control-installation-id

The remote project shown on Mac A was from Mac B.

Logs

Identifiers are redacted, but the important failure pattern is:

[remote-control-websocket] remote_control_client_refresh_start_request hasExistingEnrollment=true localEnrollmentClientId=<redacted stale client id> ...
[AppServerConnection] app_server_connection.transport_connect_failed errorMessage="Remote-control client has been revoked" hostId=remote-control:<redacted stale env id> transport=websocket
[remote-connections/window-context] connect_from_config_apply_failed errorMessage="Remote-control client has been revoked" hostId=remote-control:<redacted stale env id>

This repeats on app startup and QR setup retries.

Recovery attempts

Clearing the remote-control keys from ~/.codex/.codex-global-state.json while Codex is running is not sufficient because the running app rewrites the stale state back to disk.

Clearing both ~/.codex/.codex-global-state.json and ~/.codex/.codex-global-state.json.bak while Codex is fully stopped removes the local stale state. However, there is no obvious mobile UI to remove the incorrect/stale host from the iPhone side, and the Mac UI can still present misleading connected state before cleanup.

Why this looks like a product bug

The app treats a revoked remote-control enrollment as an existing valid local enrollment (hasExistingEnrollment=true) and keeps retrying it instead of invalidating it.

The UI also appears to conflate or reuse remote-control host state between two Macs on the same account/workspace. This produces a cross-host mismatch: Mac A reports success, while the iPhone points at Mac B.

Suggested fixes

  • When the relay returns "Remote-control client has been revoked", clear the corresponding local enrollment and remote host mapping automatically.
  • Do not display mobile access as connected if the stored enrollment is revoked.
  • Ensure electron-local-remote-control-installation-id / host identity cannot be cloned or reused across Macs without re-enrollment.
  • Add a visible "Remove this Mac / disconnect host" action in ChatGPT mobile Codex.
  • Add a "Reset Codex mobile pairing" action in Codex App Settings > Connections.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 3 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #22950
  • #23112
  • #23290
  • #23078
  • #22765

Powered by Codex Action

jshaofa-ui · 3 months ago

🔧 Solution: Revoked Enrollment Reuse Prevention (Cross-Host Stale State)

Root Cause Analysis

Three failure points:

  1. Enrollment Identity Not Host-Bound (Primary): When two Macs share the same ChatGPT account, the enrollment system doesn't distinguish between hosts. Enrollment ID is shared at account level, not host level. Server-side enrollment registry doesn't validate host identity on connection.
  1. Revoked Client Reuse (Secondary): When enrollment is revoked, the client isn't invalidated. Desktop app doesn't check revocation status before reconnecting. No revocation notification mechanism from server to client.
  1. Setup Doesn't Replace Stale Enrollment (Tertiary): Re-running mobile setup doesn't invalidate existing enrollments. No "enrollment replacement" flow — only "new enrollment". Server accepts duplicate enrollments without conflict resolution.

Proposed Fix

Part 1: Host-Bound Enrollment Identity — Bind each enrollment to a unique host identifier (machine UUID + platform fingerprint). Server validates host identity on connection.

Part 2: Revocation Status Check — Periodic revocation checking (every 5 min when connected). Pre-connect verification before each remote session.

Part 3: QR Code Setup Replacement Flow — Explicitly revoke old enrollment before creating new one when scanning QR code. Verify new enrollment is active.

Part 4: Server-Side Conflict Resolution — Prevent duplicate enrollments for same account. Notify conflicting hosts.

Implementation Priority

| Priority | Component | Effort | Impact |
|----------|-----------|--------|--------|
| P0 | Host-bound enrollment | 2-3 days | Prevents cross-host confusion |
| P0 | Revocation check | 1-2 days | Stops using revoked clients |
| P0 | QR replacement flow | 1 day | Fixes setup not replacing |
| P1 | Server conflict resolution | 2-3 days | Prevents duplicate enrollments |

Files to Modify

apps/codex-desktop/src/remote-control/enrollment.ts       [MODIFY] Add host binding
apps/codex-desktop/src/remote-control/revocation-check.ts [NEW] Revocation monitoring
apps/codex-desktop/src/remote-control/qr-setup.ts         [MODIFY] Replace flow
server/src/api/remote-enrollments.ts                      [MODIFY] Conflict resolution
apps/codex-desktop/src/remote-control/connection.ts       [MODIFY] Pre-connect verification

Full solution document: ~/.hermes/solutions/codex-23339-revoked-enrollment-reuse-security-fix.md

neilsanghrajka · 3 months ago

Faced this as well, have a macbook pro and macbook air. Connected macbook air to my iphone via chatgpt app, suddenly codex on both macbook pro and macbook air started showing connected to the same device