codex-profile-manager
v0.1.0
Published
Run multiple Codex CLI accounts side by side with isolated auth and codex-<profile> launchers.
Downloads
149
Maintainers
Readme
codex-profile-manager
Run multiple Codex CLI accounts side by side.
codex-personal · codex-work · codex-client
Codex Profile Manager gives every Codex account its own launcher and isolated login while keeping your existing config, skills, plugins, rules, MCP servers, memories, and sessions shared.
$ npx codex-profile-manager add --name Personal --slug personal
Sign in to the Codex account for "Personal".
...
Added Personal. Launch it with: codex-personal
$ npx codex-profile-manager add --name Work --slug work
$ codex-personal
$ codex-work exec "review this repository"Profiles do not overwrite ~/.codex/auth.json. Each launcher sets a different
CODEX_HOME, so two accounts can run concurrently without a global “active
account” race.
Different profiles run concurrently. A single profile is lifecycle-locked while its Codex process is active so login, rename, or removal cannot replace credentials underneath that process.
Install
Requires Node.js 18+ and the official codex
CLI on PATH.
npx
npx codex-profile-manager addLaunchers created from an npx run pin the manager version that created them,
so they keep working after npm clears its temporary cache without silently
adopting future code. Run a newer manager’s cpm sync to upgrade them.
Global install
For faster launcher startup and offline use:
npm install -g codex-profile-manager
cpm addBoth cpm and codex-profile-manager invoke the manager. Account launchers
always use the codex-<slug> form.
From source
git clone https://github.com/nhocconan/codex-profile-manager.git
cd codex-profile-manager
npm install
npm run verify
npm install -g .Launchers are installed into a writable directory on PATH, preferring
~/.local/bin. If that directory is not on PATH, the tool prints the exact
line to add to your shell profile.
Quick start
# Browser login
cpm add --name Personal --slug personal
# Device-code login for a remote/headless terminal
cpm add --name Work --slug work --device-auth
# Import the login already stored in ~/.codex/auth.json
cpm import --name Current --slug current
# See all launchers
cpm list
# Use an account anywhere normal codex works
codex-personal
codex-work exec "fix the failing tests"
codex-work review
codex-personal resume --lastRunning cpm with no arguments opens an interactive profile picker.
Commands
| Command | Purpose |
|---|---|
| cpm | Interactive picker |
| cpm add | Create a profile and run codex login |
| cpm import | Copy the current file-based Codex login into a profile |
| cpm list | Show profiles and safe login metadata |
| cpm launch <slug> | Launch a profile and pass all remaining args to Codex |
| cpm use <slug> | Alias for launch |
| cpm login <slug> | Replace a login; restores the old one if login fails |
| cpm edit <slug> | Change the label or codex-<slug> command |
| cpm remove <slug> | Delete one profile and its isolated credentials |
| cpm sync | Rebuild profile config and launcher scripts |
| cpm doctor | Audit auth, isolation, duplicate credentials, and launchers |
Common options:
--name, -n <label>
--slug, -s <suffix>
--device-auth
--api-key-env <ENV_NAME>
--access-token-env <ENV_NAME>Secrets are deliberately accepted through environment variable names instead of literal flags, keeping them out of shell history and process listings:
export MY_CODEX_API_KEY="..."
cpm add --name API --slug api --api-key-env MY_CODEX_API_KEY
unset MY_CODEX_API_KEYHow it works
OpenAI documents that Codex stores file-based credentials in
$CODEX_HOME/auth.json and that CODEX_HOME defaults to ~/.codex.
Codex Profile Manager uses that supported boundary:
~/.config/codex-profile-manager/
├── profiles.json
└── profiles/
├── personal/
│ ├── auth.json real file: Personal credentials
│ ├── config.toml regenerated config, credential store forced to file
│ ├── skills -> ~/.codex/skills
│ ├── sessions -> ~/.codex/sessions
│ └── ... other non-auth state shared from ~/.codex
└── work/
├── auth.json real file: Work credentials
└── ...
~/.local/bin/
├── codex-personal
└── codex-workOn every launch the manager:
- verifies the profile has usable credentials;
- refreshes links to the base Codex home;
- regenerates
config.tomlfrom the current base config and forcescli_auth_credentials_store = "file"; - removes competing auth environment variables;
- starts the current
codexbinary with the profile’sCODEX_HOME; - relays signals and returns Codex’s exit code.
Codex can refresh its tokens normally because each profile’s auth.json is a
real writable file. Process-local directories such as ipc, process_manager,
and temporary files also stay private to each profile. The registry contains
labels and slugs only—never tokens.
See OpenAI’s Codex authentication documentation for the credential-storage contract and security guidance.
Importing the current account
cpm import reads ~/.codex/auth.json. If Codex is configured to keep
credentials only in the OS keyring, there may be no file to import. Create a
file-based login first:
codex -c 'cli_auth_credentials_store="file"' login
cpm import --name Current --slug currentTreat every managed auth.json like a password. They are written with mode
0600 on Unix and must never be committed, pasted into issues, or shared.
Environment overrides
These are useful for testing or nonstandard installations:
| Variable | Meaning |
|---|---|
| CODEX_PROFILE_MANAGER_HOME | Manager state root |
| CODEX_PROFILE_MANAGER_BASE_HOME | Shared base Codex home (default ~/.codex) |
| CODEX_PROFILE_MANAGER_BIN_DIR | Launcher directory |
| CODEX_PROFILE_MANAGER_CODEX_BIN | Exact Codex executable |
Design boundaries
- This tool manages Codex CLI accounts. It does not switch the desktop app.
- Codex configuration profiles selected by
codex --profilecustomize model and sandbox settings; they are separate from the account profiles managed here. - Non-auth Codex state is intentionally shared. If you need fully isolated
histories and plugins, set up separate
CODEX_HOMEdirectories directly. - Launchers never replace an unrelated existing
codex-<slug>file.cpm doctorreports the collision.
Development
npm install
npm run typecheck
npm test
npm run build
npm pack --dry-runThe published CLI keeps its runtime surface small: cross-spawn safely runs
Codex’s Windows .cmd shim, and proper-lockfile protects profile lifecycle
operations across processes and recovers stale locks after crashes.
License
MIT
