Why Separate Work and Personal Codex Accounts
Managing distinct ChatGPT identities for professional and personal use prevents accidental cross-contamination of conversations, billing, and access controls. A work account may have team-shared threads, organization billing, or compliance requirements that should never mix with personal experimentation. The codex multi account switcher built into CodexMarathon lets you store both profiles locally and switch between them at a safe boundary between turns.
The approach is straightforward: sign in to each account once, give each a memorable alias like work or personal, and use the native Marathon commands to change the active identity only when no model response, tool call, or subagent turn is running. Provider quotas still apply per account; the switcher does not change how ChatGPT meters usage.
Installing the Codex Multi Account Switcher
CodexMarathon ships as a single package: a modified codex CLI, the private codexmarathon-accountd metadata daemon, and its systemd user units are installed and started together. No separate plugin, SDK, or environment variable configuration is required.
curl -fsSL https://raw.githubusercontent.com/Lem0nTree/codexmarathon/main/scripts/install.sh | sh
The installer enables the user service and socket, enables user lingering for operation after logout, and verifies the account API before reporting success. On Linux ARM64, the installer sets features.daemon_auto_start = false using Codex’s TOML editor, preserving other configuration settings. The interactive CLI uses its embedded app-server instead of the separate shared daemon.
To use a non-default Codex state directory, pass an absolute path:
curl -fsSL https://raw.githubusercontent.com/Lem0nTree/codexmarathon/main/scripts/install.sh \
| CODEXMARATHON_CODEX_HOME=/srv/codex-state sh
The installer records that selection in the owner-private $XDG_CONFIG_HOME/codexmarathon/config.json. The modified CLI and accountd use it automatically on later invocations, so shell startup changes are not required.
Signing In to Work and Personal Accounts
Once installed, use the native Marathon commands to add your accounts. The login command supports both a browser-link flow and a device-code flow for headless machines.
From the shell:
codex marathon login personal --device-code
codex marathon login work --device-code
Codex prints a verification URL and one-time code. Open the URL on your own machine, enter the code, and complete the ChatGPT sign-in. Once Codex receives the native login completion, it stores that identity under the alias you provided.
In an interactive Codex session, use:
/marathon login personal
/marathon login work
Codex presents Browser link and Device / auth code choices. On a headless server such as an AWS instance, choose device code, open the displayed verification URL on another machine, and enter the one-time code.
You can also import an identity that is already active in Codex without re-authenticating:
codex marathon import personal
Switching Between Accounts Safely
The codex multi account switcher enforces a strict safety model. A switch waits until all account-bound work is idle; it never changes an active model response, tool call, or subagent turn. The source identity is checked again before a transition. The target profile is validated and persisted atomically before Codex updates its in-memory credentials.
From the shell:
codex marathon on
codex marathon switch work
codex marathon switch personal
Inside an interactive Codex session:
/marathon on
/marathon switch work
/marathon switch personal
Running /marathon displays the current native state and a help panel. It also explains the available account, login, enabled-state, and switching commands.
A failed or uncertain transition is recorded as such and requires reconciliation; Marathon never guesses that a credential change succeeded. API keys, external bearer authentication, workload identity, and other unsupported provider modes are rejected for Marathon switching.
Viewing Account Status
Use status and accounts to see aliases, IDs, enabled state, and transition state. Credential snapshots are never printed.
codex marathon status
codex marathon accounts
The accounts --daemon command adds credential-health and quota summaries from the account daemon:
codex marathon accounts --daemon --format table
codex marathon accounts --daemon --format json
Configure the status line with the marathon and marathon-accounts items. They display whether native Marathon is enabled and the number of managed accounts.
Encrypted Account Backup
Backups operate on saved Marathon profiles, not merely the currently installed auth.json. In an interactive terminal, omit the account flags to get a checkbox picker:
codex marathon backup export --output accounts.cmbackup
codex marathon backup import accounts.cmbackup --dry-run
codex marathon backup import accounts.cmbackup
Inside the Codex TUI, /marathon export opens the same native workflow: select accounts with checkboxes, choose the destination filename, and enter and confirm a masked backup password. The password stays in zeroizing local TUI state; it is never sent to accountd, app-server RPCs, session history, or debug events.
Export asks for the passphrase twice and import asks once; terminal echo stays disabled while it is entered. For unattended use, pass an owner-only file with --passphrase-file and select accounts explicitly with repeatable --account or --all. Passphrases are never accepted in command arguments or environment variables.
The archive is authenticated age encryption with a bounded scrypt work factor. Import validates and decrypts the complete archive before changing state, stages credentials under fresh vault references, and commits the registry as one atomic update. Imported accounts start inactive, and import never replaces the destination’s active auth.json. Conflicts default to skip; replace cannot replace the active identity, while rename changes only a colliding alias.
After an interactive import writes accounts, the CLI offers an Up/Down picker to activate one of the imported or replaced accounts through the normal switch path. Escape leaves the imported credentials available without activating one; dry runs, no-op imports, and non-terminal --yes imports do not prompt.
Practical Example: Daily Workflow
Here is a complete workflow for a day with both work and personal accounts:
# Enable Marathon account management
codex marathon on
# Check current status
codex marathon status
# Switch to work account at a safe boundary
codex marathon switch work
# ... use Codex for work tasks ...
# Switch to personal account
codex marathon switch personal
# ... use Codex for personal tasks ...
# Export encrypted backup at end of day
codex marathon backup export --output daily-backup.cmbackup --all
The same workflow works inside an interactive Codex session using slash commands:
/marathon on
/marathon status
/marathon switch work
/marathon switch personal
/marathon export
Architecture and Safety
The codex multi account switcher is a native feature of the custom Codex Rust CLI. The Marathon command, interactive /marathon controls, status line, account service, and Codex authentication manager all run in the same executable. The CLI starts a typed in-process app-server client, so account state and transitions do not depend on a second process, an environment-variable socket, or a separate authentication implementation.
The account daemon owns the setting and durable jobs. The separately installed codexmarathon-reset-executor service uses native authentication to refresh credit inventory and redeem a selected credit without changing the active account. Both services must be running for unattended operation; a stopped machine cannot redeem a credit.
For more details, visit the CodexMarathon blog and the GitHub repository.