Skip to content

fix: keep multiple Codex accounts from overwriting each other - #32

Open
Kunde21 wants to merge 3 commits into
TopiCsarno:mainfrom
Kunde21:fix/codex-account-overwrites
Open

Kunde21 wants to merge 3 commits into
TopiCsarno:mainfrom
Kunde21:fix/codex-account-overwrites

Conversation

@Kunde21

@Kunde21 Kunde21 commented Sep 17, 2026

Copy link
Copy Markdown

Problem

Adding a second Codex account makes the first one disappear: the new login replaces the existing account's storage and config entry, so the popup shows only the new account. Two independent causes, both reproduced on a two-seat ChatGPT Team workspace:

1. Workspace seats share the provider account id. The usage endpoint reports the workspace-scoped account_id, so every seat of one Team workspace carries the same id (verified on the affected machine: two different emails, identical provider_account_id in stored metadata). same_identity treated equal ids as one account without consulting the email, so a second seat's login matched and overwrote the first account, and the dedupe/discover paths merged their entries. Identity now requires email agreement whenever provider account ids are compared.

2. Stale per-monitor processes clobbered the shared config. Each panel applet runs its own process with an in-memory config copy. write_config cloned that copy as the write base, so a process that had missed a watcher update wrote its stale account lists over config.json, dropping accounts added from another monitor. write_config now reloads the freshest config from disk before applying the mutation and writes only keys changed relative to that state; failed login-result persistence is logged instead of ignored.

Also sends prompt=login on the Codex OAuth authorization URL so auth.openai.com cannot silently re-authorize the browser's current session when the user intends to add a different account (verified the parameter is honored: prompt=none is rejected, prompt=login yields an interactive challenge).

Regression tests

  • shared_workspace_account_id_with_different_emails_stays_separate
  • find_matching_account_requires_email_agreement_for_known_account_ids
  • write_config_preserves_accounts_written_by_another_process
  • apply_login_account_keeps_existing_distinct_account

Known limitation (out of scope here): the host Active badge matches by provider account id alone, so all seats of one workspace badge identically.

All 777 tests pass, cargo fmt and just check are clean.

Panel applets run one process per monitor and each holds an in-memory
config copy. write_config cloned that copy as the write base, so a
process that missed a watcher update wrote its stale account lists over
config.json, silently dropping accounts added from another monitor.
write_config now reloads the freshest config from disk before applying
the mutation and writes only keys changed relative to that state, so
stale processes can no longer clobber shared account data. Failed
login-result persistence is now logged instead of ignored.
Without a prompt parameter auth.openai.com silently reuses the browser
session, so adding a second account could quietly re-authorize the
already logged-in one. prompt=login forces the account chooser, matching
the explicit login flow users expect when adding accounts.
The usage endpoint reports the workspace-scoped account id, so every
seat of a ChatGPT Team workspace carries the same provider account id.
same_identity treated equal ids as one account without checking email,
so logging in a second team member matched and overwrote the first
account's storage and config entry, and the dedupe paths merged their
entries. Identity now requires email agreement whenever provider
account ids are compared.
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.

1 participant