English README | 中文说明
CodexAuth Switch is a local Windows and macOS desktop utility for quickly switching between multiple Codex App login accounts.
It is designed for people who use more than one OpenAI / Codex App account. You can save each account's local login state, then switch the active Codex login through this tool. The app only operates on local files. Quota and usage views come from local Codex logs; it does not call remote quota endpoints or upload Codex conversation history.
One-line positioning: CodexAuth Switch is a local-first Codex App multi-account switcher with auth.json snapshot management, Windows DPAPI / macOS Keychain encryption, quota display, and token usage statistics.
This is an unofficial project and is not affiliated with OpenAI.
- Users who manage multiple Codex App login accounts on Windows or macOS.
- Users who want to switch the active OpenAI Codex / Codex App account quickly.
- Users who want to safely save and restore local
~/.codex/auth.jsonlogin snapshots. - Users who want to view local Codex quota, 5-hour quota, weekly quota, Reviews, model-level limits, token usage, and recent sessions.
- Users who want local log estimation without sending tokens, account data, or conversation history to remote quota endpoints.
Codex account switcher, Codex multi account, Codex App account manager, OpenAI Codex account switcher, Codex auth.json switcher, Codex local login manager, Codex quota viewer, Codex token usage dashboard, Codex Windows macOS desktop app, Codex DPAPI Keychain encryption, Codex local quota estimate, Codex local quota tracking, Codex local history read-only.
- Import the current Codex App login state.
- Save multiple local account snapshots.
- Switch the active Codex login by replacing
~/.codex/auth.json. - Encrypt saved credentials with Windows DPAPI or macOS Keychain-backed system storage, readable only by the current operating-system user.
- Automatically back up the original
auth.jsonbefore switching, reauth, or deleting the active account. - Provide a main window, system tray menu, and floating quick-view widget.
- Read quota and token usage from local Codex logs.
- Use a local token-event ledger to reduce repeated scans and improve local estimate stability.
- Show quota pace hints, Reviews, and model-level limit cards.
- Disable network requests in renderer pages; quota reading also stays local-only.
| Main Window | Floating Quick View |
|---|---|
![]() |
![]() |
CodexAuth Switch is intentionally scoped to the local Codex login file and the app's own storage directory.
~/.codex/auth.json- The active local login file used by Codex App.
- During account switching, the app replaces this file with a saved account snapshot.
~/.codex/config.toml- Ensures the top-level setting contains
cli_auth_credentials_store = "file"so current Codex releases continue using switchableauth.jsoncredentials. - Creates a timestamped
config.toml.codexauth-backup-*copy in the same directory before changing the file.
- Ensures the top-level setting contains
- App account metadata:
%APPDATA%\codex-auth-switcher\accounts.jsonon Windows;~/Library/Application Support/codex-auth-switcher/accounts.jsonon macOS. - Encrypted account snapshots:
%APPDATA%\codex-auth-switcher\accounts\*.dpapion Windows;~/Library/Application Support/codex-auth-switcher/accounts/*.keychainon macOS. - Encrypted backups created before operating on the active account:
%APPDATA%\codex-auth-switcher\backups\*.dpapion Windows;~/Library/Application Support/codex-auth-switcher/backups/*.keychainon macOS.
~/.codex/auth.json- Used to import the current login and identify the account.
~/.codex/sessions/**/rollout-*.jsonl- Used for local usage and quota snapshot calculation.
~/.codex/session_index.jsonl- Used to enrich local session metadata when available.
~/.codex/logs_2.sqlite- Opened in read-only mode to read local Codex quota events.
- It does not modify Codex conversation history.
- It does not delete
~/.codex/sessions. - It does not write to
logs_2.sqlite. - It does not upload tokens, account data, session logs, or usage records.
- It does not use the current access token to request remote quota endpoints.
- It does not refresh OpenAI tokens by itself.
- It does not call remote quota endpoints.
The only features that intentionally affect Codex App runtime state are account switching, reauth, deleting the active account, and restarting Codex App. These actions may update config.toml, replace or remove the current auth.json, and restart Codex App so the new local login state takes effect.
When importing the current login, the app reads ~/.codex/auth.json and validates that it matches Codex App's ChatGPT login format.
It parses JWT payloads locally and extracts fields such as email, user ID, and workspace/account ID. Account matching does not rely on a single claim. It combines personal identity and workspace identity when possible, because one person can belong to multiple workspaces and one workspace can contain multiple users.
The app does not store auth.json in plain text. Windows uses DPAPI; macOS uses Electron safeStorage backed by the system Keychain.
Windows uses DataProtectionScope.CurrentUser; macOS uses the current user's Keychain.
This binds encrypted snapshots to the current operating-system user. Other users, machines, or operating systems cannot directly decrypt them.
Saved account snapshots are stored in:
- Windows:
%APPDATA%\codex-auth-switcher\accounts - macOS:
~/Library/Application Support/codex-auth-switcher/accounts
Backups created before operating on the active login are stored in:
- Windows:
%APPDATA%\codex-auth-switcher\backups - macOS:
~/Library/Application Support/codex-auth-switcher/backups
The app does not call an OpenAI token-refresh endpoint itself. Codex refreshes access and refresh tokens during actual use; CodexAuth Switch watches the current auth.json and re-encrypts updated contents into the matching account snapshot. An expired access token alone does not mean the login is invalid—reauth is needed only when Codex can no longer refresh it.
The newest 60 encrypted backups are retained. Atomic-write temporary files older than one hour are cleaned at startup so long-running switching and usage tracking do not create unbounded cache growth.
When switching accounts, the app:
- Reads the current
~/.codex/auth.json. - Creates a backup encrypted by the current platform's secure storage if a login exists.
- Decrypts the selected account snapshot.
- Validates that the snapshot is a valid Codex login file.
- Writes the snapshot to a temporary file.
- Atomically renames the temporary file to
~/.codex/auth.json. - Restarts Codex App if the user chooses to do so.
The temporary-file plus atomic-rename approach reduces the chance that Codex App reads a partially written auth.json.
On Windows, restart stops the desktop process group belonging to the Codex installation. On macOS, it detects the current ChatGPT or legacy Codex application process, waits for it to exit, and relaunches it through Launch Services.
If a saved account's refresh token becomes invalid, the app can start a reauth flow:
- Back up the current
auth.json. - Delete the current local
auth.json. - Restart Codex App.
- Let the user complete the official login flow inside Codex App.
- After Codex App writes a fresh
auth.json, CodexAuth Switch watches for it and saves it back to the matching account.
This does not bypass or replace official login. The real login still happens inside Codex App.
The quota panel uses local estimate mode only. It reads logs already written by Codex App and does not request chatgpt.com or any other remote quota endpoint.
Local estimate mode reads:
codex.rate_limitsrecords in session JSONL files.codex.rate_limitsand usage-limit records inlogs_2.sqlite.token_countevents in session files.local-token-ledger.jsonin the app data directory, which stores only token counts, model, timestamps, rate-limit snapshots, and file state for incremental de-duplication and steadier local estimation.
The app watches local log file changes with a short debounce and uses a low-frequency SQLite modification-time polling fallback to avoid missed filesystem events.
Quota snapshots are saved only into this app's own account metadata. They are not written back to Codex log files.
Multi-account statistics use the most recent account-switch time as their boundary. A session that continues across a switch is attributed through adjacent token-snapshot deltas, and quota calibration combines only post-switch events with that account's own saved learning so same-plan accounts do not leak into each other.
The app uses the current used percentage, quota window length, and reset time to estimate consumption pace. It can show whether usage is light, on track, or likely to run out early. This is a trend hint, not a promise of how much quota the next request will consume.
Electron windows use these security settings:
contextIsolation: true
nodeIntegration: false
sandbox: true
webSecurity: trueThe page CSP disables network connections:
connect-src 'none'The main process also installs an Electron webRequest.onBeforeRequest guard that cancels outbound requests for:
http://
https://
ws://
wss://
These restrictions keep renderer pages local-only and help prevent account data or local history from being uploaded. Quota reading also stays local-only.
npm installnpm startHidden local debug start on Windows:
npm run dev:hidden- Open Codex App and sign in to the first account.
- Open CodexAuth Switch.
- Click the button that imports the current Codex login.
- Return to Codex App, sign out, and sign in to another account.
- Return to CodexAuth Switch and import again.
- Repeat for every account you want to save.
- Select a saved account in CodexAuth Switch.
- Click switch.
- Restart Codex App if needed.
The app pins current Codex releases to file-backed credentials and fully restarts the desktop app when “restart after switch” is enabled, so the selected account takes effect after relaunch.
Use reauth when Codex reports that a refresh token can no longer be refreshed, or when a saved account has become stale.
The app clears the current local login and restarts Codex App. You then complete the official login inside Codex App. After Codex writes a new auth.json, CodexAuth Switch captures and saves it.
npm run lintnpm run quota:validateThis command replays local .codex session logs and validates the quota-estimation logic. It only reads local session files and does not write to them.
npm run pack:winRun this command on macOS:
npm run pack:macIt creates DMGs for Intel (x64) and Apple Silicon (arm64).
The installers are written to:
release/
The release directory is a local build artifact and is not committed to Git by default.
src/main.js Electron main process, local file access, account switching, quota logic
src/preload.js Safe IPC bridge
src/ui/index.html Main window page
src/ui/app.js Main window renderer logic
src/ui/widget.html Floating quick-view widget page
src/ui/widget.js Floating widget renderer logic
scripts/generate-icon.js Local icon generation
scripts/start-dev-hidden.ps1 Hidden debug start script
scripts/validate-quota-estimate.js Quota replay validation script
QUOTA-LOGIC.md Quota-estimation notes
- Windows and macOS are supported; Linux is not currently supported.
- Encrypted snapshots are bound to the current system user and cannot be copied directly across machines or platforms.
- This targets Codex App local login switching, not Codex CLI-only workflows.
- Local estimate mode is a best-effort interpretation of local logs.
- Quota snapshots may stay stale until Codex writes new local rate-limit records.
- Do not share saved credential snapshots across machines or operating-system users.
Windows installers and Intel / Apple Silicon macOS DMGs are uploaded through GitHub Releases. The current builds are not commercially code-signed or Apple-notarized, so the operating system may show a security warning.
MIT License. See LICENSE.
Only save and switch accounts that you own or are authorized to use. Do not share auth.json, encrypted snapshots, or backup files with other people.


