Skip to content

Instantly share code, notes, and snippets.

@realgenekim
Last active May 17, 2026 19:33
Show Gist options
  • Select an option

  • Save realgenekim/fdba49fafca08689009f9992ed0347eb to your computer and use it in GitHub Desktop.

Select an option

Save realgenekim/fdba49fafca08689009f9992ed0347eb to your computer and use it in GitHub Desktop.
Using Codex Subscription in KiloClaw

KiloClaw is amazing.

Using a ChatGPT Subscription with KiloClaw via the openai-codex Provider

A practical field guide for routing KiloClaw/OpenClaw model calls through a ChatGPT Plus/Pro Codex OAuth session instead of a traditional OpenAI API key.

Why this matters

KiloClaw normally makes model calls through configured model providers. The regular openai provider expects an OpenAI API key and bills through the OpenAI API platform.

But OpenAI's Codex CLI can authenticate with a ChatGPT account using OAuth. OpenClaw also has an openai-codex provider that can use those OAuth credentials. If configured correctly, model calls can be routed through the Codex/ChatGPT subscription path instead of through OPENAI_API_KEY.

The key detail is the model prefix:

openai/gpt-5.5        -> regular OpenAI API provider; requires OPENAI_API_KEY
openai-codex/gpt-5.5  -> Codex provider; uses ChatGPT/Codex OAuth

That prefix is the entire trick.

Tested environment

This was tested inside a hosted KiloClaw instance running OpenClaw, with persistent state under /root.

The same approach should apply to other OpenClaw deployments if:

  • the openai-codex provider is installed/enabled;
  • the OpenAI Codex CLI can be run on the host;
  • OpenClaw stores provider auth profiles in the same OAuth profile format; and
  • the selected model id uses the openai-codex/ prefix.

High-level architecture

Kilo Chat / OpenClaw session
    -> OpenClaw agent runner
    -> model id: openai-codex/gpt-5.5
    -> provider: openai-codex
    -> OAuth profile from auth-profiles.json
    -> OpenAI Codex backend using the ChatGPT account subscription

The model selector chooses the provider by parsing the model id at the first slash:

kilocode/anthropic/claude-opus-4.7 -> provider kilocode
openai/gpt-5.5                     -> provider openai
openai-codex/gpt-5.5               -> provider openai-codex

If you accidentally use openai/gpt-5.5, OpenClaw will try to use the regular OpenAI API provider and may complain that OPENAI_API_KEY is missing. That does not mean the Codex OAuth profile is bad; it usually means the model prefix is wrong.

Step 1: Log in with the Codex CLI

Install/run the OpenAI Codex CLI and authenticate with device auth:

npx @openai/codex login --device-auth

The CLI prints:

  • a URL, usually https://auth.openai.com/codex/device;
  • a short device code; and
  • a timeout window.

Open the URL on your laptop or phone, sign in with the ChatGPT account whose subscription you want to use, and enter the device code.

After successful login, the Codex CLI writes credentials to:

~/.codex/auth.json

The file has a shape like this:

{
  "auth_mode": "chatgpt",
  "OPENAI_API_KEY": null,
  "tokens": {
    "id_token": "...",
    "access_token": "...",
    "refresh_token": "...",
    "account_id": "..."
  },
  "last_refresh": "..."
}

Do not publish this file. It contains live credentials.

Step 2: Copy the Codex OAuth credential into OpenClaw

OpenClaw's provider auth profiles live in an auth-profiles.json file. In the KiloClaw instance tested here, the file was:

/root/.openclaw/agents/main/agent/auth-profiles.json

Other deployments may use a different agent profile path, but the structure is the important part.

The openai-codex OAuth profile should look like this:

{
  "version": 1,
  "profiles": {
    "openai-codex:user@example.com": {
      "type": "oauth",
      "provider": "openai-codex",
      "access": "<access_token>",
      "refresh": "<refresh_token>",
      "expires": 1779550231000,
      "email": "user@example.com"
    }
  },
  "order": {
    "openai-codex": ["openai-codex:user@example.com"]
  },
  "lastGood": {
    "openai-codex": "openai-codex:user@example.com"
  }
}

Here is a reusable injection script. Review it before running; it modifies your OpenClaw auth profile file.

#!/usr/bin/env python3
import base64
import json
from pathlib import Path

codex_auth_path = Path.home() / ".codex" / "auth.json"
openclaw_auth_path = Path("/root/.openclaw/agents/main/agent/auth-profiles.json")

codex = json.loads(codex_auth_path.read_text())
tokens = codex["tokens"]


def decode_jwt_payload(jwt: str) -> dict:
    payload = jwt.split(".")[1]
    payload += "=" * (-len(payload) % 4)
    return json.loads(base64.urlsafe_b64decode(payload))


access_payload = decode_jwt_payload(tokens["access_token"])
id_payload = decode_jwt_payload(tokens["id_token"])

email = id_payload["email"]
expires_ms = access_payload["exp"] * 1000
profile_id = f"openai-codex:{email}"

if openclaw_auth_path.exists():
    auth_profiles = json.loads(openclaw_auth_path.read_text())
else:
    auth_profiles = {"version": 1, "profiles": {}, "order": {}, "lastGood": {}}

auth_profiles.setdefault("version", 1)
auth_profiles.setdefault("profiles", {})[profile_id] = {
    "type": "oauth",
    "provider": "openai-codex",
    "access": tokens["access_token"],
    "refresh": tokens["refresh_token"],
    "expires": expires_ms,
    "email": email,
}
auth_profiles.setdefault("order", {})["openai-codex"] = [profile_id]
auth_profiles.setdefault("lastGood", {})["openai-codex"] = profile_id

openclaw_auth_path.parent.mkdir(parents=True, exist_ok=True)
openclaw_auth_path.write_text(json.dumps(auth_profiles, indent=2) + "\n")

print(f"Wrote OpenClaw OAuth profile: {profile_id}")

If your OpenClaw auth profile path differs, change openclaw_auth_path before running.

Step 3: Set the OpenClaw model to openai-codex/...

Set the default model using the Codex provider prefix:

openclaw models set openai-codex/gpt-5.5

Do not use this if your goal is ChatGPT subscription routing:

openclaw models set openai/gpt-5.5

That routes to the regular OpenAI API provider.

Depending on the OpenClaw version/provider build, available Codex-routed model ids may include names like:

gpt-5.5
gpt-5.5-pro
gpt-5.4
gpt-5.4-pro
gpt-5.4-mini
gpt-5.3-codex
gpt-5.3

Use the full model id with the provider prefix, for example:

openai-codex/gpt-5.5

Step 4: Verify

Run:

openclaw models status

You want to see something equivalent to:

Default: openai-codex/gpt-5.5
Providers with OAuth/tokens: openai-codex
OAuth profile: openai-codex:user@example.com ok

Inside a live KiloClaw/OpenClaw chat session, /status should show the model and auth source, e.g.:

Model: openai-codex/gpt-5.5
Auth : oauth (openai-codex:user@example.com)

If an existing chat session was created before you changed the default model, it may stay pinned to the old model. Start a fresh session or switch the current one explicitly:

/model openai-codex/gpt-5.5

Persistence and reboot behavior

This setup survives ordinary restarts if the relevant files live on persistent storage.

In the tested KiloClaw environment, the important files were:

/root/.openclaw/openclaw.json
/root/.openclaw/agents/main/agent/auth-profiles.json
/root/.codex/auth.json

The default model is stored in openclaw.json; the OAuth profile is stored in auth-profiles.json; and the Codex CLI credentials remain in ~/.codex/auth.json.

On KiloClaw, /root is backed by the instance's persistent volume, so ordinary OpenClaw restarts, machine restarts, and redeploys should preserve the setup.

Token refresh caveat

Codex OAuth access tokens expire. The auth profile includes a refresh token, and OpenClaw should use it to refresh the access token automatically.

If refresh fails because OpenAI rotated or revoked the refresh token, repeat:

npx @openai/codex login --device-auth

Then rerun the injection script.

Common failure modes

Missing API key for OpenAI

Most likely cause: the model is set to openai/... instead of openai-codex/....

Fix:

openclaw models set openai-codex/gpt-5.5

/status still shows the old model

Existing sessions can be pinned to their original model.

Fix:

/model openai-codex/gpt-5.5

Or start a new chat/session.

Settings UI changed the model back

Some hosted dashboards treat the dashboard settings as source-of-truth for the primary model. If you change models there, it may overwrite your CLI-set default.

Fix: rerun:

openclaw models set openai-codex/gpt-5.5

Then verify with:

openclaw models status

OAuth profile exists, but provider does not use it

Check all of the following:

  • the model id starts with openai-codex/;
  • the profile's provider field is openai-codex;
  • the profile includes both access and refresh fields;
  • expires is epoch milliseconds, not seconds; and
  • the OpenClaw process can read the auth profile file for the active agent.

Security notes

  • Do not publish ~/.codex/auth.json.
  • Do not publish auth-profiles.json with real access or refresh tokens.
  • Treat Codex OAuth refresh tokens like passwords.
  • If writing a public guide, replace real emails with user@example.com and redact all tokens.

The short version

# Authenticate with the ChatGPT account
npx @openai/codex login --device-auth

# Copy ~/.codex/auth.json tokens into OpenClaw's openai-codex OAuth profile
python3 inject-codex-oauth-into-openclaw.py

# Select the Codex provider, not the regular OpenAI provider
openclaw models set openai-codex/gpt-5.5

# Verify
openclaw models status

If you remember only one thing, remember this:

openai-codex/gpt-5.5 uses ChatGPT/Codex OAuth.
openai/gpt-5.5 uses the regular OpenAI API provider.

References and Credits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment