vachi-codex
v0.7.2
Published
Route the OpenAI Codex CLI through the Vachi gateway. Keeps your ChatGPT/OpenAI login untouched (auth passthrough).
Maintainers
Readme
vachi-codex
Route the OpenAI Codex CLI through the Vachi gateway — your
ChatGPT-plan OAuth login (or your own OpenAI API key) stays untouched and is forwarded to OpenAI
as-is (auth passthrough). Your Vachi identity rides in a single x-vachi-id header.
npx vachi-codexThat's it: a browser window signs you in to Vachi (same sign-in and credential file as
vachi-claude — one login covers both), then Codex is configured to route through the gateway.
Run codex as usual.
Commands
| Command | What it does |
|---|---|
| npx vachi-codex | Sign in (if needed) and configure Codex |
| npx vachi-codex status | Show current configuration |
| npx vachi-codex doctor | Read-only health checks (config, login, gateway reachability) |
| npx vachi-codex login | Re-run the browser sign-in |
| npx vachi-codex disable | Restore your previous Codex config |
| npx vachi-codex disable --purge | …and delete stored credentials |
| npx vachi-codex footer <on\|off\|quiet> | Set how often the gateway appends its footer (on=every_turn default, off, quiet=milestones); no arg shows the current mode |
Custom gateway
By default everything points at https://gateway.vachiai.com. To route through your own gateway
(self-hosted, staging, or local), pass --custom-base-url on enable:
npx vachi-codex enable --custom-base-url https://gateway.example.comOr set VACHI_GATEWAY_URL (the flag wins if both are present). It's written into the provider
base_url (<url>/v1) and recorded, so a later disable / doctor — and a footer change —
keep targeting it without repeating the flag.
What it changes (and what it never touches)
Two managed edits to ~/.codex/config.toml (a timestamped backup is taken first, kept under
~/.vachi/backups/), everything else preserved byte-for-byte:
A clearly fenced provider block appended at the end of the file:
# >>> vachi-codex BEGIN — managed by `npx vachi-codex`; do not edit by hand. [model_providers.vachi] name = "Vachi gateway (OpenAI passthrough)" base_url = "https://gateway.vachiai.com/v1" wire_api = "responses" requires_openai_auth = true http_headers = { "x-vachi-id" = "vachi_sk_…", "x-vachi-footer" = "every_turn" } # <<< vachi-codex ENDThe top-level
model_provider = "vachi"line (tagged# vachi-codex:managed). If you already had a top-levelmodel_provider, the exact prior line is snapshotted to~/.vachi/state/codex.jsonand restored verbatim bydisable.
It never touches ~/.codex/auth.json — your existing Codex login (ChatGPT plan OAuth or
codex login --api-key) is what the gateway forwards upstream: requires_openai_auth = true
tells Codex to keep attaching it. No env_key is set, so nothing leaks into your shell profile
or ps output.
Credentials are stored at ~/.vachi/credentials.json (mode 0600, shared with vachi-claude).
Requirements
- Node.js ≥ 18, macOS or Linux (Windows: WSL)
- Codex CLI installed (
codexon PATH, or an existing~/.codex/) - A Codex login (
codex login) — the gateway forwards it, it can't mint one for you
Login (identical to vachi-claude)
Login is the device-authorization flow, shared byte-for-byte with vachi-claude via the
vendored lib/activation.js: a browser opens for you to sign in and approve
this device, the key is fetched over TLS (nothing to paste on the happy path), and a paste-a-code
fallback is offered concurrently for headless/blocked cases (a one-time PIN the CLI swaps for the
key via exchange; the durable key never touches the page or clipboard). The key is validated with a live
ping before it's saved to the shared ~/.vachi/credentials.json, so signing in once covers both
installers. First-ever install on a machine is greeted with a welcome message.
Backend dependency (for maintainers)
See docs/activation_frontend_spec.md and the gateway
repo's docs/BOUNDARY_SPEC.md for the full device-grant contract: POST {gateway}/v1/activate
(start/poll/approve/deny/reveal/exchange/confirm), keys minted in-process at approve, the required
confirm handshake, and the /v1/usage ping. The activation endpoint defaults to
{gateway}/v1/activate; override with VACHI_ACTIVATE_URL and the gateway with
VACHI_GATEWAY_URL for staging/local. Gateway-side, the Codex path is the OpenAI Responses
passthrough (spec §4, tasks I1/I2).
Development
node test/smoke.test.js # enable/status/disable round-trip against a throwaway HOME
node ../test/lib-parity.test.js # asserts lib/activation.js is byte-identical to vachi-claude's