Manage multiple ChatGPT Codex auth.json profiles from the command line.
codex-auth is a small, practical utility for saving, switching, listing, and refreshing multiple Codex login profiles. It is vibe-coded in the best sense: built quickly, kept useful, and polished enough to share.
Current version: 0.9.0
See CHANGELOG.md for release history.
- Save the current Codex auth snapshot as a named profile
- Switch between saved profiles
- List profiles with cached usage information
- Optionally show a compact global session-usage footer in
list - Inspect historical local session statistics with
stats - Refresh live usage data for one or all profiles, show progress while refreshing, and then print the updated list
- Inspect saved ID/access token expiration metadata with
token-status - Touch one or all profiles with a minimal Codex request, save the live auth snapshot, and report whether Codex rotated the tokens
- Set up, list, and delete managed cron jobs that run scheduled profile touches
- Update the installed CLI without cloning the repository
- Add Bash completion support for common commands and saved profile names
These must already exist before codex-auth is usable:
- Bash
- The
codexCLI installed and working
The installer can check for and, on supported systems, best-effort install these dependencies:
python3for the utility's JSON and network helperscurlfor no-clone installs and updatesfzffor the nicer interactive profile picker- Bash completion support for auto-loading completions
Notes:
install.sh --install-depscurrently supports Homebrew,apt-get,dnf, andpacman.- The installer does not install the
codexCLI for you.
bash <(curl -fsSL https://raw.githubusercontent.com/Fasand/codex-auth/main/install.sh)If dependencies are missing, the installer will report them and, in an interactive shell, offer to install supported ones.
./install.shThis installs:
codex-authto~/.local/bin/codex-auth- Bash completions to
~/.local/share/bash-completion/completions/codex-auth
You can change the destination with --prefix, --bin-dir, --completion-dir, or skip completions entirely with --skip-completions.
Check the current machine without installing anything:
./install.sh --check-deps--check-deps prints a short status view with green/red indicators so you can quickly see what is available and what is missing.
Install supported dependencies non-interactively:
./install.sh --install-depsRemote install plus dependency installation:
bash <(curl -fsSL https://raw.githubusercontent.com/Fasand/codex-auth/main/install.sh) --install-depsYou have two supported update options:
- Run the built-in updater:
codex-auth update- Re-run the install command directly:
Examples:
./install.shbash <(curl -fsSL https://raw.githubusercontent.com/Fasand/codex-auth/main/install.sh)Existing installations continue to update in place; you do not need to remove anything first.
The repository keeps retained release tags so you can install specific historical versions when needed. Use the same raw GitHub pattern, but replace main with a tag such as 0.3.0:
bash <(curl -fsSL https://raw.githubusercontent.com/Fasand/codex-auth/0.3.0/install.sh) \
--from https://raw.githubusercontent.com/Fasand/codex-auth/0.3.0You can also install any other retained tag the same way:
bash <(curl -fsSL https://raw.githubusercontent.com/Fasand/codex-auth/<tag>/install.sh) \
--from https://raw.githubusercontent.com/Fasand/codex-auth/<tag>For older 0.x release lines, the repo keeps the 0.x.0 tag and the latest patch tag from that line.
By default, the installer downloads from this repository's main branch. If you are testing a fork or a different raw file base, override it with --from or CODEX_AUTH_INSTALL_FROM.
codex-auth update also respects CODEX_AUTH_INSTALL_FROM, so advanced users can point self-update at an alternate raw base without cloning the repository.
Examples:
bash <(curl -fsSL https://raw.githubusercontent.com/Fasand/codex-auth/main/install.sh) \
--from https://raw.githubusercontent.com/someone/codex-auth/mainCODEX_AUTH_INSTALL_FROM=file:///path/to/codex-auth ./install.shcodex-auth list
codex-auth list --utc
codex-auth list --with-stats
codex-auth current
codex-auth current --utc
codex-auth save work
codex-auth switch work
codex-auth refresh-usage
codex-auth refresh work --with-stats
codex-auth token-status
codex-auth token-status work --utc
codex-auth touch work
codex-auth touch --all
codex-auth cron
codex-auth cron setup
codex-auth cron add --time 08:30 --yes
codex-auth cron delete
codex-auth stats
codex-auth stats --period 7d
codex-auth stats --recompute
codex-auth update
codex-auth --versionRun codex-auth help for the full command reference.
list,current,refresh-usage, andrefreshdisplay reset/check timestamps in your local timezone by default.- Pass
--utcto any of those commands if you want the older UTC-style output. - If a local timezone cannot be determined, the CLI falls back to UTC.
codex-auth refresh-usageandcodex-auth refreshrefresh usage data from ChatGPT Codex usage endpoints. They do not perform a Codex OAuth token refresh by themselves.codex-auth refresh-usageorcodex-auth refreshwith no profile name asks for confirmation before refreshing every saved profile.- Multi-profile refreshes show progress as each profile is processed; interactive terminals use a single live-updating line, while non-interactive output stays line-based.
- If one or more profiles fail to refresh, the command still finishes the rest of the batch, prints the updated profile list, and then summarizes the failures before exiting non-zero.
- Refresh prints the updated profile list quickly by default. Pass
--with-statsif you also want the slower local-session usage footer after the refresh.
codex-auth token-status [profile|--all]shows saved ID-token and access-token expirations, last refresh time, and whether a refresh token is present. With no profile name, it lists all saved profiles.codex-auth touch <profile>|--allswitches to each target profile, runs a minimal non-interactivecodex execprompt in a temporary empty directory, saves the liveauth.jsonback to that profile, reports whether the ID/access tokens actually changed, and then restores the profile that was active before the touch.- The touch command uses
--ephemeral,--ignore-user-config,--ignore-rules,--skip-git-repo-check, and a read-only sandbox to keep the request small and avoid loading MCP/user/project customizations. - Codex does not necessarily rotate tokens on every touch. If the current access token is still acceptable to Codex,
touchcan complete successfully and report that tokens were unchanged. - Touching profiles consumes a small amount of Codex usage because it sends a real request.
- The cron commands require a working user
crontabcommand on the machine where you schedule the job. codex-auth cronorcodex-auth cron listshows cron jobs managed by this tool.codex-auth cron setupstarts an interactive wizard. It lists existing managed jobs, asks whether to touch all profiles or one profile, asks for a daily or custom schedule, previews the exact cron fields and command, and then asks for confirmation. Ifwhiptailis available in an interactive terminal, the wizard uses that dialog UI; otherwise it falls back to colored numbered prompts with readline-style editing where Bash supports it.codex-auth cron add --time 08:30 --yesinstalls a daily scheduledtouch --alljob without prompts.codex-auth cron add --time 07:15 --profile work --yesschedules a single profile every day.codex-auth cron add --schedule "30 8 * * 1,3,5" --yesuses a custom cron expression, such as Monday/Wednesday/Friday at 08:30.codex-auth cron deletelets you choose a managed job to remove;codex-auth cron delete --all --yesremoves every codex-auth-managed touch job.- Cron entries are wrapped in
# BEGIN codex-auth touch .../# END codex-auth touch ...markers, so delete/list operations only manage jobs created bycodex-auth. - Scheduled touch output is appended to
~/.codex/accounts/cron/touch.logby default. The cron runner prints timestamped start/end lines around the normaltouchoutput. - Generated jobs call
codex-auth cron run ...instead oftouchdirectly so logs include the managed job id, start/end timestamps, and final exit status without making the crontab line itself more complex. - If you use a non-default
CODEX_HOME, the generated cron command preserves it. The generated command also sets a minimalPATHcontaining the resolvedcodexexecutable's directory, which helps cron runcodexinstallations from tools likenvmwithout depending on your interactive shell startup files. - Set
CODEX_AUTH_DISABLE_WHIPTAIL=1if you prefer the plain numbered cron setup prompts even whenwhiptailis installed.
codex-auth list --with-statsadds a compact two-line footer with global local-session usage for today and 7d when rollout history exists.codex-auth refresh-usage --with-statsandcodex-auth refresh --with-statsinclude that same footer after refreshing and listing profiles.codex-auth statsis the primary command for historical usage;codex-auth statisticsis an alias.- The stats view always shows overview columns for
today,7d,14d,30d, andall, then focuses the daily/model breakdown on30dby default. - Use
--period today|7d|14d|30d|allto change that deeper focus, and--utcto use UTC day boundaries instead of local time. - Parsed rollout-session data is cached under
~/.codex/accounts/session-stats-cache.jsonby default. Unchanged session files are reused on laterstats/--with-statsruns, while changed files are reparsed automatically. - Pass
codex-auth stats --recomputeto ignore and rewrite the session stats cache. - Estimated cost is shown as API-equivalent cost based on cached official OpenAI pricing, not your actual ChatGPT subscription charge.
The repo includes completions/codex-auth.bash, which enables tab completion for:
- top-level commands such as
list,switch,refresh-usage,refresh,token-status,touch,cron, andupdate - saved profile names read from
~/.codex/accounts/profiles --all,--utc,--with-stats,--period,--recompute, and cron flags such as--time,--schedule,--profile, and--yesfor the relevant commands
If your shell does not auto-load completions from the installed directory, add this to ~/.bashrc:
source "$HOME/.local/share/bash-completion/completions/codex-auth"If you want system-provided Bash completion auto-loading, install your distro's bash-completion package.
Bash completion auto-loading typically requires Homebrew's bash-completion@2 package. Even without it, you can still source the installed completion file manually:
source "$HOME/.local/share/bash-completion/completions/codex-auth"- Profiles are stored under
~/.codex/accounts/profiles - The active auth file remains
~/.codex/auth.json - Usage refresh talks to ChatGPT Codex usage endpoints using the saved access token
- Saved profile metadata tracks both ID-token and access-token expirations
- Session statistics parse rollout JSONL files under
~/.codex/sessions - Pricing for session cost estimates is cached under
~/.codex/accounts/pricing-cache.jsonfor one week by default - Parsed session statistics are cached under
~/.codex/accounts/session-stats-cache.jsonby default - Scheduled touch logs are written under
~/.codex/accounts/cron/touch.logby default - Terminal colors are enabled automatically on color-capable terminals and can be disabled with
NO_COLOR=1 - This project is intentionally small and practical; the code favors usefulness over ceremony
tests/smoke.shexercises the version flag, dependency report, README-style installer path, reinstall/update behavior, timezone-aware list output, refresh/list workflows, touch behavior, and managed cron setup.- GitHub Actions runs that smoke test on Ubuntu and macOS for pushes and pull requests.
MIT