Skip to content

Switch a stored Codex account into the native main login from OpenCodex #656

Closed

Description

@luvs01

Area

Authentication and account pool

What are you trying to accomplish?

Switch the physical Codex/ChatGPT identity used as the native main login (__main__, backed by $CODEX_HOME/auth.json) from the OpenCodex UI or CLI, similar to a CodexSwitcher-style profile switcher.

This is intentionally different from choosing an active account in the OpenCodex Pool. The selected profile should become the login seen by native Codex App/CLI and by Direct mode, while local task/history files remain in the same Codex home.

What prevents this today?

  • ocx account use openai <id> and the dashboard account cards only change Pool routing (activeCodexAccountId); they do not change the physical native login.
  • The native main credential is treated as a read-only external source. OpenCodex can detect that another tool already replaced auth.json, but it does not provide the switch itself.
  • Users must log out and back in, run a separate switcher, or manually swap credential files. That is slow and can race a running Codex process, target the wrong CODEX_HOME, leave stale __main__ quota/cooldown/reauth state, or make rollback difficult.

What should OpenCodex do?

Add a separate Native main login profiles surface in the dashboard and CLI.

  • Let the user save the current native login as a named local profile and switch a previously authenticated/stored Codex identity into the native main slot.
  • Keep this UI and terminology separate from Pool selection. A native-login switch must not silently change Pool strategy, Pool membership, or per-conversation account namespaces.
  • Resolve the effective Codex home first and show which installation/home will be changed.
  • Validate the target identity before activation, then atomically replace auth.json with restrictive permissions/ACLs. Preserve a recoverable backup and roll back automatically if validation or the final write fails.
  • Never log or display tokens. Reuse the existing protected credential storage where possible instead of creating extra plaintext profile copies.
  • After a successful physical identity change, invoke the existing main-account reconciliation behavior: clear only __main__ quota, cooldown, reauthentication, plan/cache and thread-affinity state, and invalidate stale __main__ WebSockets.
  • Requests already in flight may keep their captured identity; the next request must use the newly selected native login. Report clearly if a full Codex App restart is required on a particular platform/version.
  • Preserve local task/history data. If an existing remote continuation is account-bound and cannot be resumed by the new login, fail with an explicit compatibility error rather than silently starting a different task.
  • Provide an explicit switch-back/rollback action.

Example usage or interface

$ ocx account main list
  personal   current
  work

$ ocx account main switch work
  Switching the native Codex login in C:\\Users\\me\\.codex ...
  ✓ Native main login is now: work

Dashboard:

Native main login
  Current: personal
  [Switch to work]  [Save current as profile]  [Restore previous]

OpenCodex Pool routing
  Active pool account: team-a

The two sections must remain independent.

Alternatives or workarounds

  • Manually selecting a Pool account changes proxy routing only.
  • Logging out and back in through Codex changes the main identity but is disruptive and does not provide quick rollback.
  • External switchers or manual auth.json replacement work, but OpenCodex can only react after the change and cannot validate or coordinate it.

Additional context

  • Issue #425 is about account-qualified model namespaces and does not replace the native main login.
  • PR #370 detects an externally changed physical main identity and purges stale __main__ runtime state. This request would provide the user-facing, validated switch that occurs before that reconciliation.
  • Current dev still documents the native main token as read-only from auth.json; this request intentionally proposes a new, explicit credential-lifecycle operation rather than changing normal request routing.
  • On Windows, an implementation that reuses OpenCodex's generic secret-file/ACL-hardening path should avoid inheriting the synchronous event-loop wait tracked separately in #612. This cross-reference is implementation context only; this request neither duplicates nor expands the scope of [Bug]: synchronous Windows ACL hardening stalls the proxy on response-state writes #612.

Checks

  • I searched existing issues and documentation.
  • This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
  • I removed secrets and personal data.

