How Codex Router Works — Architecture & Request Flow
Codex Router is a local HTTP service that sits between the Codex App or CLI and external model providers. This page explains why that service exists, what its four moving pieces do, how a request flows through it, and where the security boundaries are.
Why a router is needed
The Codex App expects the Responses API and a Codex-shaped model catalog. Kimi and DeepSeek expose OpenAI-compatible Chat Completions APIs with different authentication and request details. A router is needed to bridge those contracts while leaving native GPT traffic on the normal ChatGPT Codex backend.
The four pieces
- A generated catalog places external models beside native GPT models in Codex’s
model_catalog_json. - A dispatcher chooses native or external routing by namespaced model ID — anything starting with
deepseek/,kimi-oauth/,anthropic-api/and so on goes to the external path. - LiteLLM translates Responses requests, streams and tool calls to each provider’s native protocol, including OpenAI-compatible Chat Completions and Anthropic Messages.
- Credential forwarders inject only the selected provider’s authentication and strip everything else.
Every listener binds to 127.0.0.1, so the whole service is local to your machine.
Request flow
Codex sends a Responses request to the loopback router on port 4102:
| Port | Listener | Role |
|---|---|---|
| 4102 | Router | Receives Codex Responses requests, authenticates the caller |
| 4100 | LiteLLM | Translates Responses to each provider’s native protocol |
| 4101 | Kimi OAuth | Forwards to Kimi with a refreshed OAuth bearer |
| 4103 | API forwarder | Forwards to API-key providers with the selected key |
For a native GPT model, the router forwards the request to the ChatGPT Codex backend with allow-listed Codex headers and the native model ID — the router never sends a native request to an external provider.
For a registry model (for example kimi-oauth/k3), the router validates the caller, passes a gateway model plus an internal key to LiteLLM, which translates the request and hands it to the matching forwarder. The forwarder discards the internal key and injects only the selected provider credential. The stream flows back through LiteLLM as Responses events.
Credential boundaries
| Route | Incoming Codex credential | Upstream credential |
|---|---|---|
| Native GPT | Allow-listed and forwarded | Existing ChatGPT/Codex authentication |
| Kimi OAuth | Discarded | Kimi CLI OAuth bearer from ~/.kimi-code |
| Kimi API | Discarded | Kimi Platform API key |
| DeepSeek | Discarded | DeepSeek API key |
The Codex-to-router and internal-service trust boundaries use two different random keys, each stored with mode 600 or a current-user Windows ACL. External forwarders remove Codex account, installation, attestation and private headers before sending a request upstream.
Security model
- Local caller authentication. The managed base URL contains a separate random capability; the router validates it before reading a model request or contacting any upstream. Codex cannot attach a router-specific header to the built-in provider, so the capability lives in the URL path. Status, migration and support tools redact it.
- No browser access. The router requires JSON content, rejects browser-origin headers, and never grants CORS access.
- Sanitized errors. Network-facing errors are bounded and non-sensitive; raw exception text is replaced.
- No credential leakage. Diagnostics report presence and source, never values. Protected files use mode
600or a current-user ACL.
Transport and compaction
Current Codex builds first attempt a Responses WebSocket; the router responds with HTTP 426 and Codex falls back to HTTP, which is expected behavior. Request bodies may use Zstandard, gzip, deflate or Brotli, and the router safely decompresses them before inspecting the model ID.
External Chat Completions providers cannot create OpenAI’s opaque encrypted compaction payload, so the router asks the selected external model for a continuation summary and wraps it in a router-owned kcr1: payload. On replay it converts that payload back to a plain continuation message.
What stays in Codex
Commands, permissions, MCP tools, skills, agent loops and task state remain in Codex. The router handles model inference and external-model compaction; it cannot add a capability the selected model or provider does not implement.
For collaboration subagents, the router relays the exact native task payload through the already-authenticated native Codex backend — the relay requires an active ChatGPT sign-in and fails closed in login-free mode rather than forwarding unreadable ciphertext to an external provider.
The native catalog is preserved
The integration preserves the built-in OpenAI provider, native GPT models, ChatGPT sign-in, profiles, MCP settings, project trust and reasoning defaults. It adds one marked root block and one inert custom-provider table to the Codex config, and disable restores the previous values exactly.
Related: installation, models overview, troubleshooting.