Point OpenAI Codex at a LiteLLM proxy for routed models and budgets
Point OpenAI Codex at one LiteLLM proxy URL and get routed access to many models, centralized cost logs and per-developer virtual keys with their own budgets.
This article is published in English.
This walkthrough points OpenAI Codex at a LiteLLM proxy you run (or your team already hosts). Codex reads one base URL from config, so a proxy gives you multi-model routing, centralized logs/cost, per-developer keys with budgets, and one upstream provider key on the server.
Requirements
Docker (or an existing LiteLLM endpoint), Codex CLI or desktop app, and access to at least one upstream model provider.
1. Install OpenAI Codex
Follow current install docs for CLI/desktop. Confirm codex runs locally before wiring a proxy.
2. Configure LiteLLM for model routing
config.yaml
npm install -g @openai/codex
model_list:
# `codex -m <id>` works with any of them.
- model_name: gpt-5.6-terra
litellm_params:
model: openai/gpt-5.6-terra
api_key: os.environ/OPENAI_API_KEY
- model_name: gpt-5.6-luna
litellm_params:
model: openai/gpt-5.6-luna
api_key: os.environ/OPENAI_API_KEY
- model_name: gpt-5.6-sol
litellm_params:
model: openai/gpt-5.6-sol
api_key: os.environ/OPENAI_API_KEY
# Anything from another provider goes in the same list.
- model_name: claude-sonnet-5
litellm_params:
model: anthropic/claude-sonnet-5
api_key: os.environ/ANTHROPIC_API_KEY
# Catch-all, so `codex -m <anything>` reaches OpenAI without editing
# this file. Delete this entry to restrict a fleet to the list above.
- model_name: "*"
litellm_params:
model: openai/*
api_key: os.environ/OPENAI_API_KEY
litellm_settings:
drop_params: true
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
# Coding turns stream for a long time. Do not cut them off.
request_timeout: 600
name: litellm-coding-agents
services:
litellm:
image: ghcr.io/berriai/litellm:main-stable
restart: unless-stopped
command: ["--config", "/app/config.yaml", "--port", "4000"]
ports:
- "4000:4000"
volumes:
- ./config.yaml:/app/config.yaml:ro
env_file:
- .env
environment:
DATABASE_URL: postgresql://litellm:litellm@postgres:5432/litellm
STORE_MODEL_IN_DB: "True"
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "python -c \"import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:4000/health/liveliness').status==200 else 1)\""]
interval: 10s
timeout: 5s
retries: 12
start_period: 30s
postgres:
image: postgres:16-alpine
restart: unless-stopped
# Deliberately not published to the host. Nothing outside this
# network needs it, and 5432 is usually already taken.
environment:
POSTGRES_USER: litellm
POSTGRES_PASSWORD: litellm
POSTGRES_DB: litellm
volumes:
- litellm-pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U litellm -d litellm"]
interval: 5s
timeout: 5s
retries: 20
volumes:
name: litellm-pgdata
OPENAI_API_KEY=... ANTHROPIC_API_KEY=... LITELLM_MASTER_KEY=sk-1234
docker compose up -d
curl -s http://localhost:4000/health/liveliness
curl -s http://localhost:4000/v1/models -H "Authorization: Bearer sk-1234" | head -c 400
lsof -nP -iTCP:4000 -sTCP:LISTEN
cp ~/.codex/config.toml ~/.codex/config.toml.bak 2>/dev/null || true
model = "gpt-5.6-terra" model_provider = "litellm" model_reasoning_effort = "medium" [model_providers.litellm] name = "LiteLLM Gateway" base_url = "http://localhost:4000/v1" # More on setting up LITELLM_API_KEY towards the end env_key = "LITELLM_API_KEY" # Codex talks the Responses API. wire_api = "responses" # A coding turn can stream for long time, hence the setting below stream_idle_timeout_ms = 7200000 stream_max_retries = 5 request_max_retries = 4 # Codex cli complains if not in a trusted folder [projects."/path/to/your/project"] trust_level = "trusted"
codex exec "reply with the word CONNECTED and nothing else"
launchctl setenv LITELLM_API_KEY "sk-1234"
export LITELLM_API_KEY=""
codex -m gpt-5.6-luna
# Optional profiles # Saved model plus reasoning-effort pairs. `codex --profile deep`. [profiles.fast] model = "gpt-5.6-luna" model_reasoning_effort = "low" [profiles.deep] model = "gpt-5.6-sol" model_reasoning_effort = "high"
codex --profile deep
Map friendly model aliases to upstream deployments. Keep secrets in environment variables, not the yaml committed to git.
3. Start the LiteLLM proxy
docker-compose.yml
Bring the proxy up and health-check the /models endpoint.
4. Configure Codex to use LiteLLM
~/.codex/config.toml
Set the base URL to your proxy and use a virtual key LiteLLM issued—not the raw provider key.
5. Run Codex
Issue a simple coding task and confirm LiteLLM logs show the routed model and token usage.
6. Desktop app
Point the desktop client at the same base URL/key so CLI and UI share budgets.
Advanced options
Virtual keys
Per-developer keys with model allowlists and spend caps stop one runaway session from burning the org budget.
Using different models
Change the alias in Codex config or per-request; LiteLLM handles upstream differences.
Additional resources
Keep LiteLLM and Codex versions pinned; proxy auth and model alias drift are the usual breakages after a quiet month.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.
Security note: treat the proxy as a production service—TLS, network allowlists, and key rotation—because it concentrates provider credentials and sees every prompt.