Activity

  1. github-actions commented on Jul 29, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: unknown.

  2. luvs01 commented on Jul 31, 2026

    @luvs01
    CollaboratorAuthor

    Follow-up after checking the current dev implementation:

    Recommended implementation boundary: define a full-fidelity native-profile representation and its refresh ownership, backup/rollback, and app-restart semantics first. Once that product/storage model is agreed and receives the required security review, a first PR can stay CLI/backend-only: validate the selected profile, activate it through the async atomic writer, roll back on failure, and then invoke the existing __main__ reconciliation. The dashboard can follow separately.

  3. added
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    on Aug 1, 2026
  4. Ingwannu commented on Aug 1, 2026

    @Ingwannu
    Owner

    Maintainer direction: this is a valid product idea, but a Pool credential is not a full native Codex auth envelope and must never be serialized directly into auth.json.

    The prerequisite is a full-fidelity encrypted native-profile format with explicit refresh ownership, effective CODEX_HOME targeting, atomic activation, rollback, app-restart semantics, and main runtime reconciliation. The first PR should be CLI/backend-only and must prove that failed validation or write restores the original native login without touching task/history data. Dashboard work can follow after the credential-lifecycle review.

    Keeping this open as needs-design; the generic Pool record is not an acceptable shortcut.

  5. added
    roadmapAccepted long-term work item; needs its own project cycle
    maintainer-sponsoredMaintainer sponsors this change to an auth, workflow, release, or dependency surface
    guiDashboard, tray, settings UI
    cliCLI, config inject, packaging flags
    on Aug 3, 2026
  6. Wibias commented on Aug 3, 2026

    @Wibias
    Contributor

    Thanks @luvs01 — fixed by PR #863 (1d1c80384): encrypted native-main profiles with OS-keyring key custody, transactional switching with crash recovery, and admission fencing; the review-loop findings (POSIX lock ownership, process probe, restart handoff, staging heartbeat, keyring CI) are all fixed with regression coverage.

  7. WilliamLuuu commented on Sep 4, 2026

    @WilliamLuuu

    Dashboard follow-up to the completed CLI/backend implementation

    I checked why this issue was closed: #863 implemented encrypted native-main profiles and transactional switching, and explicitly scoped the work to CLI/backend only, with no dashboard UI. This comment does not request reimplementation of that completed work.

    In the 2.41.0 WebUI, the main-account card still shows a lock and App login. The visible account-selection actions change Pool routing; there is no user-facing workflow to replace the native main login from the dashboard. The existing native-profile backend is not exposed by the shipped dashboard.

    Requested workflow

    Please expose the existing native-main profile workflow in the WebUI, clearly separated from use this account for the next request / Pool selection:

    1. Show the current native main login and offer Manage main login / Change main account.
    2. Let the user save the current application login as a profile, authenticate another login through the existing staging flow, or choose an existing native profile.
    3. Explain which Codex installation/home will change and any requirement to close or restart Codex; request explicit confirmation before switching.
    4. Reuse the existing encrypted profile, validation, transactional activation, rollback and recovery behavior. Do not convert a partial Pool credential into a native login envelope.
    5. On success, refresh the main-account display and provide an explicit restore-previous/recovery action. Preserve task/history data, other providers' API keys and Pool settings.

    Example: the native main login is account A; from the dashboard, authenticate/select native profile B and make B the login used by native Codex, rather than merely routing the next proxy request to B.

    The existing ocx account main workflow is an alternative for CLI users, but the request is to make that capability available and discoverable for users managing OpenCodex through the WebUI.

    Adding this as a follow-up to #656 / #863 rather than filing a duplicate “add main-account switching” issue. If dashboard work should be tracked separately, please split out that UI scope.

  8. luvs01 commented on Sep 4, 2026

    @luvs01
    CollaboratorAuthor

    @WilliamLuuu Thanks — your reading is correct. I rechecked the full #863 history, including the force-push-era heads and the separate design branch. The Dashboard workflow was considered in #656, but no native-profile WebUI implementation was removed; the GUI scope was intentionally deferred while the CLI/backend and management API were reviewed and landed.

    I opened #3417 to track that deferred phase. It treats the existing native-profile API and safety model as the foundation, keeps native-login actions separate from Pool routing, and calls out the one part that is not a simple frontend connection: staged enrollment currently relies on the CLI launching the official codex login process and maintaining its lease. The issue proposes reviewing that bridge separately while keeping the user workflow together.

    Further Dashboard design and implementation can continue in #3417 without reopening or expanding the completed #656/#863 backend slice.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, planscliCLI, config inject, packaging flagsenhancementNew feature or requestguiDashboard, tray, settings UImaintainer-sponsoredMaintainer sponsors this change to an auth, workflow, release, or dependency surfaceroadmapAccepted long-term work item; needs its own project cycle

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions