Use a policy-scoped ClawRouter key and an OpenAI Platform API grant. The shared router supports native Responses HTTP, SSE, and explicitly qualified WebSocket routes. This setup keeps normal Codex tools, approval settings, and model prompts.
From a ClawRouter checkout with its dependencies installed, create a separate Codex CLI profile. Export the issued client key in the shell that will launch Codex; the setup command does not store it or edit shell startup files.
export CLAWROUTER_API_KEY="$(cat /path/to/client-key.txt)"
pnpm codex:connect connect \
--router-url https://router.example.com \
--provider openai --model gpt-6-astra --service-tier priority \
--codex /path/to/codex --dry-run
# Repeat without --dry-run to apply the displayed field changes.
# Run the returned launch command; it preserves --codex and --codex-home.
/path/to/codex --profile clawrouterThis creates $CODEX_HOME/clawrouter.config.toml and a complete native catalog
beside it. The default home is ~/.codex. Use --profile NAME or
--codex-home DIR to choose another installation. Codex 0.153.0 and 0.155.0 load
separate <name>.config.toml profile files over the base configuration;
[profiles.NAME] is not the supported format. Existing profiles are never
adopted or overwritten by connect. The base config.toml, auth.json, sandbox
and approval settings, and key file stay unchanged. This command configures the
CLI; Desktop uses the explicit root target described below.
The profile selects the requested upstream model and the router's native provider URL. Each exported model needs an eligible native HTTP Responses offer in the issued key's catalog. Provider readiness, session access, and model-less operation forms do not qualify a model. Use a router version that publishes operation offers; older catalogs fail setup before any files change.
The profile disables hosted web search and enables WebSockets only when every
exported model has a matching WebSocket offer for the same endpoint, route,
policy, and generation. Codex applies that flag to the whole provider, including
internal models. Catalog observations do not reserve budget or probe upstream;
token-priced offers remain request-dependent, and dispatch checks access and
budget again. --service-tier defaults to
default; request priority explicitly for Fast. A missing native descriptor
or unqualified priority tier fails before installation. Use a producer that
contains the selected model, such as Codex 0.155.0 for Astra.
pnpm codex:connect verify --codex /path/to/codex
pnpm codex:connect update --codex /path/to/codex --dry-run
pnpm codex:connect update --codex /path/to/codex
pnpm codex:connect remove --dry-run
pnpm codex:connect removePass the same profile/home options on each command when using non-default
paths. verify checks catalog access with the issued key, native metadata
freshness, and owned profile settings. It makes no inference requests and does
not prove that an upstream account can serve the model. Managed requirements,
project settings, and command-line overrides still apply when Codex starts.
--key-file PATH can supply the key to a setup command without changing that
file; subsequent Codex processes still need CLAWROUTER_API_KEY exported.
update writes a complete nonempty catalog generation before atomically
switching the profile and its ownership receipt. Failed preparation leaves
the previous profile and catalog usable. Earlier catalog generations stay
available until remove, so a concurrently starting client can finish loading
the profile it already read. Restart Codex after an update; running
clients do not reload the static catalog. Changes and dry-run summaries list
field names and catalog hashes, never keys or model instructions.
The profile's first comment is an ownership receipt; keep it intact. Updates
preserve user-added fields and comments and refuse changed owned fields.
To change connection settings, remove and reconnect. remove deletes only
unchanged owned fields and catalog files; modified fields/files remain and
are reported. If the user changes the catalog pointer, all published catalog
generations remain available for that retained reference. It keeps unrelated
additions and does not revoke the key. An empty generated provider table is
removed; user-added provider settings retain the required provider name.
Credential revocation is a separate operator action through the admin UI or
pnpm cf:key:revoke -- --kid <credential-id>. If an interrupted process leaves
a profile lock directory, check that no setup command is still running before
removing that named lock.
Fully quit Desktop before connect, update, or remove. These commands edit
$CODEX_HOME/config.toml, which also supplies defaults to CLI sessions without
a named profile. They preserve authentication files, sandbox and approval
settings, reasoning effort, existing tier preferences, and unrelated config.
pnpm codex:connect connect --target desktop \
--router-url https://router.example.com \
--provider openai --model gpt-6-astra \
--codex /path/to/codex-0.155 --dry-run
# Review the field changes, then repeat without --dry-run.
pnpm codex:connect verify --target desktop --codex /path/to/codex-0.155
pnpm codex:connect update --target desktop --codex /path/to/codex-0.155
pnpm codex:connect remove --target desktopUse --codex-home DIR consistently if Desktop uses another home. --codex
selects the metadata producer; it does not replace the app's embedded engine.
Desktop does not accept --profile or --service-tier. The installed app's
API-key mode clears Fast even when an existing root preference requests priority.
Use the CLI profile workflow when you need to request priority through ClawRouter.
The root file's first comment records the original value or absence of each
owned routing setting. Keep that receipt intact. A dedicated provider collision
or active legacy profile selector fails explicitly. Existing unrelated providers
and profiles remain; ordinary and inline provider tables are supported.
update refuses changed owned fields. remove restores model, provider, catalog,
and hosted-search settings together only when all still match the installation.
On a conflict it preserves the whole connection and reports the field names.
User-added provider settings survive with their required name; an edited inline
provider stays intact with its catalog generations. Removal does not revoke keys.
One root lock coordinates setup commands. Rereading before replacement detects observed edits; it cannot lock out an unrelated editor or running app. Keep the app closed during changes. Catalogs are installed before the atomic root-config switch, and failed preparation keeps the previous configuration usable.
Export the key from the actual interactive login shell that the macOS launcher
reads. For zsh, add a loader to .zshrc using the saved key file's real path:
if [ -r "$HOME/.config/clawrouter/client-key.txt" ]; then
export CLAWROUTER_API_KEY="$(cat "$HOME/.config/clawrouter/client-key.txt")"
fiThe setup command does not edit shell startup or launchctl state. A Terminal
export does not change an already-running app. Fully quit and restart Desktop,
then start a new thread. Never put an admin, upstream provider, or ChatGPT token
in CLAWROUTER_API_KEY; use only the issued router client key.
Codex needs its complete model descriptor, including instructions and service tiers. A model name alone can select fallback metadata. Export the official bundled descriptors through the authorized ClawRouter catalog:
export CLAWROUTER_API_KEY="<issued ClawRouter credential>"
node scripts/codex-catalog.mjs \
--router-url https://router.example.com \
--provider openai \
--codex /path/to/codex \
--output ./clawrouter-models.jsonUse a Codex producer whose codex debug models --bundled contains the requested
models. Codex 0.155.0 includes Astra; the 0.153.0 bundle does not. Both engines
can consume the exported Astra descriptor. The helper preserves the producer's
instructions, context limits, and internal model metadata, changes only the
public model slug, and narrows paid tiers to the router's priced contract.
Missing descriptors are reported on stderr; the helper never invents prompts.
Stderr also records the producer version, input hashes, route mappings, and base URL.
The OpenAI export uses upstream slugs such as gpt-6-astra and
gpt-5.6-luna. This lets native internal model requests use the same provider
base. The documented gpt-5.6 API alias uses Sol's descriptor. Refresh the file
after changes to the authorized router catalog or the producer's bundled models.
Merge these settings into the shared user configuration, $CODEX_HOME/config.toml
(default ~/.codex/config.toml). CLI and Desktop instances using the same directory
share this base; profiles can override it. Project configuration cannot select a
different provider. Keep existing
sandbox, approval, workspace, and tool settings. Set model_catalog_json to the absolute
path of the exported file on that machine, or a relative path beside the
configuration file. TOML does not expand shell variables in that path.
model = "gpt-6-astra"
model_provider = "clawrouter"
model_catalog_json = "/absolute/path/to/clawrouter-models.json"
model_reasoning_effort = "high"
service_tier = "priority"
web_search = "disabled"
[model_providers.clawrouter]
name = "ClawRouter"
base_url = "https://router.example.com/v1/native/openai/v1"
wire_api = "responses"
env_key = "CLAWROUTER_API_KEY"
requires_openai_auth = false
supports_websockets = trueEnable supports_websockets only when the authenticated catalog's Responses
route reports websocket: "openai.responses". Alternate subscription transports
are not qualified for this bridge. HTTP/SSE remains available with the flag set
to false. The provider-native base also supports bare internal Sol, Terra, and
Luna requests; a unified, namespaced-only catalog does not cover those lookups.
HTTP/SSE and WebSockets bind returned response IDs and Codex turn state to their original
credential owner. A 409 continuation_restart_required requires a fresh request
with full input and no continuation fields; another account cannot resume that
state. Unknown or expired identities, including state created before this router
upgrade, are rejected before upstream dispatch. Owner-controlled refresh keeps
the binding, while explicit credential replacement requires a restart. Stateless
requests and known environment/API-key continuations remain supported. See
Responses continuation limits.
priority requests Fast routing. In Codex 0.153.0 and 0.155.0, default disables
the Fast override but is omitted from the wire; upstream project defaults can
still apply. Direct API clients can send service_tier: "default" explicitly.
The upstream may serve a different tier; usage records contain both requested
and served values. Admission reserves a conservative priced envelope, and complete
terminal usage settles at the actual served tier. Missing tier or cache counters
retain the estimate. With both budgets disabled, undeclared request tiers can
forward; unknown final prices are marked unavailable rather than reported as free.
The monthly allowance is ClawRouter list-price accounting,
not a guarantee about the provider invoice. See spend control.
CLI and engine priority forwarding is separate from the Desktop Fast control.
The inspected macOS build 26.901.22334 (7746), with embedded Codex 0.153.0,
clears Fast in API-key mode (upstream report).
Its account gate sends serviceTier: null; changing the root priority preference
does not bypass that gate. Setup keeps requires_openai_auth = false and the
explicit router env_key. It does not fabricate a ChatGPT account or change the
provider's authentication requirement to expose an account-only control.
The installed 0.153.0 app engine and 0.155.0 CLI are covered by isolated native
fixtures for account state, catalog loading, Lite payloads, priority forwarding,
and bearer ownership. Root setup fixtures separately check config/account reads
and connect/update/remove through synthetic native turns, including the GUI's
null-tier request shape. Native fixtures do not prove the graphical controls,
microphone permission, or an account's entitlement. Desktop dictation uses a
separate authenticated OpenAI /transcribe request. Dictation and Realtime remain
unqualified by this setup; Responses WebSockets do not proxy those voice services.
The isolated native fixture also exercises synchronous Guardian approval with
the official catalog, a key-only loopback provider, and a prompt-approved
synthetic MCP echo. On both 0.153.0 and 0.155.0, the native reviewer selected
gpt-6-astra: an allow decision invoked the tool once; a deny decision invoked
it zero times. Review notifications matched the target call, thread, and turn.
These cases emitted no Luna classifier traffic and do not qualify asynchronous
Guardian scoring, genuine upstream review decisions, or the Desktop UI.
No ChatGPT login or user approval RPC is fabricated for these tests.
To run the opt-in fixtures, set CLAWROUTER_CODEX_BINARY to the official binary
and CLAWROUTER_CODEX_CATALOG_BINARY to a 0.155.0 catalog producer, then run
node --test test/codex-native.test.mjs. Ordinary script tests skip native cases when
the binary is absent. Each case removes its temporary home and loopback server.
node --test test/codex-router.test.mjs also runs those engines through the actual
Worker, authority, and SQL budget/usage ledgers with an isolated synthetic
upstream. It covers credential-scoped metadata discovery, HTTP and WebSocket
priority requests, a tool continuation, two turns, cancellation during active response
delivery, upstream shutdown, and settlement in both ledgers. It also verifies a
fresh turn after interruption, same-ID proxy-key rotation across native processes,
and revocation before the next turn. CI downloads checksum-pinned official Linux
engines for 0.153.0 and 0.155.0; neither case needs an account or paid upstream call. This qualifies
native engine routing, not macOS Desktop UI behavior or live model quality.
The cancellation case requires upstream shutdown before the native idle timeout.
It does not qualify stalled HTTP/1 streams: ordinary socket closure and native
interruption with no further upstream output left the fixture reservation
unsettled at five seconds. An explicit TCP reset did propagate an ingress abort
and cancellation receipt. Codex 0.153 also waits for the next recognized SSE
event to notice a dropped consumer. Stalled-stream shutdown and deployed protocol
behavior, including HTTP/2, still require qualification.
See the Responses WebSocket contract for per-create authorization, accounting, continuation, and connection limits.
Azure OpenAI supports /v1/native/azure-openai/openai/v1/responses with an
explicit deployment model and api-key authentication. This v1 route does not
inherit the dated api-version used by legacy chat and embedding routes.
OpenRouter supports /v1/native/openrouter/v1/responses, preserving upstream
namespaced models such as openai/gpt-6-astra. These endpoints support HTTP/SSE;
they do not inherit OpenAI's WebSocket qualification or Codex metadata.
Unknown deployments and routing aliases have no invented prices or model
descriptors. A policy or provider budget requires declared pricing or an explicit
fixed policy tariff. For concrete provider models, both /v1/models and /v1/catalog apply the same selected
policy, provider budget, and eligible grant transport. Verify the chosen upstream
account and model before use.
Fusion discovery applies the same Chat model eligibility to its configured synthesizer and advisers; unavailable advisers remain optional. Hosted search is rejected before dispatch under measured policy or provider budgets unless a fixed policy tariff is configured. Full hosted-tool fee metering remains separate. Keep this setup's hosted web search disabled: token rates do not cover its tool fees or repeated search input. Dispatched requests retain their budget charge across the 15-minute admission lease; late settlement uses the original ledger receipt within its 45-day retention period.
Sources: Codex custom providers, Responses WebSockets, OpenAI pricing, and the official Codex 0.153.0 and 0.155.0 source contracts.