---
summary: "Run OpenClaw embedded agent turns through the official Codex app-server harness"
title: "Codex harness"
read_when:
  - You want to use the official Codex app-server harness
  - You need Codex harness config examples
  - You want Codex-only deployments to fail instead of falling back to OpenClaw
---

The official `codex` plugin runs embedded OpenAI agent turns through Codex
app-server instead of the built-in OpenClaw harness. Codex owns the
low-level agent session: native thread resume, native tool continuation,
native compaction, and app-server execution. OpenClaw still owns chat
channels, session files, model selection, OpenClaw dynamic tools, approvals,
media delivery, and the visible transcript mirror.

Remote Codex app-servers can run on a different machine from the Gateway. Set
`remoteWorkspaceRoot` to validate remote workspace attachment paths. OpenClaw
transfers authoritative attachment bytes over the existing app-server connection
using a fixed, no-shell `command/exec` reader. The reader rejects symlinks,
enforces file and response size limits before allocation, and stages immutable
Gateway-managed media before channel delivery without requiring a shared or
synchronized filesystem. Codex images are materialized directly from typed
app-server events; saved-path-only images use the same bounded remote reader.
Uploads always use the Gateway's configured channel identity and request timeout.

Use canonical OpenAI model refs such as `openai/gpt-5.6-sol`. Do not configure
legacy Codex GPT refs; put OpenAI agent auth order under `auth.order.openai`.
Legacy Codex auth profile ids and legacy Codex auth order entries are
repaired by `openclaw doctor --fix`.

With provider/model runtime policy unset or `auto`, the `openai/*` prefix alone
never selects this harness. OpenAI may select Codex implicitly only for an
exact official HTTPS Platform Responses or ChatGPT Responses route with no
authored provider request override. Valid model-scoped `params.fastMode` /
`params.fast_mode` values and valid cutoff keys are typed agent-runtime
controls, so they do not count as authored provider request params or select a
runtime by themselves. See
[OpenAI implicit agent runtime](/providers/openai#implicit-agent-runtime).
If Codex owns auth before Platform versus ChatGPT routing is known, OpenClaw
still requires every candidate route to declare Codex compatibility. Native
auth ownership alone never bypasses that route check.

When no OpenClaw sandbox is active, OpenClaw starts Codex app-server threads
with Codex native code mode enabled (code-mode-only stays off by default), so
native workspace/code capabilities remain available alongside OpenClaw
dynamic tools routed through the app-server `item/tool/call` bridge. An
active OpenClaw sandbox or restricted tool policy disables native code mode
entirely unless you opt into the experimental sandbox exec-server path.

Eligible native-shell turns also retain `gateway_exec` and `gateway_process`
as a distinct OpenClaw execution path. Use `gateway_exec` only when a command
needs OpenClaw-managed Gateway environment access, including Secret Store
agent-readable environment values or protected egress sentinels. It is pinned
to the Gateway host and follows OpenClaw exec policy. `gateway_process` uses the
existing per-session OpenClaw process scope for background follow-up. Prefer
Codex native shell for ordinary local work.

With the default `tools.exec.host: "auto"` and no active OpenClaw sandbox,
Codex also receives `node_exec` for commands on paired nodes. Native shell
remains on the Codex app-server host and workspace
(Gateway-local for the default stdio deployment); `node_exec` selects a node by
name or id, keeps OpenClaw's node approval policy in force, and waits for the
remote command to finish. Remote-node background follow-up is not available. If
a finite runtime allowlist disables native Code Mode and leaves the turn without
an execution environment, OpenClaw keeps its policy-filtered `exec` and
`process` tools available instead for direct, unsandboxed execution.

When `tools.exec.host: "node"` or `/exec host=node` makes the node the session
default, OpenClaw hides the Codex-native shell and exposes `node_exec` as the
shell path. This keeps the configured execution host from silently falling
back to the app-server or Gateway machine.

`gateway_exec` is not exposed when an active OpenClaw sandbox, a node-default
execution policy, memory-flush restrictions, tool allow/deny policy, or
`codexDynamicToolsExclude` would make Gateway host access a bypass. Secret
Store environment values never enter the Codex app-server process, native
shell, sandbox exec-server, ACP children, sandbox exec, or node exec.

This Codex-native feature is separate from
[OpenClaw Code Mode](/tools/code-mode), an opt-in QuickJS-WASI runtime
for generic OpenClaw runs with a different `exec` input shape. For the
broader model/provider/runtime split, start with
[Agent runtimes](/concepts/agent-runtimes): `openai/gpt-5.6-sol` is the model
ref, `codex` is the runtime, and Telegram, Discord, Slack, or another
channel is the communication surface.

## Requirements

- The official `@openclaw/codex` plugin installed. Include `codex` in
  `plugins.allow` if your config uses an allowlist.
- Codex app-server `0.147.0` or newer. The plugin ships and manages the exact
  `@openai/codex` `0.148.0` artifact, so a `codex` command on `PATH` does not
  affect normal startup. Explicit custom, remote, and macOS desktop-owned
  app-servers must report valid SemVer at or above the supported minimum.
  Versions newer than the managed artifact initialize with a warning;
  acceptance permits an attempt and is not readiness or capability proof.
- Node.js on the remote Codex app-server host when `remoteWorkspaceRoot` is set
  and cross-machine workspace attachments must be transferred.
- Codex auth through `openclaw models auth login --provider openai`, an
  app-server account already present in the agent's Codex home, or an
  explicit Codex API-key auth profile.

For auth precedence, environment isolation, custom app-server commands,
model discovery, and the full config field list, see
[Codex harness reference](/plugins/codex-harness-reference).

## Quickstart

Install the official plugin, then sign in with Codex OAuth:

```bash
openclaw plugins install @openclaw/codex
openclaw models auth login --provider openai
```

Enable the `codex` plugin and select an OpenAI agent model:

```json5
{
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
  agents: {
    defaults: {
      model: "openai/gpt-5.6-sol",
    },
  },
}
```

If your config uses `plugins.allow`, add `codex` there too:

```json5
{
  plugins: {
    allow: ["codex"],
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
}
```

Restart the gateway after changing plugin config. If a chat already has a
session, run `/new` or `/reset` first so the next turn resolves the harness
from current config.

## Share threads with Codex Desktop and CLI

The default `appServer.homeScope: "agent"` isolates each OpenClaw agent from
the operator's native Codex state. To let an owner inspect and manage the
same native threads shown by Codex Desktop and the Codex CLI, opt into the
user Codex home:

```json5
{
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          appServer: {
            homeScope: "user",
          },
        },
      },
    },
  },
}
```

User-home mode supports a local managed stdio process or the shared Unix-socket
transport. It uses `$CODEX_HOME` when set and `~/.codex` otherwise, including
that home's native Codex auth, config, plugins, and thread store. OpenClaw does
not inject an OpenClaw auth profile into this app-server, even when the agent's
model route has a stored OpenAI profile. The native account is verified against
the route instead, in both directions:

- A subscription route requires the native home to be signed in to ChatGPT. Run
  `codex login` in that home if a turn reports missing subscription credentials.
- A Platform (API-key) route refuses a native home signed in with a ChatGPT
  subscription, so an API-billed route never silently spends the plan. Sign that
  home in with `codex login --with-api-key`, or switch to `homeScope: "agent"`
  and let OpenClaw inject the key it already holds.

A stored OpenAI profile is fine alongside `homeScope: "user"`; OpenClaw keeps it
for agent-scoped connections and simply does not hand it to the native home. Use
`openclaw models auth list --provider openai` to inspect stored profiles and
`openclaw models auth logout <profileId> --yes` to remove one you no longer want.

Owner turns gain the `codex_threads` tool: list, search, read, fork, rename,
archive, and restore native threads. Fork a thread to continue it in
OpenClaw; the fork attaches to the current OpenClaw session and stays
visible to other native Codex clients. Archiving requires explicit
confirmation that the thread is closed elsewhere. When supervision is also
enabled, transcript fields and mutations require the matching
`supervision.allowRawTranscripts` or `supervision.allowWriteControls` opt-in.

Do not resume or write the same thread concurrently through independent managed
stdio App Servers. Codex coordinates live writers inside one App Server, not
across separate processes. Forking is the safe coexistence path for ordinary
user-home stdio sessions.

`appServer.homeScope: "user"` alone does not control the fleet catalog. Native
session discovery is enabled while the plugin is active; set
`sessionCatalog.enabled: false` to remove it from the OpenClaw sidebar without
disabling Codex. The catalog uses a separate supervision connection; without
explicit `appServer` connection settings, that connection defaults to managed
user-home stdio while the ordinary harness stays agent-scoped. Explicit
`appServer` settings are honored by both paths. Set `homeScope: "user"`
explicitly, as above, when the ordinary harness should also share native state.

## Supervise Codex sessions

The same `codex` plugin can list non-archived Codex sessions from the Gateway
computer and opted-in paired nodes. A stored or idle Gateway-local session can
create a model-locked Chat that mirrors its bounded persisted user and assistant
history. Its private binding uses the supervision connection for the native
snapshot, canonical branch, and later turns while ordinary Codex sessions remain
agent-scoped. The first canonical start uses exactly the model and provider that
Codex returns for the snapshot fork. Later resumes leave selection to Codex's
native configuration; the outer OpenClaw model and fallback chain never replace
it. Stored and idle rows can be archived after explicit no-other-runner
confirmation. Active sources cannot create a branch or be archived; an existing
supervised Chat can still be opened. Paired-node sessions remain metadata-only.

See [Supervise Codex sessions](/plugins/codex-supervision) for setup, branching
rules, paired-node limits, metadata exposure, and troubleshooting.

## Configuration

| Need                                                | Set                                                                                                       | Where                              |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| Enable the harness                                  | `plugins.entries.codex.enabled: true`                                                                     | OpenClaw config                    |
| Hide native Codex session discovery                 | `plugins.entries.codex.config.sessionCatalog.enabled: false`                                              | Codex plugin config                |
| Include additional local Codex stores (stdio only)  | `plugins.entries.codex.config.sessionCatalog.homes`                                                       | Codex plugin config                |
| Keep an allowlisted plugin install                  | Include `codex` in `plugins.allow`                                                                        | OpenClaw config                    |
| Allow eligible OpenAI turns to use Codex implicitly | Exact official HTTPS Responses/ChatGPT route, no authored provider request override, runtime unset/`auto` | OpenAI provider/model config       |
| Sign in with ChatGPT/Codex OAuth                    | `openclaw models auth login --provider openai`                                                            | CLI auth profile                   |
| Add API-key backup for Codex runs                   | `openai:*` API-key profile listed after subscription auth in `auth.order.openai`                          | CLI auth profile + OpenClaw config |
| Fail closed when Codex is unavailable               | Provider or model `agentRuntime.id: "codex"`                                                              | OpenClaw model/provider config     |
| Use direct OpenAI API traffic                       | Provider or model `agentRuntime.id: "openclaw"` with normal OpenAI auth                                   | OpenClaw model/provider config     |
| Tune app-server behavior                            | `plugins.entries.codex.config.appServer.*`                                                                | Codex plugin config                |
| Enable native Codex plugin apps                     | `plugins.entries.codex.config.codexPlugins.*`                                                             | Codex plugin config                |
| Enable Codex Computer Use                           | `plugins.entries.codex.config.computerUse.*`                                                              | Codex plugin config                |

Prefer `auth.order.openai` for subscription-first/API-key-backup ordering.
Existing legacy Codex auth profile ids and legacy Codex auth order are
doctor-only legacy state; do not write new legacy Codex GPT refs.

```json5
{
  auth: {
    order: {
      openai: ["openai:user@example.com", "openai:api-key-backup"],
    },
  },
}
```

For a Codex-compatible effective route, both profiles above remain candidates
for the same Codex run. Profile order chooses credentials, not the runtime.
Changing auth order does not make a custom, Completions, HTTP, or
request-overridden route Codex-compatible. Valid model-scoped Fast-mode and
cutoff controls are runtime controls, not request overrides.

### Project instructions

Codex loads `AGENTS.md` files through native project-document discovery. For
normal app-server threads, OpenClaw raises Codex's aggregate root-to-working-
directory budget from the upstream 32 KiB default to a bounded 128 KiB so later
scoped instructions are not silently clipped. Lightweight and restricted turns
set the native project-document budget to zero instead.

This byte budget is separate from the character-based workspace bootstrap
limits configured through `agents.defaults.bootstrapMaxChars` and
`agents.defaults.bootstrapTotalMaxChars`.

`/context` reports native project documents as unverified because app-server
exposes their source paths but not the retained byte counts needed to tell
whether any individual file was fully loaded or truncated.

### Compaction

Do not set `compaction.model` or `compaction.provider` on Codex-backed
agents. Codex compacts through its native app-server thread state, so
OpenClaw ignores those local summarizer overrides at runtime, and
`openclaw doctor --fix` removes them when the agent uses Codex.

An authored `models.providers.*.models[].contextTokens` cap is forwarded to
Codex thread start and resume as `model_context_window`. Codex clamps the value
to the model's native maximum and derives automatic compaction from the capped
window. When the model entry has no authored cap, OpenClaw sends no override.

Lossless remains supported as a context engine for assembly, ingestion, and
maintenance around Codex turns, configured through
`plugins.slots.contextEngine: "lossless-claw"` and
`plugins.entries.lossless-claw.config.summaryModel`, not through
`agents.defaults.compaction.provider`. `openclaw doctor --fix` migrates the
old `compaction.provider: "lossless-claw"` shape to the Lossless
context-engine slot when Codex is the active runtime, but native Codex still
owns compaction. The native app-server harness supports context engines
that need pre-prompt assembly; generic CLI backends, including `codex-cli`,
do not provide that host capability.

For Codex-backed agents, `/compact` starts native Codex app-server
compaction on the bound thread and waits for its terminal result. The shared
`agents.defaults.compaction.timeoutSeconds` budget applies; on timeout,
OpenClaw asks Codex to interrupt the native turn and keeps the per-thread fence
until termination is confirmed. It never falls back to a context engine or
public OpenAI summarizer. If the native Codex thread binding is missing or
stale, the command fails closed instead of silently switching compaction
backends.

### Direct API long context

Codex subscription and direct OpenAI API traffic are separate contracts. The
live ChatGPT/Codex catalog commonly exposes a `272000` token model window,
while OpenAI documents a `1050000` token Platform API window and `128000`
maximum output for GPT-5.5 and GPT-5.6. Both runtime translations use the same
safe arithmetic:

```text
1050000 total - 128000 maximum output = 922000 safe active input
automatic compaction threshold = 700000 active tokens
```

The native Codex translation is not a Responses parameter set. Codex owns the
native thread's context and compaction, so do not add
`responsesServerCompaction` or `responsesCompactThreshold` to a Codex-backed
model.

Start from a complete Codex model catalog compatible with the installed Codex
version. For the exact `gpt-5.6-sol` entry, preserve the rest of the descriptor
and set:

```json
{
  "context_window": 922000,
  "max_context_window": 922000,
  "auto_compact_token_limit": 700000
}
```

Codex applies its normal 95% effective-window reserve to the `922000` catalog
value, so it reports exactly `875900` usable tokens. Compacting at `700000`
leaves `175900` tokens before that effective guard and `222000` before the
provider-safe input allowance. This larger margin is deliberate: Codex checks
already-recorded context before adding the next user message and context
updates, so the threshold must cover one large incoming turn as well as tools,
instructions, serialization, and the compaction turn itself.

For standalone Codex CLI or Desktop use, a command-auth custom provider can
read the API key from a system keychain or secret manager while the normal
ChatGPT login remains available for connectors:

```toml
model = "gpt-5.6-sol"
model_provider = "openai_api_direct"
model_context_window = 922000
model_auto_compact_token_limit = 700000
model_auto_compact_token_limit_scope = "total"
model_catalog_json = "/absolute/path/to/models-api-1m.json"

[model_providers.openai_api_direct]
name = "OpenAI API direct"
base_url = "https://api.openai.com/v1"
wire_api = "responses"
requires_openai_auth = false

[model_providers.openai_api_direct.auth]
command = "/absolute/path/to/read-openai-inference-key"
timeout_ms = 5000
refresh_interval_ms = 300000
```

The auth helper must print only the key to stdout. Do not put it in TOML.

For the OpenClaw Codex app-server harness, keep the default agent-scoped Codex
home and let OpenClaw inject an `openai` API-key profile. Create the profile by
the normal OpenAI API-key auth flow, put its actual id first in
`auth.order.openai`, and pass the catalog and context limits as native Codex
app-server arguments:

```json5
{
  auth: {
    order: {
      openai: ["openai:api-key"],
    },
  },
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          appServer: {
            args: [
              "app-server",
              "--listen",
              "stdio://",
              "-c",
              'model_catalog_json="/absolute/path/to/models-api-1m.json"',
              "-c",
              "model_context_window=922000",
              "-c",
              "model_auto_compact_token_limit=700000",
              "-c",
              "model_auto_compact_token_limit_scope=total",
            ],
          },
        },
      },
    },
  },
  agents: {
    defaults: {
      model: { primary: "openai/gpt-5.6-sol" },
      models: {
        "openai/gpt-5.6-sol": {
          agentRuntime: { id: "codex" },
          params: { fastMode: true },
        },
      },
    },
  },
}
```

Replace `openai:api-key` with the actual API-key profile id. The
agent-scoped app-server receives only that prepared key; the operator's native
`~/.codex` ChatGPT login, plugins, connectors, and thread store remain
untouched. Use the injected agent-scoped API-key path above for this route
rather than relying on `homeScope: "user"` to provide the intended credential.

The model catalog, `model_context_window`, total-scope automatic compaction
limit, exact `openai/gpt-5.6-sol` route, and API-key profile order form one
configuration unit. Apply them together. OpenClaw can keep embedded and native
long-context choices at the same time only when their model refs or agent
configurations are distinguishable; one model entry cannot carry both
runtime-owned compaction strategies.

After changing the catalog or app-server arguments, restart the Gateway and
native Codex app-server, then start a fresh chat. Run `/model default -s` when
an existing session has a model or runtime override. Existing native threads
preserve their recorded provider and model settings. Verify the runtime with
`/status` and `/codex status`, then send a harmless direct API turn before
starting a long session.

A process-owned isolated Gateway and app-server run verified this exact
`openai/gpt-5.6-sol` API-key configuration. Codex reported an effective window
of `875900`. Active context grew from `197032` to `377386`, `561957`, and
`750745` tokens without manual compaction; the next small turn triggered
automatic compaction to `75980` active tokens, with a minimum after-compaction
snapshot of `68375`. Compaction took `2810` ms and persisted a count of one. A
durable marker survived compaction and restart, a deterministic long response
produced `5442` output tokens, and OpenClaw sent the Codex app-server tier
`priority` on every call. That request evidence does not prove which upstream
tier processed each call. The full suite took `401.37` seconds. These timings
are observations, not service-level guarantees.

<Warning>
Long context is deliberately opt-in. Once input exceeds `272000` tokens,
OpenAI bills the entire request at 2× input and cache rates and 1.5× output
rates. Fast-mode pricing is model-specific; GPT-5.6 Sol API Fast mode (formerly
Priority processing) is currently another 2× over Standard, so this recipe is
4× short-context Standard input-side pricing and 3× short-context Standard
output pricing. OpenClaw currently sends the wire value
`service_tier: "priority"`. ChatGPT/Codex-credit Fast mode is separate: GPT-5.6
and GPT-5.5 currently consume 2.5× Standard credits, while this API-key Codex
route uses API token pricing. The API remains authoritative for access, actual
limits, and billing. See
[OpenAI model limits](https://developers.openai.com/api/docs/models/compare),
[Fast mode](https://openai.com/api-priority-processing/),
[API pricing](https://developers.openai.com/api/docs/pricing), and
[Codex speed](https://learn.chatgpt.com/docs/agent-configuration/speed).
</Warning>

The rest of this page covers deployment shape, fail-closed routing, guardian
approval policy, native Codex plugins, and Computer Use. For full option
lists, defaults, enums, discovery, environment isolation, timeouts, and
app-server transport fields, see
[Codex harness reference](/plugins/codex-harness-reference).

## Verify Codex runtime

Use `/status` in the chat where you expect Codex. A Codex-backed OpenAI
agent turn shows:

```text
Runtime: OpenAI Codex
```

Then check Codex app-server state:

```text
/codex status
/codex models
/codex binding
```

After installing or updating OpenClaw, explicitly verify the managed package
binary before cutover:

```bash
openclaw doctor --lint --only codex/managed-app-server --json
```

For an effective Codex route using the managed stdio app-server, this
default-disabled check resolves the platform-native executable and requires the
exact Codex version pinned by OpenClaw. It does not execute custom, remote, or
macOS desktop-owned app-servers.

`/status` reports the resolved OpenClaw Fast policy (`on`, `off`, or `auto`)
and the selected runtime. It does not report the upstream service tier actually
honored or returned for a completed request. `/codex binding` reports the
attached native thread and current model settings. `/codex status` reports
app-server connectivity, account, rate limits, MCP servers, and skills.
Neither Codex command is provider-response telemetry. `/codex models` lists
the live Codex app-server catalog for the harness and account. If `/status` is
surprising, see
[Troubleshooting](#troubleshooting).

## Routing and model selection

Keep provider refs and runtime policy separate:

- Use `openai/gpt-*` for canonical OpenAI model selection. The prefix alone
  never selects Codex.
- With runtime unset or `auto`, only an exact official HTTPS Platform Responses
  or ChatGPT Responses route with no authored provider request override may
  select Codex implicitly. Valid model-scoped Fast-mode and cutoff controls do
  not count as authored request params.
- Do not use legacy Codex GPT refs in config; run `openclaw doctor --fix` to
  repair legacy refs and stale session route pins.
- `agentRuntime.id: "codex"` makes Codex a fail-closed requirement for a
  compatible route. It does not make an incompatible effective route compatible.
- `agentRuntime.id: "openclaw"` opts a provider or model into the embedded
  OpenClaw runtime when that is intentional.
- `/codex ...` controls native Codex app-server conversations from chat.
- ACP/acpx is a separate external harness path. Use it only when the user
  asks for ACP/acpx or an external harness adapter.

| User intent                                                | Use                                                                                                   |
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| Attach the current chat                                    | `/codex bind [thread-id] [--cwd <path>] [--model <model>] [--provider <provider>]`                    |
| Resume an existing Codex thread                            | `/codex resume <thread-id>`                                                                           |
| List or filter Codex threads                               | `/codex threads [filter]`                                                                             |
| Read or update the bound thread's native goal              | `/codex goal [status\|set <objective>\|pause\|resume\|block\|complete\|clear]`                        |
| List native Codex plugins                                  | `/codex plugins list`                                                                                 |
| Discover available native Codex marketplace plugins        | `/codex plugins available`                                                                            |
| Install and authorize one native Codex plugin              | `/codex plugins install <plugin>@<marketplace>`                                                       |
| Enable or disable a configured native Codex plugin         | `/codex plugins enable <name>`, `/codex plugins disable <name>`                                       |
| Resume a stored Codex CLI session as a paired-node turn    | `/codex sessions --host <node> [filter]`, then `/codex resume <session-id> --host <node> --bind here` |
| View non-archived Codex sessions across computers          | Enable Codex supervision and open **Codex Sessions**                                                  |
| Change the bound thread's model, fast-mode, or permissions | `/codex model <model>`, `/codex fast [on\|off\|status]`, `/codex permissions [default\|yolo\|status]` |
| Compact the current Codex session                          | `/codex compact`                                                                                      |
| Stop or steer the active turn                              | `/codex stop`, `/codex steer <text>`                                                                  |
| Detach the current binding                                 | `/codex detach` (alias `/codex unbind`)                                                               |
| Send Codex feedback only                                   | `/codex diagnostics [note]`                                                                           |
| Start an ACP/acpx task                                     | ACP/acpx session commands, not `/codex`                                                               |

| Use case                                        | Configure                                                                                                            | Verify                                  | Notes                                                   |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | ------------------------------------------------------- |
| Eligible OpenAI route with native Codex runtime | Exact official HTTPS Responses/ChatGPT route with no authored provider request override, plus enabled `codex` plugin | `/status` shows `Runtime: OpenAI Codex` | Valid Fast runtime controls do not disqualify this path |
| Fail closed if Codex is unavailable             | Provider or model `agentRuntime.id: "codex"`                                                                         | Turn fails instead of embedded fallback | Use for Codex-only deployments                          |
| Direct OpenAI API-key traffic through OpenClaw  | Provider or model `agentRuntime.id: "openclaw"` and normal OpenAI auth                                               | `/status` shows OpenClaw runtime        | Use only when OpenClaw is intentional                   |
| Legacy config                                   | legacy Codex GPT refs                                                                                                | `openclaw doctor --fix` rewrites it     | Do not write new config this way                        |
| ACP/acpx Codex adapter                          | ACP `sessions_spawn({ runtime: "acp" })`                                                                             | ACP task/session status                 | Separate from native Codex harness                      |

`agents.defaults.imageModel` follows the same prefix split. Use `openai/gpt-*`
for the normal OpenAI route and `codex/gpt-*` only when image understanding
should run through a bounded Codex app-server turn. Doctor rewrites legacy
Codex GPT refs to `openai/gpt-*`.

## Deployment patterns

### Basic Codex deployment

Use the quickstart config for an OpenAI model whose effective official HTTPS
route is eligible to select Codex implicitly:

```json5
{
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
  agents: {
    defaults: {
      model: "openai/gpt-5.6-sol",
    },
  },
}
```

### Mixed provider deployment

Configure a Claude `main` agent and add a named Codex agent:

```json5
{
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
  agents: {
    ownership: "explicit",
    defaults: {
      model: "anthropic/claude-opus-4-6",
    },
    entries: {
      main: {
        model: "anthropic/claude-opus-4-6",
      },
      codex: {
        name: "Codex",
        model: "openai/gpt-5.6-sol",
      },
    },
  },
}
```

This explicit fleet has no default agent; target `main` or `codex` with a session, `--agent`, or binding. The `main` agent uses its normal provider path. The `codex` agent uses Codex app-server when its effective OpenAI route remains compatible; add explicit model-scoped `agentRuntime.id: "codex"` when that should be a fail-closed requirement.

### Fail-closed Codex deployment

An eligible exact official HTTPS OpenAI route can resolve to Codex when the
bundled plugin is available. Add explicit runtime policy for a written
fail-closed rule:

```json5
{
  models: {
    providers: {
      openai: {
        agentRuntime: {
          id: "codex",
        },
      },
    },
  },
  agents: {
    defaults: {
      model: "openai/gpt-5.6-sol",
    },
  },
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
}
```

With Codex forced, OpenClaw fails early if the effective route is not declared
Codex-compatible, the plugin is disabled, the app-server is too old, or the
app-server cannot start.

## App-server policy

By default, the plugin starts OpenClaw's managed Codex binary locally with
stdio transport. Set `appServer.command` only to intentionally run a
different executable. Codex classifies WebSocket transport as experimental
and unsupported; use it only for non-production testing against an app-server
already running elsewhere:

```json5
{
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          appServer: {
            transport: "websocket",
            url: "ws://gateway-host:39175",
            authToken: "${CODEX_APP_SERVER_TOKEN}",
          },
        },
      },
    },
  },
}
```

WebSocket transport proactively establishes the app-server connection at
gateway startup and limits the opening handshake to 10 seconds. An idle
connection sends a WebSocket ping every 20 seconds and allows 20 seconds for its
matching pong. A healthy app-server message or pong resets the missed-heartbeat
count; five consecutive missed pongs close the connection. Transient failures
reconnect automatically with bounded, jittered exponential backoff. Authentication
failures and unsupported app-server versions stop reconnecting and report that
operator action is required. Ping and pong frames are transport-level health
checks: they do not start a Codex turn or invoke a model. Local stdio and Unix
transports do not perform these remote connection checks.

Local stdio app-server sessions default to the trusted local operator
posture: `approvalPolicy: "never"`, `approvalsReviewer: "user"`, and
`sandbox: "danger-full-access"`. If local Codex requirements disallow that
implicit YOLO posture, OpenClaw selects allowed guardian permissions
instead. When an OpenClaw sandbox is active for the session, OpenClaw
disables Codex native Code Mode, user MCP servers, and app-backed plugin
execution for that turn instead of relying on Codex host-side sandboxing.
Shell access instead goes through OpenClaw sandbox-backed dynamic tools such
as `sandbox_exec` and `sandbox_process` when the normal exec/process tools
are available.

Use normalized OpenClaw exec mode for Codex native auto-review before
sandbox escapes or extra permissions:

```json5
{
  tools: {
    exec: {
      mode: "auto",
    },
  },
  plugins: {
    entries: {
      codex: {
        enabled: true,
      },
    },
  },
}
```

For Codex app-server sessions, `tools.exec.mode: "auto"` maps to Codex
Guardian-reviewed approvals: usually `approvalPolicy: "on-request"`,
`approvalsReviewer: "auto_review"`, and `sandbox: "workspace-write"` when
local requirements allow those values. In `tools.exec.mode: "auto"`,
OpenClaw does not preserve legacy unsafe Codex `approvalPolicy: "never"` or
`sandbox: "danger-full-access"` overrides; use `tools.exec.mode: "full"` for
an intentional no-approval Codex posture. The legacy
`plugins.entries.codex.config.appServer.mode: "guardian"` preset still
works, but `tools.exec.mode: "auto"` is the normalized OpenClaw surface.

For the mode-level comparison with host exec approvals and ACPX
permissions, see [Permission modes](/tools/permission-modes). For every
app-server field, auth order, environment isolation, and timeout behavior,
see [Codex harness reference](/plugins/codex-harness-reference).

### Native approval audit evidence

With `tools.exec.mode: "ask"` and the Codex user reviewer, native command and
file prompts use OpenClaw's two-phase operator approval route. The prompt shows
only decisions that the native request can preserve. For example, a command
that permits one execution but not session trust offers allow-once and deny;
byte-bound script approvals also remain one-shot. File prompts support both
one-shot and session approval.

Terminal operator decisions reuse the Gateway's authoritative approval row and
its exact execution binding. When execution identity collection is enabled,
inspect the admitted run with
[`openclaw audit --run <run-id> --explain`](/cli/audit). The resulting receipt
can report allow-once, allow-always, denial, no-route, expiry, or cancellation
without exposing command text, patch content, paths, or native request ids.

Codex auto-review, full-access policy, and native hook or OpenClaw policy
decisions do not create an operator approval row. Missing or stale native turn
context is rejected before routing. These cases therefore do not produce an
enforced operator-approval receipt; audit inspection does not reconstruct one
from later tool events.

## Commands and diagnostics

The `codex` plugin registers `/codex` as a slash command on any channel that
supports OpenClaw text commands.

Native execution and control require an owner or an `operator.admin`
Gateway client: binding or resuming threads, sending or stopping turns,
changing model, fast-mode, or permission state, compacting or reviewing, and
detaching a binding. Other authorized senders keep read-only status, help,
account, model, thread, native goal, MCP server, skill, and binding inspection
commands.

Common forms:

- `/codex status` checks app-server connectivity, models, account, rate
  limits, MCP servers, and skills.
- `/codex models` lists live Codex app-server models.
- `/codex threads [filter]` lists recent Codex app-server threads.
- `/codex goal` reads or updates the attached thread's native Codex goal. Codex automatic goal continuation stays disabled; OpenClaw does not own autonomous follow-on turns yet.
- `/codex resume <thread-id>` attaches the current OpenClaw session to an
  existing Codex thread.
- `/codex bind [thread-id] [--cwd <path>] [--model <model>] [--provider <provider>]`
  attaches the current chat.
- `/codex detach` (or `/codex unbind`) detaches the current binding.
- `/codex binding` describes the current binding.
- `/codex stop` stops the active turn; `/codex steer <text>` steers it.
- `/codex model <model>`, `/codex fast [on|off|status]`, and
  `/codex permissions [default|yolo|status]` change per-conversation state.
- `/codex compact` runs the same completion and session-accounting pipeline as
  `/compact`, then reports whether Codex compacted the session and the resulting
  token count. If compaction is skipped or fails, the reply includes the reason.
- `/codex review` starts Codex native review for the attached thread.
- `/codex diagnostics [note]` asks before sending Codex feedback for the
  attached thread.
- `/codex account` shows account and rate-limit status.
- `/codex mcp` lists Codex app-server MCP server status.
- `/codex skills` lists Codex app-server skills.
- `/codex plugins list` shows configured native plugins; `/codex plugins
available` discovers Codex marketplace plugins in the bound workspace.
- `/codex plugins install <plugin>@<marketplace>` installs and authorizes one
  discovered plugin. `/codex plugins enable <name>` and `/codex plugins
disable <name>` update its persisted policy. Mutations require an owner or
  `operator.admin` gateway client.
- `/codex computer-use [status|install]` manages Codex Computer Use.
- `/codex help` lists the full command tree.

### Shared Fast mode and Codex fast mode

`/fast` controls the shared OpenClaw policy. A directive-only `/fast off`
persists `off` in the OpenClaw session and sends `null` on affected Codex
harness turns to clear the OpenClaw-owned service-tier override. `/fast default`
clears only that session layer, so lower-precedence shared defaults may still
resolve to `on`, `off`, or `auto`.

`/codex fast` instead changes the bound native Codex conversation preference.
`/codex fast off` stores `flex` for later conversation-bound native turns; it
is not a synonym for `/fast off`, and it does not change the shared OpenClaw
session policy. When a shared Fast-mode run control reaches a Codex harness
turn, it supersedes `plugins.entries.codex.config.appServer.serviceTier` and
any binding preference that applies to that turn: Fast on sends `priority`,
Fast off sends `null`, and auto decides for each model call. The configured or
bound native tier is used only when no shared run control is supplied.

`/codex fast status` and `/codex binding` report native preference state, not
the upstream tier that processed a completed provider request.

For most support reports, start with `/diagnostics [note]` in the
conversation where the bug happened. It creates one Gateway diagnostics
report and, for Codex harness sessions, asks for approval to send the
relevant Codex feedback bundle. See
[Diagnostics export](/gateway/diagnostics) for the privacy model and group
chat behavior. Use `/codex diagnostics [note]` only when you specifically
want the Codex feedback upload for the currently attached thread without
the full Gateway diagnostics bundle.

### Inspect Codex threads locally

The fastest way to inspect a bad Codex run is often to open the native
Codex thread directly:

```bash
codex resume <thread-id>
```

Get the thread id from the completed `/diagnostics` reply, `/codex binding`,
or `/codex threads [filter]`.

For upload mechanics and runtime-level diagnostics boundaries, see
[Codex harness runtime](/plugins/codex-harness-runtime#codex-feedback-upload).

### Auth order

In the default per-agent home, auth is selected in this order:

1. Ordered OpenAI auth profiles for the agent, preferably under
   `auth.order.openai`. Run `openclaw doctor --fix` to migrate older legacy
   Codex auth profile ids and legacy Codex auth order.
2. The app-server's existing account in that agent's Codex home.
3. For local stdio app-server launches only, `CODEX_API_KEY`, then
   `OPENAI_API_KEY`, when no app-server account is present and OpenAI auth
   is still required.

When OpenClaw sees a ChatGPT subscription-style Codex auth profile, it
removes `CODEX_API_KEY` and `OPENAI_API_KEY` from the spawned Codex child
process. That keeps Gateway-level API keys available for embeddings or
direct OpenAI models without making native Codex app-server turns bill
through the API by accident. Explicit Codex API-key profiles and local
stdio env-key fallback use app-server login instead of inherited
child-process env. WebSocket app-server connections do not receive Gateway
env API-key fallback; use an explicit auth profile or the remote
app-server's own account.

If a subscription profile hits a Codex usage limit, OpenClaw records the
reset time when Codex reports one and tries the next ordered auth profile
for the same Codex run. When the reset time passes, the subscription
profile becomes eligible again without changing the selected `openai/gpt-*`
model or Codex runtime.

When native Codex plugins are configured, OpenClaw reads and caches one
runtime-and-workspace-scoped `plugin/installed` snapshot. That one snapshot
covers configured plugins from Codex-discovered marketplaces, including
disabled plugin ownership. `plugin/read` resolves only explicitly configured
plugin details. `/codex plugins available` queries `plugin/list` with the
bound workspace, while `/codex plugins install <plugin>@<marketplace>` is the
owner- or administrator-authorized installation path. Routine thread setup
retains existing explicitly configured curated-plugin recovery.

`app/installed` supplies the installed app runtime snapshot, and `app/read`
supplies authenticated app metadata in batches of at most 100 app IDs. OpenClaw
force-refreshes a cold snapshot once and consolidates successful curated
installations into one app-inventory refresh. Ordinary cached reads do not
force a connector refresh for every thread.

An authorized app can initially appear disabled or non-callable because Codex
has not yet applied the target thread's restrictive app configuration.
OpenClaw provisionally admits only explicitly allowed, ownership-proven apps,
starts the thread with `_default.enabled = false`, and reads `app/installed`
once with that thread's ID and `forceRefresh: false`. An app is exposed only
after Codex confirms it is enabled and callable for the actual thread. Missing
metadata, revoked auth, managed restrictions, workspace policy, and unavailable
tools remain fail-closed.

The check runs before OpenClaw starts a turn or commits a thread binding. A
failed persistent provisional thread is deleted; an ephemeral thread is
unsubscribed. If cleanup cannot be confirmed, OpenClaw retires the app-server
connection instead of reusing an unsafe thread.

Account-wide app access never overrides an explicitly disabled configured
workspace plugin. When `app/read` omits that plugin's ownership, OpenClaw uses
the `plugin/installed` snapshot and reads only the exact configured plugin's
details to keep its apps denied. This check never installs, enables, or
authenticates the plugin.

OpenClaw does not install unknown apps or let the model authorize new plugin
installs. Owner-approved plugin installation refreshes the target runtime
inventory. Missing inventory methods, authentication errors, transport
failures, and connector refresh failures fail closed.

### Environment isolation

For local stdio app-server launches, OpenClaw sets `CODEX_HOME` to a
per-agent directory so Codex config, auth/account files, plugin cache/data,
and native thread state do not read or write the operator's personal
`~/.codex` by default. OpenClaw preserves the normal process `HOME`;
Codex-run subprocesses can still find user-home config and tokens, and
Codex may discover shared `$HOME/.agents/skills` and
`$HOME/.agents/plugins/marketplace.json` entries. With
`appServer.homeScope: "user"`, OpenClaw instead uses the native user Codex
home and its existing account without injecting an OpenClaw auth profile.

If a deployment needs additional environment isolation, add those
variables to `appServer.clearEnv`:

```json5
{
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          appServer: {
            clearEnv: ["CODEX_API_KEY", "OPENAI_API_KEY"],
          },
        },
      },
    },
  },
}
```

`appServer.clearEnv` only affects the spawned Codex app-server child
process. OpenClaw removes `CODEX_HOME` and `HOME` from this list during
local launch normalization: `CODEX_HOME` stays pointed at the selected
agent or user scope, and `HOME` stays inherited so subprocesses can use
normal user-home state.

Verified local setup turns also attest the selected Codex launcher and package.
Inherited `NODE_OPTIONS` may contain bounded resource, warning, DNS result order,
network-family autoselection, environment-proxy, and CA-source options because
those settings cannot preload code or change module resolution. For example,
`--dns-result-order=ipv4first --no-network-family-autoselection` is allowed.
Malformed or unknown options and code-loading options such as `--require` or
`--import` fail closed. If an inherited option is not needed by Codex, remove
`NODE_OPTIONS` with `appServer.clearEnv`.

### Dynamic tools and web search

Codex dynamic tools default to `searchable` loading. OpenClaw normally does
not expose dynamic tools that duplicate Codex-native workspace operations:
`read`, `write`, `edit`, `apply_patch`, `exec`, `process`,
`get_goal`, `create_goal`, `update_goal`, `tool_call`, `tool_describe`,
`tool_search`, and `tool_search_code`. Goal operations stay native to Codex,
so OpenClaw does not project a second goal store into Codex turns. Most
remaining OpenClaw integration tools, such as messaging, media, cron,
browser, nodes, gateway, `progress_card`, and `heartbeat_respond` are available through
Codex tool search under the `openclaw` namespace, keeping the initial model
context smaller. The restricted-turn shell fallback is the exception for
`exec` and `process` when a finite allowlist disables native Code Mode;
runtime allowlists and `codexDynamicToolsExclude` still apply.
When native shell remains active and Gateway access is policy-eligible,
OpenClaw instead publishes the distinct `gateway_exec` and `gateway_process`
names so native shell and the OpenClaw-managed environment path cannot be
confused.

Tools marked `catalogMode: "direct-only"`, including the OpenClaw `computer`
tool, use the `openclaw_direct` namespace instead. Codex treats that namespace
as `DirectModelOnly`, so those tools stay directly model-visible in normal and
code-mode-only threads rather than crossing nested Code Mode `tools.*` calls.

Web search uses Codex's hosted `web_search` tool by default when search is
enabled and no managed provider is selected. Native hosted search and
OpenClaw's managed `web_search` dynamic tool are mutually exclusive so
managed search cannot bypass native domain restrictions. OpenClaw uses the
managed tool when hosted search is unavailable, explicitly disabled, or
replaced by a selected managed provider. OpenClaw keeps Codex's standalone
`web.run` extension disabled because production app-server traffic rejects
its user-defined `web` namespace. `tools.web.search.enabled: false`
disables both paths, as do tool-disabled LLM-only runs. Codex treats
`"cached"` as a preference and resolves it to live external access for
unrestricted app-server turns. Automatic managed fallback fails closed when
native `allowedDomains` are set so the allowlist cannot be bypassed.
Persistent effective search-policy changes rotate the bound Codex thread
before the next turn; transient per-turn restrictions use a temporary
restricted thread and preserve the existing binding for later resume.

`sessions_yield`, `sessions_spawn`, and message-tool-only source replies stay
direct because they are turn-control or delegation contracts. Guidance still
prefers Codex's native `spawn_agent` as the primary Codex subagent surface,
while explicit OpenClaw or ACP delegation remains directly callable through
`sessions_spawn`. In Codex Code Mode, generic OpenClaw
dynamic-tool results are JSON text rather than JavaScript objects, so parse
JSON-looking results before reading fields. Codex also serializes nested
dynamic calls; submit several `sessions_spawn` calls in a bounded loop rather
than expecting `Promise.all` to launch them concurrently. Already-accepted
children can still overlap while later calls are submitted. See
[Swarm](/tools/swarm#use-swarm-from-other-harnesses) for a complete pattern.
Heartbeat collaboration instructions
tell Codex to search for `heartbeat_respond` before ending a heartbeat turn
when the tool is not already loaded.

Set `codexDynamicToolsLoading: "direct"` only when connecting to a custom
Codex app-server that cannot search deferred dynamic tools or when
debugging the full tool payload.

### Config fields

Supported top-level Codex plugin fields:

| Field                      | Default        | Meaning                                                                                  |
| -------------------------- | -------------- | ---------------------------------------------------------------------------------------- |
| `codexDynamicToolsLoading` | `"searchable"` | Use `"direct"` to put OpenClaw dynamic tools directly in the initial Codex tool context. |
| `codexDynamicToolsExclude` | `[]`           | Additional OpenClaw dynamic tool names to omit from Codex app-server turns.              |
| `codexPlugins`             | disabled       | Native Codex plugin/app support for migrated source-installed curated plugins.           |
| `sessionCatalog`           | enabled        | Sidebar discovery for native Codex sessions on this Gateway and eligible paired nodes.   |
| `supervision`              | disabled       | Agent-facing native-session transcript and write-control policy.                         |

Supported `appServer` fields:

| Field                                         | Default                                                | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                            |
| --------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transport`                                   | `"stdio"`                                              | `"stdio"` spawns Codex; explicit `"unix"` connects to the local control socket; `"websocket"` connects to `url`.                                                                                                                                                                                                                                                                                                                   |
| `homeScope`                                   | `"agent"`                                              | `"agent"` isolates ordinary harness state per OpenClaw agent. `"user"` is an explicit opt-in that shares the native `$CODEX_HOME` or `~/.codex`, uses native auth, and enables owner-only thread management. User scope supports local stdio or Unix transport. For the separate supervision connection, an unset value resolves to `"user"` for stdio or Unix and `"agent"` for WebSocket.                                        |
| `command`                                     | managed Codex binary                                   | Executable for stdio transport. Leave unset to use the managed binary; set it only for an explicit override.                                                                                                                                                                                                                                                                                                                       |
| `args`                                        | `["app-server", "--listen", "stdio://"]`               | Arguments for stdio transport.                                                                                                                                                                                                                                                                                                                                                                                                     |
| `url`                                         | unset                                                  | WebSocket App Server URL or `unix://` URL. An empty explicit Unix path selects the canonical user-home control socket.                                                                                                                                                                                                                                                                                                             |
| `authToken`                                   | unset                                                  | Bearer token for WebSocket transport. Accepts a literal string or SecretInput such as `${CODEX_APP_SERVER_TOKEN}`.                                                                                                                                                                                                                                                                                                                 |
| `headers`                                     | `{}`                                                   | Extra WebSocket headers. Header values accept literal strings or SecretInput values, for example `x-codex-client-session-token: "${CODEX_CLIENT_SESSION_TOKEN}"`.                                                                                                                                                                                                                                                                  |
| `clearEnv`                                    | `[]`                                                   | Extra environment variable names removed from the spawned stdio app-server process after OpenClaw builds its inherited environment. OpenClaw keeps the selected `CODEX_HOME` and inherited `HOME` for local launches.                                                                                                                                                                                                              |
| `codeModeOnly`                                | `false`                                                | Opt into Codex's code-mode-only tool surface. Ordinary OpenClaw dynamic tools remain available through nested `tools.*` calls; `openclaw_direct` tools stay directly model-visible.                                                                                                                                                                                                                                                |
| `remoteWorkspaceRoot`                         | unset                                                  | Remote Codex app-server workspace root. OpenClaw maps the local cwd into this root and transfers authoritative remote attachments over an output-capped, no-shell `command/exec` reader. Paths escaping either workspace, symbolic links, oversized files, and unbounded attachment batches fail closed; uploads retain the configured channel identity and app-server request timeout.                                            |
| `requestTimeoutMs`                            | `60000`                                                | Timeout for app-server control-plane calls.                                                                                                                                                                                                                                                                                                                                                                                        |
| `turnCompletionIdleTimeoutMs`                 | `60000`                                                | Quiet window after Codex accepts a turn or after a turn-scoped app-server request while OpenClaw waits for `turn/completed`.                                                                                                                                                                                                                                                                                                       |
| `turnAssistantCompletionIdleTimeoutMs`        | `10000`                                                | Quiet window after a final/non-commentary assistant item or pre-tool raw assistant completion arms the assistant-output release while OpenClaw still waits for `turn/completed`. Raising it gives Codex more time to emit `turn/completed` before OpenClaw interrupts and releases the session lane.                                                                                                                               |
| `postToolRawAssistantCompletionIdleTimeoutMs` | `300000`                                               | Completion-idle and progress guard used after a tool handoff, native tool completion, post-tool raw assistant progress, raw reasoning completion, or reasoning progress while OpenClaw waits for `turn/completed`. Use this for trusted or heavy workloads where post-tool synthesis can legitimately stay quiet longer than the final assistant release budget.                                                                   |
| `mode`                                        | `"yolo"` unless local Codex requirements disallow YOLO | Preset for YOLO or guardian-reviewed execution. Local stdio requirements that omit `danger-full-access`, `never` approval, or the `user` reviewer make the implicit default guardian.                                                                                                                                                                                                                                              |
| `approvalPolicy`                              | `"never"` or an allowed guardian approval policy       | Native Codex approval policy sent to thread start/resume/turn. Guardian defaults prefer `"on-request"` when allowed.                                                                                                                                                                                                                                                                                                               |
| `sandbox`                                     | `"danger-full-access"` or an allowed guardian sandbox  | Native Codex sandbox mode sent to thread start/resume. Guardian defaults prefer `"workspace-write"` when allowed, otherwise `"read-only"`. When an OpenClaw sandbox is active, `danger-full-access` turns use Codex `workspace-write` with network access derived from the OpenClaw sandbox egress setting.                                                                                                                        |
| `approvalsReviewer`                           | `"user"` or an allowed guardian reviewer               | Use `"auto_review"` to let Codex review native approval prompts when allowed, otherwise `guardian_subagent` or `user`. `guardian_subagent` remains a legacy alias.                                                                                                                                                                                                                                                                 |
| `serviceTier`                                 | unset                                                  | Native Codex app-server preference only. Any non-empty string passes through for forward compatibility; documented values are `"priority"` and `"flex"`. `null` clears the override, and legacy `"fast"` normalizes to `"priority"`. This is neither the shared Fast-mode setting nor a direct embedded OpenAI setting. A shared Fast run control supersedes it with `priority` or `null`, or decides per model call in auto mode. |
| `networkProxy`                                | disabled                                               | Opt into Codex permissions-profile networking for app-server commands. OpenClaw defines the selected `permissions.<profile>.network` config and selects it with `default_permissions` instead of sending `sandbox`.                                                                                                                                                                                                                |
| `experimental.sandboxExecServer`              | `false`                                                | Preview opt-in that registers an OpenClaw sandbox-backed Codex environment with the supported Codex app-server so native Codex execution can run inside the active OpenClaw sandbox.                                                                                                                                                                                                                                               |

`appServer.networkProxy` is explicit because it changes the Codex sandbox
contract. When enabled, OpenClaw also sets `features.network_proxy.enabled`
and `default_permissions` in the Codex thread config so the generated
permission profile can start Codex managed networking. By default, OpenClaw
generates a collision-resistant `openclaw-network-<fingerprint>` profile
name from the profile body; use `profileName` only when a stable local name
is required.

```json5
{
  plugins: {
    entries: {
      codex: {
        config: {
          appServer: {
            sandbox: "workspace-write",
            networkProxy: {
              enabled: true,
              domains: {
                "api.openai.com": "allow",
                "blocked.example.com": "deny",
              },
              unixSockets: {
                "/tmp/proxy.sock": "allow",
                "/tmp/blocked.sock": "none",
              },
              allowUpstreamProxy: true,
              proxyUrl: "http://127.0.0.1:3128",
            },
          },
        },
      },
    },
  },
}
```

If the normal app-server runtime would be `danger-full-access`, enabling
`networkProxy` uses workspace-style filesystem access for the generated
permission profile: Codex managed network enforcement is sandboxed
networking, so a full-access profile would not protect outbound traffic.
Domain entries use `allow` or `deny`; Unix socket entries use Codex's
`allow` or `none` values.

### Image loader ownership

For image-capable models with Codex native tools enabled, Codex owns
`view_image` and OpenClaw suppresses its duplicate loader. The native Codex
schema accepts one local filesystem `path`. For text-only models, or when the
native tool surface is disabled, OpenClaw supplies `view_image` with its
`path`/`paths` schema and delegated vision route. Callers must use the schema
advertised for the active run.

### Dynamic tool call timeouts

OpenClaw-owned dynamic tool calls are bounded independently from
`appServer.requestTimeoutMs`: Codex `item/tool/call` requests use a 90
second OpenClaw watchdog by default. A positive per-call `timeoutMs`
argument extends or shortens that specific tool budget, capped at 600000 ms.
The `image_generate` tool uses `agents.defaults.mediaModels.image.timeoutMs`
when the tool call does not provide its own timeout, or a 120 second
image-generation default otherwise. The media-understanding `view_image` tool
uses the selected image-capable `tools.media.models[]` entry's `timeoutSeconds` or its 60 second media default; for
image understanding, that timeout applies to the request itself and is not
reduced by earlier preparation work. On timeout, OpenClaw aborts the tool
signal where supported and returns a failed dynamic-tool response to Codex
so the turn can continue instead of leaving the session in `processing`.
This watchdog is the outer dynamic `item/tool/call` budget; provider-specific
request timeouts run inside that call and keep their own timeout semantics.

After Codex accepts a turn, and after OpenClaw responds to a turn-scoped
app-server request, the harness expects Codex to make current-turn progress
and eventually finish the native turn with `turn/completed`. If the
app-server goes quiet for `appServer.turnCompletionIdleTimeoutMs`, OpenClaw
best-effort interrupts the Codex turn, records a diagnostic timeout, and
releases the OpenClaw session lane so follow-up chat messages are not
queued behind a stale native turn. Most non-terminal notifications for the
same turn disarm that short watchdog because Codex has proven the turn is
still alive.

Tool handoffs use a longer post-tool idle budget: after OpenClaw returns an
`item/tool/call` response, after native tool items such as
`commandExecution` complete, after raw `custom_tool_call_output`
completions, and after post-tool raw assistant progress, raw reasoning
completions, or reasoning progress. The guard uses
`appServer.postToolRawAssistantCompletionIdleTimeoutMs` when configured and
defaults to five minutes otherwise; that same budget also extends the
progress watchdog for the silent synthesis window before Codex emits the
next current-turn event. Global app-server notifications, such as
rate-limit updates, do not reset turn-idle progress. Reasoning completions,
commentary `agentMessage` completions, and pre-tool raw reasoning or
assistant progress can be followed by an automatic final reply, so they use
the post-progress reply guard instead of releasing the session lane
immediately.

Only final/non-commentary completed `agentMessage` items and pre-tool raw
assistant completions arm the assistant-output release: if Codex then goes
quiet without `turn/completed`, OpenClaw best-effort interrupts the native
turn and releases the session lane. If another turn watch wins that release
race, OpenClaw still accepts the completed final assistant item once no
native request, item, or dynamic tool completion remains active and the
assistant-output release still belongs to the latest completed item, with
no later item completion. This can preserve the final answer after
completed tool work without replaying the turn. Partial assistant deltas,
stale earlier replies, and empty later completions do not qualify.

Replay-safe stdio app-server failures, including turn-completion idle
timeouts without assistant, tool, active-item, or side-effect evidence, are
retried once on a fresh app-server attempt. Unsafe timeouts still retire the
stuck app-server client and release the OpenClaw session lane; they also
clear the stale native thread binding instead of being replayed
automatically. Completion-watch timeouts surface Codex-specific timeout
text: replay-safe cases say the response may be incomplete, while unsafe
cases tell the user to verify current state before retrying. Public timeout
diagnostics include structural fields such as the last app-server
notification method, raw assistant response item id/type/role, active
request/item counts, and armed watch state; when the last notification is a
raw assistant response item, they also include a bounded assistant text
preview. They do not include raw prompt or tool content.

### Local testing env overrides

- `OPENCLAW_CODEX_APP_SERVER_BIN` bypasses the managed binary when
  `appServer.command` is unset.
- `OPENCLAW_CODEX_APP_SERVER_ARGS`
- `OPENCLAW_CODEX_APP_SERVER_MODE=yolo|guardian`
- `OPENCLAW_CODEX_APP_SERVER_APPROVAL_POLICY`
- `OPENCLAW_CODEX_APP_SERVER_SANDBOX`

`OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1` was removed. Use
`plugins.entries.codex.config.appServer.mode: "guardian"` instead, or
`OPENCLAW_CODEX_APP_SERVER_MODE=guardian` for one-off local testing. Config
is preferred for repeatable deployments because it keeps the plugin
behavior in the same reviewed file as the rest of the Codex harness setup.

## Native Codex plugins

Native Codex plugin support uses Codex app-server's own app and plugin
capabilities in the same Codex thread as the OpenClaw harness turn. OpenClaw
does not translate Codex plugins into synthetic `codex_plugin_*` OpenClaw
dynamic tools.

`codexPlugins` affects only sessions that select the native Codex harness.
It has no effect on built-in harness runs, normal OpenAI provider runs, ACP
conversation bindings, or other harnesses.

Minimal migrated config:

```json5
{
  plugins: {
    entries: {
      codex: {
        enabled: true,
        config: {
          codexPlugins: {
            enabled: true,
            allow_destructive_actions: true,
            plugins: {
              "google-calendar": {
                enabled: true,
                marketplaceName: "openai-curated",
                pluginName: "google-calendar",
              },
            },
          },
        },
      },
    },
  },
}
```

Thread app config is computed when OpenClaw establishes a Codex harness
session or replaces a stale Codex thread binding; it is not recomputed on
every turn. After changing `codexPlugins`, use `/new`, `/reset`, or restart
the gateway so future Codex harness sessions start with the updated app
set.

For migration eligibility, app inventory, destructive action policy,
elicitations, and native plugin diagnostics, see
[Native Codex plugins](/plugins/codex-native-plugins).

OpenAI-side app and plugin access is controlled by the signed-in Codex
account and, for Business and Enterprise/Edu workspaces, workspace app
controls. See
[Using Codex with your ChatGPT plan](https://help.openai.com/en/articles/11369540-using-codex-with-your-chatgpt-plan)
for OpenAI's account and workspace-control overview.

## Computer Use

Computer Use has its own setup guide:
[Codex Computer Use](/plugins/codex-computer-use).

Short version: OpenClaw does not vendor the desktop-control app or execute
desktop actions itself. It prepares Codex app-server, verifies that the
`computer-use` MCP server is available, and then lets Codex own the native
MCP tool calls during Codex-mode turns.

## Runtime boundaries

The Codex harness changes the low-level embedded agent executor only.

- OpenClaw dynamic tools are supported. Codex asks OpenClaw to execute
  those tools, so OpenClaw remains in the execution path.
- Codex-native shell, patch, MCP, and native app tools are owned by Codex.
  OpenClaw can observe or block selected native events through the
  supported relay, but it does not rewrite native tool arguments.
- `gateway_exec` and `gateway_process` are OpenClaw-owned dynamic tools. They
  deliberately re-enter Gateway exec preparation for agent-readable Secret
  Store environment and protected egress; those values never flow into Codex
  native shell.
- Codex owns native compaction. OpenClaw keeps a transcript mirror for
  channel history, search, `/new`, `/reset`, and future model or harness
  switching, but does not replace Codex compaction with an OpenClaw or
  context-engine summarizer.
- Media generation, media understanding, TTS, approvals, and messaging-tool
  output continue through the matching OpenClaw provider/model settings.
- `tool_result_persist` applies to OpenClaw-owned transcript tool results,
  not Codex-native tool result records.

For hook layers, supported V1 surfaces, native permission handling, queue
steering, Codex feedback upload mechanics, and compaction details, see
[Codex harness runtime](/plugins/codex-harness-runtime).

## Troubleshooting

**Codex does not appear as a normal `/model` provider:** expected for new
configs. Select an `openai/gpt-*` model, enable
`plugins.entries.codex.enabled`, and check whether `plugins.allow` excludes
`codex`.

**OpenClaw uses the built-in harness instead of Codex:** confirm the effective
route is an exact official HTTPS Platform Responses or ChatGPT Responses route,
has no authored provider request override, and that the Codex plugin is installed and
enabled. The `openai/gpt-*` prefix alone is not enough. For strict proof while
testing, set provider or model `agentRuntime.id: "codex"`; forced Codex fails
instead of falling back when the route or harness is incompatible.

**OpenAI Codex runtime falls back to the API-key path:** collect a redacted
gateway excerpt that shows the model, runtime, selected provider, and
failure. Ask affected collaborators to run this read-only command on their
OpenClaw host:

```bash
(
  pattern='openai/gpt-5\.[45]|openai[-]codex|agentRuntime(\.id)?|harnessRuntime|Runtime: OpenAI Codex|legacy OpenAI Codex prefix|resolveSelectedOpenAIRuntimeProvider|candidateProvider[": ]+openai|status[": ]+401|Incorrect API key|No API key|api-key path|API-key path|OAuth'

  if ls /tmp/openclaw/openclaw-*.log >/dev/null 2>&1; then
    grep -E -i -n "$pattern" /tmp/openclaw/openclaw-*.log 2>/dev/null || true
  else
    journalctl --user -u openclaw-gateway --since today --no-pager 2>/dev/null \
      | grep -E -i "$pattern" || true
  fi
) | sed -E \
    -e 's/(Authorization: Bearer )[A-Za-z0-9._~+\/-]+/\1[REDACTED]/Ig' \
    -e 's/(Bearer )[A-Za-z0-9._~+\/-]+/\1[REDACTED]/Ig' \
    -e 's/(api[_ -]?key[=: ]+)[^ ,}"]+/\1[REDACTED]/Ig' \
    -e 's/(OPENAI_API_KEY[=: ]+)[^ ,}"]+/\1[REDACTED]/Ig' \
    -e 's/sk-[A-Za-z0-9_-]{12,}/sk-[REDACTED]/g' \
    -e 's/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/[EMAIL-REDACTED]/g' \
  | tail -200
```

Useful excerpts usually include `openai/gpt-5.6-sol` or `openai/gpt-5.6-luna`,
`Runtime: OpenAI Codex`, `agentRuntime.id` or `harnessRuntime`,
`candidateProvider: "openai"`, and a `401`, `Incorrect API key`, or
`No API key` result. A corrected run should show the OpenAI OAuth path
instead of a plain OpenAI API-key failure.

**Legacy Codex model refs config remains:** run `openclaw doctor --fix`.
Doctor rewrites legacy model refs to `openai/*`, removes stale session and
whole-agent runtime pins, and preserves existing auth-profile overrides.

**The app-server is rejected:** use Codex `0.147.0` or newer. OpenClaw rejects
older, malformed, and unversioned servers. Same-version prereleases such as
`0.147.0-alpha.2` remain below the stable minimum; build metadata such as
`0.147.0+desktop` does not affect precedence. A newer external version is
permitted to initialize rather than treated as proof of compatibility, so
startup and capability operations can still fail with their normal diagnostics.

**`/codex status` cannot connect:** check that the `codex` plugin
is enabled, that `plugins.allow` includes it when an allowlist is
configured, and that any custom `appServer.command`, `url`, `authToken`, or
headers are valid.

**The Codex app-server uses too much memory:** distinguish the two processes
first. OpenClaw runs the local Codex app-server as a separate Rust child.
`NODE_OPTIONS=--max-old-space-size=...` changes only the Gateway's Node.js V8
heap; it does not cap or enlarge Codex. Managed Gateway installs already choose
an adaptive V8 heap, and raising it can leave less host memory for Codex. Use
[Gateway memory troubleshooting](/gateway/troubleshooting#gateway-exits-during-high-memory-use)
for Gateway pressure, and inspect host or container memory for the Codex child.

The bundled Codex has no heap or RSS limit and no configurable idle-unload
delay. After the last client unsubscribes, an inactive thread can remain loaded
for up to 30 minutes. OpenClaw independently keeps up to 64 idle conversation
threads subscribed on each Codex app-server for 30 minutes after their last
activity. This preserves warm sessions and session-scoped approvals when several
conversations alternate. Active turns and parents with unfinished native
subagents are protected from idle eviction; session reset or deletion releases
its own thread immediately. Idle-limit eviction unsubscribes the least recently
used conversation, after which Codex applies its separate unloading delay and a
later resumed session can require approvals again.

On constrained hosts, reduce native Codex subagent fan-out before increasing the
Gateway heap:

```json5
{
  plugins: {
    entries: {
      codex: {
        config: {
          appServer: {
            args: ["-c", "agents.max_threads=3", "app-server", "--listen", "stdio://"],
          },
        },
      },
    },
  },
}
```

That setting limits native child threads for the bundled Codex default
multi-agent backend. If you explicitly enable Codex multi-agent v2, use
`features.multi_agent_v2.max_concurrent_threads_per_session=3` instead; the v2
limit includes the root thread and cannot be combined with `agents.max_threads`.
For more Codex headroom, increase the host, container, or cgroup memory
allocation. An OS hard limit can terminate Codex rather than backpressure it.

**Model discovery is slow:** lower
`plugins.entries.codex.config.discovery.timeoutMs` or disable discovery.
See [Codex harness reference](/plugins/codex-harness-reference#model-discovery).

**WebSocket transport fails immediately:** check `appServer.url`,
`authToken`, headers, and that the remote app-server speaks the same Codex
app-server protocol version. Codex WebSocket transport remains experimental
and unsupported; prefer managed stdio or the local Unix control socket.

**Native shell or patch tools are blocked with `Native hook relay
unavailable`:** the Codex thread is still trying to use a native hook relay
id that OpenClaw no longer has registered. This is a native Codex hook
transport problem, not an ACP backend, provider, GitHub, or shell-command
failure. Start a fresh session in the affected chat with `/new` or `/reset`,
then retry a harmless command. If that works once but the next native tool
call fails again, treat `/new` as a temporary workaround only: copy the
prompt into a fresh session after restarting the Codex app-server or
OpenClaw Gateway so old threads are dropped and native hook registrations
are recreated.

**Codex tool calls create too many short-lived hook processes:** set
`plugins.entries.codex.config.appServer.loopDetectionPreToolUseRelay: false`
and restart the gateway. This disables only the Codex `PreToolUse` subprocess
used for OpenClaw loop detection and its no-policy marker. Required
`before_tool_call` and trusted-tool policy relays remain enabled.

**A non-Codex model uses the built-in harness:** expected unless provider
or model runtime policy routes it to another harness. Plain non-OpenAI
provider refs stay on their normal provider path in `auto` mode.

**Computer Use is installed but tools do not run:** check
`/codex computer-use status` from a fresh session. If a tool reports
`Native hook relay unavailable`, use the native hook relay recovery above.
See [Codex Computer Use](/plugins/codex-computer-use#troubleshooting).

## Related

- [Codex harness reference](/plugins/codex-harness-reference)
- [Codex harness runtime](/plugins/codex-harness-runtime)
- [Codex supervision](/plugins/codex-supervision)
- [Native Codex plugins](/plugins/codex-native-plugins)
- [Codex Computer Use](/plugins/codex-computer-use)
- [Agent runtimes](/concepts/agent-runtimes)
- [Model providers](/concepts/model-providers)
- [OpenAI provider](/providers/openai)
- [OpenAI Codex help](https://help.openai.com/en/collections/14937394-codex)
- [Agent harness plugins](/plugins/sdk-agent-harness)
- [Plugin hooks](/plugins/hooks)
- [Diagnostics export](/gateway/diagnostics)
- [Status](/cli/status)
- [Testing](/help/testing-live#live-codex-app-server-harness-smoke)
