Home / Articles

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.

Publisher: REACTAPP.TOP5 min read1062 words

This article is published in English.

Sources: How to set up OpenAI Codex with LiteLLM

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.