Skip to content

feat(gui): expose native main login profiles in the WebUI #3417

Description

@luvs01

Area

Dashboard

What are you trying to accomplish?

Manage the physical native Codex login from the OpenCodex WebUI without confusing it with Pool routing.

The user should be able to see the current native main login, save it as a profile, choose an existing encrypted native profile, switch the login used by native Codex, and recover or restore the previous profile. The workflow must make clear which effective CODEX_HOME will change and whether native Codex must be closed or restarted.

This is the Dashboard phase originally described in #656 and intentionally deferred when #863 shipped the credential lifecycle as a CLI/backend-only first phase.

What prevents this today?

#863 established the encrypted native-profile backend and /api/native-main-profiles management routes for listing, diagnostics, registration, staged login state, switching, and recovery. Those routes carry safe profile identifiers and labels rather than auth envelopes or tokens.

The current WebUI main-account card still exposes Pool-routing actions and the locked App login identity only. It has no native-main profile-management entry point, so Dashboard users must leave the UI and use ocx account main.

Adding a brand-new login is also not a frontend-only API connection. The current CLI add flow launches the official codex login process in the restricted staging home, maintains the staging lease heartbeat, and then finishes or cancels the stage. A browser cannot safely perform that process step by itself.

What should OpenCodex do?

  • Add a clearly separate Manage main login / Change main account entry point near the native main-account card.
  • Show the effective Codex home, current native profile, and only the existing safe public profile fields.
  • Let users list profiles, register the current app login, switch to an existing profile, and recover or restore the previous profile.
  • Before switching, explain which Codex installation/home will change, require explicit confirmation that native Codex is stopped when necessary, and report the required restart afterward.
  • Refresh the main-account display after success without changing Pool strategy, Pool membership, provider credentials, API keys, task/history data, or per-conversation namespaces.
  • Reuse the validation, encrypted vault, transactional activation, rollback, recovery, request-drain, and __main__ reconciliation behavior from feat(codex): add encrypted native main profiles #863.
  • Keep credential bytes, tokens, raw account IDs, vault payloads, and key material out of browser responses, logs, and persisted GUI state.
  • For new-profile enrollment, use either a narrowly scoped backend orchestration bridge for the official login process or an explicit user-assisted CLI handoff. Do not synthesize a native auth envelope from a Pool record or add a generic shell-execution surface.

Example usage or interface

Native main login
  Current: personal
  Codex home: C:\Users\me\.codex
  [Manage main login]

Manage main login
  personal   active
  work       [Switch]

  [Save current as profile]
  [Add another login]
  [Restore previous]

OpenCodex Pool routing
  Active pool account: team-a

Selecting Switch should show the target native profile, effective Codex home, native-process requirement, and restart result before any credential change occurs.

Alternatives or workarounds

  • ocx account main list/register/add/switch/recover provides the completed CLI workflow.
  • Logging out and back in through Codex changes the native login but is disruptive and does not provide the same profile recovery workflow.
  • Dashboard Pool selection changes proxy routing only; it does not replace the physical native login.

Additional context

The full #863 history, including its force-push-era heads and separate design branch, contains no native-profile WebUI implementation that was later removed. The design explicitly kept GUI work out of the first PR, while leaving a reusable management boundary for this follow-up.

A reviewable delivery can remain under this one workflow while using two stacked PRs:

  1. Existing-profile UI: list, register current, switch, confirmation/restart messaging, recovery, refresh, accessibility, i18n, and GUI tests using the existing routes.
  2. New-profile enrollment: the approved staged-login orchestration or handoff, including cleanup, expiry, cancellation, and error-path tests.

Acceptance requires the native-login surface to remain visually and behaviorally distinct from use this account for the next request / Pool selection. Existing management authentication, same-origin GUI session, CSRF, route-admission, secret-redaction, task/history preservation, and failure-recovery guarantees must remain enforced.

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 Sep 4, 2026

    @github-actions
    Contributor

    Issue reopened

    The report now contains the information required by the automated check. Thanks for updating it.

  2. lidge-jun commented on Sep 4, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 44 / 80

    이 이슈는 물리적인 native Codex 메인 로그인 프로필을 WebUI에서 다루고 싶다는 요청입니다. Pool에서 “다음 요청에 이 계정 쓰기”를 고르는 것과는 다른 축입니다. 사용자는 현재 native main이 무엇인지 보고, 암호화된 프로필로 저장·선택·전환·복구하고, 그 결과가 어느 CODEX_HOME을 바꾸는지·native Codex를 끄거나 재시작해야 하는지를 UI에서 분명히 보고 싶어 합니다. 본문이 #656의 Dashboard 예시와, #863이 CLI/백엔드만 먼저 싣고 GUI는 일부러 미룬 설계를 정확히 인용하고 있어서, “새 아이디어”가 아니라 이미 합의된 2단계 중 Dashboard 단계를 다시 연 것입니다.

    현재 dev에서 백엔드 경계는 이미 있습니다. src/server/management/route-registry.ts에 GET/POST /api/native-main-profiles 및 doctor/register/stage/switch/recover 경로가 등록돼 있고, 구현은 src/codex/native-profile-api.ts·src/codex/native-profile-store.ts(.opencodex-native-main-profiles) 쪽입니다. CLI는 src/cli/account-main.ts의 ocx account main list|register|add|switch|recover|doctor가 같은 API를 부릅니다. 헬프 문구도 “Pool의 ocx account use openai와 독립”이라고 못 박아 두었습니다. 반대로 GUI(gui/src)에는 native-main-profiles를 부르는 화면이 없습니다. Codex 계정 UI는 CodexAccountPool / Multi-auth(gui/src/pages/codex-set-multiauth.tsx, useCodexAccountPool.ts)가 Pool·Direct·App login 고정 신원 쪽에 머물러 있고, 최근 대시보드 트레인(#3387 overview-only, #3393 Codex 카드 disclosure, #3415/#3418 affordance 복원)도 Pool 라우팅 카드를 다듬은 것이지 native-main 프로필 관리를 넣지 않았습니다. 그래서 “Dashboard에서 Pool만 보이고 main 프로필은 CLI로 나가라”는 본문 진단이 HEAD와도 맞습니다.

    이슈가 제안한 전달 방식도 실무적으로 좋습니다. (1) 기존 프로필 UI — list/register/switch/확인·재시작 문구/recover/refresh/a11y/i18n/테스트로 기존 라우트만 소비, (2) 새 로그인 enrollment — 공식 codex login을 스테이징 홈에서 돌리는 stage 오케스트레이션 또는 명시적 CLI 핸드오프. 브라우저가 Pool 레코드로 auth envelope를 합성하거나 임의 셸 실행면을 여는 것은 금지라는 제약도 #863 보안 모델과 같습니다. 지금 dev 방향(대시보드 최소화 후 필요한 affordance만 되돌리기, Integrations 복원)과도 충돌하지 않되, 메인 카드에 Pool 액션과 native-main 액션이 한 덩어리로 섞이면 사용자가 또 헷갈리므로 UI 분리가 수용 조건의 핵심입니다. types/config 스플릿에 무효화될 PR도 아니고, #656은 이미 닫혀 #863으로 1단계가 끝났으니 이 이슈를 그 GUI 후속의 정식 추적 티켓으로 두는 편이 맞습니다.

    경로 /api/native-main-profiles* - 백엔드·CLI는 이미 있음. GUI 미연결이 갭의 전부
    경로 gui/src CodexAccountPool / Multi-auth - Pool·App login만 노출, native-main 진입점 없음
    src/cli/account-main.ts - 워크어라운드가 완성돼 있어 P0 블로커는 아님 (우선순위 중하위 근거)
    본문 “새 로그인 = 브라우저 단독 불가” - stage/핸드오프 설계를 PR1에서 억지로 넣지 말라는 좋은 가드
    관련 #656/#863 - 중복 신규 설계 이슈가 아니라 합의된 phase-2; 닫지 말고 GUI 스코프로 유지

    메인테이너의 판단이 필요한 지점

    • Dashboard 어디에 둘지: Codex Set Multi-auth 카드 옆 분리 패널 vs 별도 Integrations/Codex 탭 (최근 overview-only·disclosure 패턴과 맞출지)
    • PR 스택을 이슈 제안대로 2단(기존 프로필 → enrollment)으로 받을지, enrollment까지 한 PR에 묶을지
    • 새 로그인 경로를 “백엔드가 codex login을 오케스트레이트” vs “UI는 CLI 명령만 안내” 중 무엇으로 승인할지 (보안·지원 부담)

    너의 추천
    이슈를 열고 enhancement/gui로 유지. 첫 PR은 기존 /api/native-main-profiles만 소비하는 기존 프로필 관리 UI(list/register/switch/recover + CODEX_HOME/재시작 확인 + Pool과 시각·행동 분리 + hermetic GUI 테스트)만 받기. enrollment는 후속 PR로 분리하고, 브라우저 셸/envelope 합성은 리뷰에서 즉시 거절. CLI가 이미 있으므로 merge 급한 P0는 아님 — 대시보드 안정화 트레인 사이 슬롯에 넣기.

    이 댓글은 grok-bot이 작성했습니다

  3. nordz0r commented on Sep 7, 2026

    @nordz0r
    Contributor

    Headless-hub follow-up (deviceauth reauth of existing native _main_, not the profile switcher): #3898

  4. luvs01 commented on Sep 10, 2026

    @luvs01
    CollaboratorAuthor

    Author response: scope boundary with #3898, and a concrete answer to the three open decisions

    @nordz0r's cross-link is correct and worth stating explicitly, because the two issues touch the same card and would otherwise look like duplicates.

    #3898 replaces a broken credential in the slot the operator already has; this issue changes which stored profile occupies that slot. #3898 is about a headless hub whose native __main__ grant became unusable (token_revoked) and needs a fresh device login written into $CODEX_HOME/auth.json, with no local Codex App and oauthOpenBrowser: false. It needs a re-login control on the existing main card and a device-code path that accepts __main__. This issue is about listing, saving, switching between and recovering multiple encrypted native profiles through /api/native-main-profiles, where the risky part is that switching changes the effective CODEX_HOME and may require native Codex to be stopped and restarted. Neither one subsumes the other: #3898 can ship without any profile store, and profile switching does not repair a revoked grant. They do share the constraint that the native main surface must stay visually and behaviorally separate from Pool routing, so whichever lands first should establish that separation and the second should reuse it rather than re-open the card layout.

    On placement: a separate panel reached from the native main card, not a new Integrations or Codex tab. The overview-only and disclosure work in #3387/#3393/#3415/#3418 settled on keeping the dashboard surface small and revealing detail on demand. Profile management is a rare, deliberate operation, so a disclosure panel matches both that pattern and the acceptance condition that Pool actions and native-main actions must not read as one group. A dedicated tab would give a rarely used workflow permanent top-level weight and would separate it from the card whose state it changes.

    On the PR stack: two PRs, as the review recommended. The first consumes only the existing routes — list, register current, switch with the CODEX_HOME and restart confirmation, recover and restore, refresh, accessibility, i18n and hermetic GUI tests. It has no new backend surface, so it can be reviewed purely as UI against a settled API. Enrollment is a different review: it involves running the official codex login in the restricted staging home, lease heartbeats, cancellation, expiry and cleanup. Merging them would force the security-sensitive orchestration and the ordinary UI work through one review, and any objection to the staging bridge would block a UI change that is independently useful.

    On new-login enrollment: I recommend the backend-orchestrated staged login rather than the CLI-handoff-only option, but only as the second PR and only over the existing #863 stage boundary. The CLI already maintains the staging lease and finishes or cancels the stage, so the orchestration path exists and the browser only starts and observes it. A UI that merely prints a command to run elsewhere leaves the dashboard unable to report enrollment outcome, which is the part operators actually need. If the added support burden is judged too high, the CLI handoff is an acceptable fallback and does not change the first PR at all. In either case the prohibitions from #863 hold without exception: no synthesizing a native auth envelope from a Pool record, and no generic shell-execution surface.

    I am not opening the first PR before that placement decision, since panel-versus-tab determines the component boundary and the i18n and test surface, and rewriting it afterwards would waste a review cycle. The scope, routes and acceptance conditions above are otherwise settled from my side.

  5. lidge-jun commented on Sep 18, 2026

    @lidge-jun
    Owner

    Phase 1 is on dev via #4781, squashed as 11bc4f708cf8e5ae5150b1fbda15fffa4d935615.

    Existing native main login profiles are now manageable from the WebUI. The change is additive and carries its own translation modules rather than extending the per-locale catalogs, so it does not touch any other surface's strings.

    Closing this as the feature it asked for. If the parts deliberately left out of phase 1 still matter to you, a fresh issue naming them specifically will be easier to act on than reopening this one, because the scope here predates the work that landed.

    Shipping in the next release off dev.

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

    enhancementNew feature or requestguiDashboard, tray, settings UI

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions