The Codex CLI stores a working OpenAI credential on your machine after you log in. codexpass reads that credential and lets your other tools use it. You can print shell export lines, grab the raw token, or run a local OpenAI-compatible server for editors, SDKs, and scripts. No separate API key to set up.
Install · Usage · Local proxy · Configuration · Releases
After codex login, the Codex CLI saves a working OpenAI credential in
~/.codex/auth.json. codexpass reads that file. If the token has expired, it
refreshes it with the stored refresh token and writes the new token back safely
with 0600 file permissions. Then it hands you the credential in the shape you
need.
Download a prebuilt binary for Linux, macOS, or Windows from the latest release, or install with Go:
go install github.com/hdprajwal/codexpass@latestOr build from source:
git clone https://github.com/hdprajwal/codexpass
cd codexpass
make build # produces ./codexpassLoad the credential into your current shell session:
eval "$(codexpass export)"Now OPENAI_API_KEY (and, in ChatGPT mode, OPENAI_BASE_URL) are set for every
tool you run in that session.
Grab the bare token for a script or to paste into code:
KEY=$(codexpass token)Export only the key, without the base-URL override:
eval "$(codexpass export --no-base-url)"Check your local Codex login:
codexpass doctor
codexpass doctor --json
codexpass doctor --live # also checks the upstream models endpointcodexpass serve runs a local OpenAI-compatible server and forwards requests to
the Codex backend. It supports /v1/chat/completions, /v1/responses,
/v1/models, /healthz, and optional /metrics.
codexpass serve --port 8080
codexpass serve --port 8080 --token local-secret
codexpass serve --metrics --log-format json --stats-path ~/.cache/codexpass/usage.jsonlIn Zed settings.json (the schema may change between Zed versions, so check
the current docs):
{
"language_models": {
"openai_compatible": {
"Codex": {
"api_url": "http://localhost:8080/v1",
"available_models": [
{ "name": "gpt-5.6", "display_name": "GPT-5.6 Sol (Codex)", "max_tokens": 272000 },
{ "name": "gpt-5.6-sol", "display_name": "GPT-5.6 Sol (Codex, explicit)", "max_tokens": 272000 },
{ "name": "gpt-5.6-terra", "display_name": "GPT-5.6 Terra (Codex)", "max_tokens": 272000 },
{ "name": "gpt-5.6-luna", "display_name": "GPT-5.6 Luna (Codex)", "max_tokens": 272000 }
]
}
}
}
}When Zed asks for an API key, enter the --token value, or any placeholder if
you did not set one. The real Codex credential stays inside the proxy.
A few caveats. Requests count against your ChatGPT subscription quota. The
Codex backend does not serve embeddings, images, or audio; those endpoints
return 501 unless you explicitly configure a fallback backend. The proxy is
meant for personal, local use. Keep it bound to loopback (the default) and do
not expose it to others.
List models available to your current Codex credential:
codexpass models listGPT-5.6 has three tiers: gpt-5.6-sol for frontier capability,
gpt-5.6-terra for a balance of intelligence and cost, and gpt-5.6-luna
for efficient high-volume work. When Sol is available, codexpass also exposes
OpenAI's official gpt-5.6 alias and resolves it to gpt-5.6-sol if the
upstream model catalog does not already provide the alias.
You can also define model aliases. This lets a client ask for a local name while codexpass sends the real Codex model name upstream.
{
"models": {
"cache_ttl_seconds": 300,
"aliases": {
"gpt-codex": "gpt-5.6-sol"
}
}
}With this config, clients can request gpt-codex. codexpass forwards
gpt-5.6-sol upstream.
The proxy accepts common OpenAI chat/completions fields used by SDKs and
editors: model, messages, stream, stream_options.include_usage,
temperature, top_p, max_tokens, max_completion_tokens,
reasoning_effort, safety_identifier, tools, tool_choice, and
response_format. GPT-5.6 reasoning efforts through max and image detail
values including original are preserved. User text, image parts, function
tools, tool results, and structured output are translated to the Responses API.
These fields are accepted for compatibility but ignored by the Codex-backed
route today: metadata, user, n, presence_penalty,
frequency_penalty, stop, logit_bias, and seed. Invalid request shape,
unsupported message roles, non-function tools, and malformed tool_choice
return OpenAI-shaped invalid_request_error responses.
/v1/responses is proxied too. JSON request bodies are validated without
rewriting unknown fields, aliases are resolved, and store defaults to false
when the client does not set it. GPT-5.6 features such as Pro mode, persisted
reasoning, explicit prompt caching, and Programmatic Tool Calling should use
this endpoint. The OpenAI-Beta request header is forwarded for opt-in features
such as the multi-agent beta; client-supplied authorization and account headers
are never forwarded upstream.
For one local secret, use --token:
codexpass serve --token local-secretFor multiple local clients, generate a config snippet:
codexpass token create zedClient policy can restrict endpoints, models, request size, fallback use, and simple per-minute rate limits:
{
"clients": {
"zed": {
"token": "generated-local-token",
"allowed_endpoints": ["models", "chat.completions", "responses"],
"allowed_models": ["gpt-codex", "gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"],
"max_body_bytes": 1048576,
"rate_limit_per_minute": 60,
"allow_fallback": false
}
}
}/healthz stays public. When any token or client policy is configured, all
other endpoints require a matching bearer token.
Verbose logging records request metadata only:
codexpass serve --verbose
codexpass serve --log-format jsonLogs include route, status, latency, and client metadata. They do not include prompts, completions, tool arguments, Authorization headers, API keys, OAuth access tokens, refresh tokens, or id tokens.
Enable Prometheus-style metrics:
codexpass serve --metrics
curl http://localhost:8080/metricsWrite redacted usage events and summarize them later:
codexpass serve --stats-path ~/.cache/codexpass/usage.jsonl
codexpass stats --path ~/.cache/codexpass/usage.jsonlUnsupported endpoints can route to a separate OpenAI-compatible backend. This is off by default.
{
"fallback": {
"enabled": true,
"base_url": "https://api.openai.com/v1",
"api_key_env": "OPENAI_API_KEY"
}
}When enabled, /v1/embeddings, /v1/images/generations, /v1/audio/speech,
and /v1/audio/transcriptions go to the fallback backend. Those requests may
use a different quota or billing account.
Install codexpass as a user-level background service:
codexpass service install --config ~/.config/codexpass/config.json
codexpass service status
codexpass service uninstallUse --dry-run to print the generated systemd user unit or macOS launchd plist:
codexpass service install --dry-runService installation refuses non-loopback hosts unless you pass --allow-network.
Codex stores credentials in one of two modes:
chatgptmode: you logged in with a ChatGPT subscription. The borrowed value is a ChatGPT OAuth access token, not a normalsk-...key. It only works against the Codex backend, socodexpass exportalso setsOPENAI_BASE_URL=https://chatgpt.com/backend-api/codex, and you have to use Codex model names (gpt-5.x). Some tools also send aChatGPT-Account-IDheader. That header cannot be passed through an environment variable, so tools that do not send it may fail.codexpassprints your account id to stderr as a reminder.apikeymode: you logged in with an API key. The borrowed value is a real OpenAI API key that works againstapi.openai.com.codexpassexports justOPENAI_API_KEYand leaves the base URL alone.
| Command | Description |
|---|---|
codexpass export [--no-base-url] |
Print eval-able export lines to stdout; notes go to stderr. |
codexpass token |
Print the bare borrowed token to stdout. |
codexpass token create NAME |
Generate a local proxy client-token config snippet. |
codexpass doctor [--json] [--live] |
Inspect local Codex auth state without printing secrets. |
codexpass models list |
List available models, including configured aliases. |
codexpass stats --path PATH |
Summarize redacted usage JSONL. |
codexpass serve [--host H] [--port N] [--token S] [--config PATH] |
Run the local OpenAI-compatible server. |
codexpass service install|uninstall|status |
Manage a user-level background proxy service. |
codexpass --version |
Print the version. |
codexpass --help |
Show help. |
CODEX_HOME: override the Codex home directory. The default is~/.codex.CODEXPASS_CONFIG: override the codexpass config path.
The default config path is $XDG_CONFIG_HOME/codexpass/config.json, or
~/.config/codexpass/config.json when XDG_CONFIG_HOME is unset. If the file
does not exist, codexpass uses its defaults.
Example:
{
"server": {
"host": "127.0.0.1",
"port": 8080,
"log_format": "json",
"metrics": true,
"stats_path": "/home/me/.cache/codexpass/usage.jsonl",
"retry_attempts": 3
},
"models": {
"cache_ttl_seconds": 300,
"aliases": {
"gpt-codex": "gpt-5.6-sol"
}
},
"clients": {
"zed": {
"token": "generated-local-token",
"allowed_endpoints": ["models", "chat.completions", "responses"],
"allowed_models": ["gpt-codex", "gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"],
"max_body_bytes": 1048576,
"rate_limit_per_minute": 60,
"allow_fallback": false
}
},
"fallback": {
"enabled": false,
"base_url": "https://api.openai.com/v1",
"api_key_env": "OPENAI_API_KEY"
}
}codexpass serve flags override config-file server values.
make test # go test ./...
make vet # go vet ./...
make build # build ./codexpassThe credential-borrowing and token-refresh logic is ported from Simon Willison's llm-openai-via-codex.
Apache-2.0 · Built by HD Prajwal · Contribute