mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 09:39:25 +00:00
793 lines
47 KiB
Markdown
793 lines
47 KiB
Markdown
---
|
|
summary: "Configure native Codex plugins for Codex-mode OpenClaw agents"
|
|
title: "Native Codex plugins"
|
|
read_when:
|
|
- You want Codex-mode OpenClaw agents to use native Codex plugins
|
|
- You are migrating source-installed openai-curated Codex plugins
|
|
- You are discovering or installing a Codex marketplace plugin
|
|
- You are troubleshooting codexPlugins, app inventory, destructive actions, or plugin app diagnostics
|
|
- You need the precedence of OpenClaw policy, native app defaults, and per-tool overrides
|
|
---
|
|
|
|
Native Codex plugin support lets a Codex-mode OpenClaw agent use Codex
|
|
app-server's own app and plugin capabilities inside the same Codex thread that
|
|
handles the OpenClaw turn. Plugin calls stay in the native Codex transcript;
|
|
Codex app-server owns app-backed MCP execution. OpenClaw does not translate
|
|
Codex plugins into synthetic `codex_plugin_*` OpenClaw dynamic tools.
|
|
|
|
Use this page after the base [Codex harness](/plugins/codex-harness) is
|
|
working.
|
|
|
|
## Requirements
|
|
|
|
- The agent runtime must be the native Codex harness.
|
|
- `plugins.entries.codex.enabled` is `true`.
|
|
- `plugins.entries.codex.config.codexPlugins.enabled` is `true`.
|
|
- Codex app-server reports `0.149.0` or newer. The official plugin ships
|
|
`@openai/codex` `0.158.0`; newer custom, remote, and macOS desktop-owned
|
|
binaries continue with a compatibility warning and normal runtime validation.
|
|
- The target Codex app-server can see the expected marketplace, plugin, and
|
|
app inventory.
|
|
- Migration supports only `openai-curated` plugins that it observed as
|
|
source-installed in the source Codex home. Codex serves the same catalog to
|
|
API-key and Bedrock accounts under the `openai-api-curated` wire name;
|
|
OpenClaw treats both names as the one curated catalog, so configured
|
|
`openai-curated` plugins resolve from either.
|
|
- Native runtime support also includes other marketplaces already available to
|
|
Codex, such as `openai-bundled`, `openai-primary-runtime`,
|
|
`workspace-directory`, and marketplace manifests in the current repository.
|
|
Plugins remain unavailable until an owner or `operator.admin` explicitly
|
|
installs or enables their marketplace-qualified identity.
|
|
|
|
`codexPlugins` has no effect on OpenClaw-provider runs, ACP conversation
|
|
bindings, or other harnesses, because those paths never create Codex
|
|
app-server threads with native `apps` config.
|
|
|
|
OpenAI-side Codex account, app availability, and workspace app/plugin controls
|
|
come from the signed-in Codex account. See
|
|
[Using Codex with your ChatGPT plan](https://help.openai.com/en/articles/11369540-using-codex-with-your-chatgpt-plan)
|
|
for the OpenAI account and admin model.
|
|
|
|
## Quickstart
|
|
|
|
The source Codex home is the Codex CLI state directory you are migrating from:
|
|
`~/.codex` by default, or `CODEX_HOME` when that variable is set. See
|
|
[`openclaw migrate`](/cli/migrate) to point at a different one with `--from`.
|
|
|
|
Preview migration from the source Codex home:
|
|
|
|
```bash
|
|
openclaw migrate codex --dry-run
|
|
```
|
|
|
|
Add `--verify-plugin-apps` to make migration read the source installed app
|
|
snapshot and app metadata, requiring every owned app to be present, enabled,
|
|
and accessible before planning native activation:
|
|
|
|
```bash
|
|
openclaw migrate codex --dry-run --verify-plugin-apps
|
|
```
|
|
|
|
Apply the migration when the plan looks right:
|
|
|
|
```bash
|
|
openclaw migrate apply codex --yes
|
|
```
|
|
|
|
Migration writes explicit `codexPlugins` entries for eligible plugins and
|
|
calls Codex app-server `plugin/install` for selected plugins. A migrated
|
|
config looks like this:
|
|
|
|
```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",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
Migration remains limited to `openai-curated`. To find another plugin that
|
|
Codex can already see, list the available marketplace catalog and install the
|
|
exact marketplace-qualified identity:
|
|
|
|
```text
|
|
/codex plugins available
|
|
/codex plugins install security-review@company-tools
|
|
/codex plugins status security-review@company-tools
|
|
```
|
|
|
|
Codex discovers repository marketplaces from
|
|
`.agents/plugins/marketplace.json` in the current conversation workspace. An
|
|
owner does not need to add that marketplace to OpenClaw configuration before
|
|
listing or installing its plugins. Official bundled, primary-runtime, curated,
|
|
workspace, shared, and personal marketplaces depend on the signed-in Codex
|
|
account and upstream feature or administrator policies.
|
|
When Codex requires marketplace sources to be explicitly configured or
|
|
allowlisted, those requirements still apply; OpenClaw does not bypass them.
|
|
|
|
Installation writes an explicit configuration entry such as:
|
|
|
|
```json5
|
|
{
|
|
plugins: {
|
|
entries: {
|
|
codex: {
|
|
enabled: true,
|
|
config: {
|
|
codexPlugins: {
|
|
enabled: true,
|
|
plugins: {
|
|
"security-review@company-tools": {
|
|
enabled: true,
|
|
marketplaceName: "company-tools",
|
|
pluginName: "security-review",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
The install command checks the authenticated owner or administrator before it
|
|
calls Codex `plugin/install`. Codex continues to enforce marketplace source,
|
|
workspace administrator, account, and connector-authentication policies.
|
|
Remote plugins that require a Codex installation interstitial, or do not
|
|
report whether one is required, must be installed in Codex first; rerun the
|
|
OpenClaw install command afterward to authorize the already-installed plugin.
|
|
OpenClaw keeps apps hidden when the response omits the exact marketplace,
|
|
plugin identity, detail identity, or app-readiness evidence. If a connector
|
|
requires additional sign-in, complete that authorization before expecting the
|
|
plugin's tools to become available.
|
|
|
|
Installing the plugin bundle and configuring OpenClaw app access do not confirm
|
|
hosted app connections. When installation returns apps that still need sign-in,
|
|
OpenClaw provides **Open <app> in ChatGPT** links to the app pages returned by
|
|
Codex. Sign in with the same ChatGPT account and workspace used by the Codex
|
|
harness. Opening a link does not verify the connection or make its tools callable
|
|
in the current conversation. If the browser shows a directory instead of the app,
|
|
or no safe link is available, run `/apps` in Codex CLI and select the app there.
|
|
Responses show up to five app links and explicitly report additional apps to
|
|
review in Codex CLI. These links are for hosted ChatGPT apps; native MCP server
|
|
setup remains separate.
|
|
|
|
An app can also request sign-in when you first use one of its tools. In the
|
|
Control UI, choose **Open link** to open the requested page in a separate tab.
|
|
The question stays pending while you sign in. After completing the browser step,
|
|
select **I've completed this step** and submit to let Codex refresh and retry.
|
|
Opening the link alone does not resume the tool or confirm a connection. Clients
|
|
without a link action still show the URL to open manually before answering.
|
|
|
|
For setup completed outside an active Codex sign-in prompt, refresh hosted app
|
|
inventory for the current Codex account/runtime:
|
|
|
|
```text
|
|
/codex plugins refresh
|
|
```
|
|
|
|
This refresh covers all hosted apps in that runtime; it is not a per-plugin
|
|
backend refresh. A plugin's **Refresh hosted apps** button runs this command.
|
|
The separate **Check status** button inspects only that plugin without refreshing
|
|
hosted tools. Neither action changes authorization or the current conversation's
|
|
app policy. Use `/new` or `/reset` after connecting, then inspect status in the new
|
|
conversation.
|
|
|
|
After a `codexPlugins` change, new Codex conversations pick up the updated
|
|
app set automatically. Run `/new` or `/reset` to refresh the current
|
|
conversation. A gateway restart is not required for plugin enable/disable
|
|
changes.
|
|
|
|
## Scheduled automations
|
|
|
|
When an authenticated owner creates an automation from a Codex turn, OpenClaw
|
|
captures the app IDs and approval limits callable on that exact Codex thread.
|
|
The stored authority is bound to the creator's prepared Codex profile and
|
|
account. Scheduled runs intersect that cap with current Codex policy and app
|
|
availability. They never gain new app IDs or a broader destructive,
|
|
open-world, or approval ceiling. Tools added later within an already captured
|
|
app may run only when both the stored ceiling and current policy allow them.
|
|
|
|
Scheduled app calls are unattended. Only actions explicitly allowed both when
|
|
the job was created and when it runs can proceed without a prompt. An action
|
|
that still requires approval or elicitation is declined. A changed account,
|
|
runtime, revoked app, narrower policy, or unavailable inventory stops before
|
|
app execution and reports how to restore access or reauthorize the automation.
|
|
Model fallbacks cannot move this authority to another runtime or account.
|
|
|
|
This path is stricter than an ordinary interactive turn. OpenClaw generates
|
|
per-tool `enabled` and `approval_mode` values from current tool metadata and
|
|
the captured authority. An explicit native `enabled: true` cannot override a
|
|
captured or current destructive/open-world restriction on a scheduled run.
|
|
Approval intersections keep `"prompt"` if either side requires it;
|
|
`"approve"` defers to the other side. Combining `"auto"` with `"writes"`
|
|
produces `"prompt"`, because their annotation-dependent rules are not totally
|
|
ordered.
|
|
|
|
Jobs created before app authority capture may keep their ordinary OpenClaw
|
|
tool cap and continue non-app work, but cannot recover Codex app access
|
|
automatically. Recreate or reauthorize only a job that needs app access, from a
|
|
fresh authenticated owner turn. See
|
|
[Automations](/automation/cron-jobs#codex-apps-in-scheduled-automations).
|
|
Ordinary edits preserve captured app authority. Explicitly replacing a job's
|
|
`toolsAllow` cap without a fresh authenticated Codex authority capture clears
|
|
that authority; the next run reports that app access requires reauthorization.
|
|
An update from a fresh authenticated owner turn can instead capture and store a
|
|
new app ceiling for the updated job.
|
|
|
|
## Manage plugins from chat
|
|
|
|
`/codex plugins` inspects or changes configured native Codex plugins from the
|
|
same chat where you operate the Codex harness:
|
|
|
|
```text
|
|
/codex plugins
|
|
/codex plugins list
|
|
/codex plugins available
|
|
/codex plugins available security
|
|
/codex plugins available --page 2
|
|
/codex plugins install security-review@company-tools
|
|
/codex plugins status security-review@company-tools
|
|
/codex plugins refresh
|
|
/codex plugins disable google-calendar
|
|
/codex plugins enable google-calendar
|
|
/codex plugins disable security-review@company-tools
|
|
```
|
|
|
|
`/codex plugins` is an alias for `/codex plugins list`. The list shows each
|
|
configured plugin's key, on/off state, Codex plugin name, and marketplace
|
|
from `plugins.entries.codex.config.codexPlugins.plugins`.
|
|
|
|
`available [query] [--page <n>]` requires an owner or `operator.admin`. It reads
|
|
Codex's marketplace catalogs using the bound workspace, including repository-local
|
|
plugins, without installing or enabling them. Search matches names, display titles, publishers, marketplaces,
|
|
and descriptions case-insensitively across the full returned catalog before
|
|
showing ten results per page. **Next page** and **Previous page** preserve your
|
|
search; channels without buttons show the commands to send. Search text is limited
|
|
to 100 characters. Use `--` before literal search text containing `--page`.
|
|
|
|
Results show display titles, publishers, and descriptions when supplied by Codex,
|
|
with explicit placeholders for missing publishers or descriptions. They retain
|
|
marketplace-qualified identities and availability restrictions; display titles
|
|
and publisher names do not change installation identity.
|
|
This searches Codex catalogs, not OpenClaw's plugin registry or every ChatGPT
|
|
connection. The owner-scoped `codex_plugins` model tool uses the same search
|
|
matching and is also read-only: it can recommend an exact install command but
|
|
cannot install, enable, or add a marketplace.
|
|
|
|
`status <name>@<marketplace> [page]` inspects exactly one configured plugin and
|
|
requires an owner or `operator.admin`. The qualified identity is required;
|
|
bare `status` or an unqualified name returns usage guidance pointing to `list`.
|
|
|
|
Status shows bundle installation, marketplace restrictions, Codex enablement, and
|
|
shared OpenClaw app access separately. Changes to OpenClaw app access take effect
|
|
on the next message; they do not install or enable the Codex bundle.
|
|
|
|
App results show at most five apps per page. A ChatGPT app-page link requires
|
|
confirmed hosted-app runtime support, an available plugin under its catalog
|
|
policy, and matching authorized metadata from `app/read`. A plugin's app
|
|
declaration or setup URL alone does not establish that access. OpenClaw app
|
|
access can be disabled while an eligible ChatGPT page remains available;
|
|
opening that page does not enable OpenClaw app access. Plugins without hosted
|
|
apps receive no ChatGPT connection or setup guidance. Status does not assess
|
|
their skills or native MCP server readiness.
|
|
|
|
The selected agent, auth profile, conversation workspace, and account email/plan
|
|
are shown when available. ChatGPT workspace identity remains unknown when
|
|
Codex does not report it; use the same account and workspace in the browser
|
|
when opening an eligible hosted app page.
|
|
|
|
Status uses `app/read` for app metadata and displays the `enabled` and `callable`
|
|
flags returned by `app/installed`. The runtime scope is the bound Codex thread
|
|
when available, or the account otherwise. These flags reflect effective Codex
|
|
configuration and the current runtime tool snapshot; they are separate from
|
|
OpenClaw app access. Status does not infer a separate connection state. Missing
|
|
app records and failed reads are reported explicitly instead of becoming false
|
|
flags.
|
|
|
|
`/codex plugins refresh` requires owner or `operator.admin` authority and confirmed
|
|
hosted-app support in the selected Codex account/runtime. It works without a
|
|
configured plugin. It invalidates that runtime's OpenClaw app cache, calls
|
|
Codex `app/installed` with `forceRefresh: true` and no `threadId`, and reads
|
|
metadata for the returned apps. It does not refresh marketplace catalogs,
|
|
reinstall plugin bundles, or reload native MCP servers.
|
|
|
|
After refreshing, use `/codex plugins status <name>@<marketplace>` to inspect
|
|
one plugin. Status never forces a hosted refresh. Disabled or blocked plugins
|
|
remain disabled or blocked, but do not prevent an otherwise permitted hosted
|
|
refresh.
|
|
|
|
A completed request does not prove that Codex replaced its snapshot or that a
|
|
live tool call will succeed. Refresh never installs, enables, authenticates,
|
|
or replaces a thread, and does not reload other conversations. After connecting,
|
|
use `/new` or `/reset` and inspect status again. Browser setup does not change
|
|
OpenClaw app access; local app-access changes take effect on the next message.
|
|
Unsupported methods, cancellation, and refresh failures provide a retry action
|
|
without treating the previous inventory as confirmed.
|
|
|
|
`install`, `enable`, and `disable` require the owner or a gateway client with
|
|
the `operator.admin` scope. OpenClaw's reserved `/codex` command is dispatched
|
|
before agent invocation, so a model-generated recommendation does not count as
|
|
installation approval. For a plugin that Codex has not installed yet, `install`
|
|
calls the Codex app-server and records the explicit plugin policy only after
|
|
installation succeeds. If Codex confirms that the plugin is already installed
|
|
and enabled, the same command records its authorization without installing it
|
|
again. `enable` and `disable` change OpenClaw's persisted policy; qualified
|
|
identities and existing configuration keys are both accepted.
|
|
|
|
Installing or enabling a configured plugin also turns on the global
|
|
`codexPlugins.enabled` switch without enabling `allow_all_plugins`. If a plugin
|
|
reports `auth_required`, authorize the app in Codex before starting a new
|
|
conversation. Authorization remains in effect for later conversations until
|
|
the plugin is disabled or the upstream account or workspace revokes access.
|
|
|
|
Only install plugins you trust. A Codex plugin can contribute skills, apps,
|
|
MCP servers, and hooks. Some hooks can participate in permission decisions,
|
|
so explicit installation trusts the selected plugin's code; it is not a
|
|
security review or an isolation boundary.
|
|
|
|
## How native plugin setup works
|
|
|
|
The integration tracks three states:
|
|
|
|
| State | Meaning |
|
|
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
| Installed | Codex has the plugin bundle in the target app-server runtime. |
|
|
| Enabled | Codex reports the plugin enabled, and OpenClaw config allows it for Codex harness turns. |
|
|
| Accessible | Codex app-server confirms the plugin's app entries are available for the active account and map to the configured plugin identity. |
|
|
|
|
For `openai-curated` plugins, migration is the durable install/eligibility
|
|
step:
|
|
|
|
- During planning, OpenClaw reads source Codex `plugin/read` details and
|
|
checks the source Codex app-server account. `codex_subscription_required`
|
|
means `account/read` positively identified an API-key or other
|
|
non-ChatGPT account; a missing account is not evidence that a subscription
|
|
is absent.
|
|
- By default, migration skips source app inventory calls: app-backed source
|
|
plugins that pass the account gate are planned without source app
|
|
accessibility verification. A missing account or failed `account/read`
|
|
skips them with `codex_account_unavailable`.
|
|
- With `--verify-plugin-apps`, migration takes a fresh source `app/installed`
|
|
snapshot, fetches authenticated metadata with `app/read`, and requires every
|
|
owned app to be present, enabled, and accessible in the source Codex account
|
|
before planning native activation. If `account/read` is missing or fails,
|
|
strict verification can still prove access through the source app-server's
|
|
configured bearer or header authentication. A positively identified
|
|
non-ChatGPT account remains ineligible.
|
|
|
|
For explicitly approved plugins from any discovered marketplace, OpenClaw uses
|
|
its `plugin/installed` snapshot and `plugin/read` details to establish the
|
|
exact marketplace-qualified identity and app ownership. The installed-only
|
|
check during ordinary thread setup is read-only; apps from disabled or
|
|
unapproved plugins stay denied. Owner-issued installation is the explicit
|
|
mutation path. Missing or ambiguous ownership fails closed instead of granting
|
|
account-wide access.
|
|
|
|
Runtime app inventory is the target-session accessibility check for both
|
|
migrated curated plugins and manually configured workspace plugins. Before
|
|
enabled-policy turns, including warm reuse and cold resume, the Codex harness
|
|
rebuilds the restrictive thread app policy from current native settings while
|
|
reusing its app inventory and plugin metadata caches.
|
|
|
|
## Support boundary
|
|
|
|
- Only `openai-curated` plugins already installed in the source Codex
|
|
app-server inventory are migration-eligible.
|
|
- Runtime supports explicitly approved plugins from Codex-discovered official,
|
|
workspace, personal, shared, and repository-local marketplaces. A missing
|
|
marketplace, plugin, ownership detail, or app readiness evidence exposes no
|
|
plugin app.
|
|
- Positively identified non-ChatGPT source accounts fail the subscription gate.
|
|
Missing or unreadable source accounts are unavailable by default.
|
|
`--verify-plugin-apps` can instead establish access through authenticated
|
|
source app inventory, including bearer- or header-authenticated app-servers.
|
|
Inaccessible, disabled, or missing source apps and inventory refresh failures
|
|
remain skipped manual items. Unreadable plugin details are skipped before the
|
|
app-inventory gate.
|
|
- Migration writes explicit plugin identities (`marketplaceName` and
|
|
`pluginName`); it does not write local `marketplacePath` cache paths.
|
|
- `codexPlugins.enabled` is the only global enablement switch; there is no
|
|
`plugins["*"]` wildcard or config key that grants arbitrary install
|
|
authority.
|
|
- Migration does not automatically import non-curated marketplaces, cached
|
|
plugin bundles, hooks, or Codex config files. Use `/codex plugins available`
|
|
and an owner-issued `/codex plugins install <plugin>@<marketplace>` command
|
|
to opt into an additional discovered plugin.
|
|
- OpenClaw does not add new Git or local marketplace sources in this flow.
|
|
Additional sources must already be configured in Codex or be discoverable
|
|
from the bound repository.
|
|
|
|
## App inventory and ownership
|
|
|
|
OpenClaw first reads and caches one `plugin/installed` snapshot scoped to the
|
|
target Codex app-server and configured workspace. That snapshot covers plugins
|
|
from the marketplaces visible in that scope, including disabled plugin
|
|
identities; failed or incomplete snapshots are never cached. Conversations in
|
|
the same runtime and workspace share this metadata, and owner installation
|
|
invalidates it for all of them. App readiness remains specific to each thread.
|
|
`plugin/read` is
|
|
limited to exact configured plugin details required to establish ownership.
|
|
Explicit discovery queries `plugin/list` with the conversation workspace to
|
|
find repository marketplaces. Routine setup retains its existing curated
|
|
recovery behavior; additional marketplace installation requires the explicit
|
|
owner or administrator command.
|
|
|
|
Codex owns skill, hook, and MCP refresh after plugin installation. OpenClaw
|
|
refreshes its plugin and app inventories without reloading unrelated threads.
|
|
Use `/new` or `/reset` if an older custom Codex runtime does not make a newly
|
|
installed plugin available in an existing conversation.
|
|
|
|
OpenClaw reads installed app runtime state through `app/installed` and fetches
|
|
canonical app metadata with `app/read` in batches of at most 100 app IDs. The
|
|
first read force-refreshes a cold installed runtime snapshot. When multiple
|
|
configured curated plugins are installed, OpenClaw combines their cache
|
|
invalidations into a single app-inventory refresh. Ordinary cached reads do
|
|
not force a connector refresh for every new thread. OpenClaw caches the
|
|
combined inventory in memory for one hour and refreshes stale or missing
|
|
entries asynchronously. The cache is process-local; restarting the CLI or
|
|
gateway drops it.
|
|
|
|
Missing inventory methods, authentication errors, transport failures, and
|
|
connector refresh failures do not admit app tools. Ordinary turns, including
|
|
those using `allow_destructive_actions: "ask"`, can continue with native apps
|
|
disabled when inventory exceeds its startup budget. Scheduled runs stop if
|
|
their captured app policy cannot be revalidated within that budget.
|
|
|
|
Migration and runtime use separate cache keys:
|
|
|
|
- Source migration verification uses the source Codex home and start
|
|
options. It runs only with `--verify-plugin-apps` and forces a fresh
|
|
source runtime snapshot and metadata read for that planning run.
|
|
- Target runtime setup uses the target agent's Codex app-server identity when
|
|
building and verifying the thread app config. Curated plugin activation
|
|
invalidates that target cache key, then force-refreshes it after
|
|
`plugin/install`. Explicit marketplace installation refreshes the same
|
|
target runtime state before subsequent conversations use the plugin.
|
|
|
|
A plugin app is exposed only when OpenClaw can map it back to the configured
|
|
plugin through stable ownership: an exact app id from plugin detail, a known
|
|
MCP server name, or unique stable metadata. Display-name-only or ambiguous
|
|
ownership is excluded until the next inventory refresh proves ownership.
|
|
|
|
Missing plugins and marketplaces remain in saved settings for future discovery,
|
|
but are omitted from the effective runtime plugin policy. OpenClaw logs an error
|
|
and continues with healthy plugins and connected account apps. A missing entry's
|
|
permissions do not apply to other apps, even when their display names match.
|
|
The entry is reconsidered on the next normal inventory refresh; no saved settings
|
|
are removed. Found plugins disabled by an administrator retain their restrictions.
|
|
|
|
## Connected account apps
|
|
|
|
Owner-operated agents can opt into every app already connected to their Codex
|
|
account without requiring a matching plugin package:
|
|
|
|
```json5
|
|
{
|
|
plugins: {
|
|
entries: {
|
|
codex: {
|
|
enabled: true,
|
|
config: {
|
|
codexPlugins: {
|
|
enabled: true,
|
|
allow_all_plugins: true,
|
|
allow_destructive_actions: "auto",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
`allow_all_plugins: true` reads the installed app snapshot and authenticated
|
|
metadata when a new native Codex thread is established. It admits only
|
|
account-accessible apps. Codex must also confirm each admitted app is enabled
|
|
and callable for that thread. OpenClaw does not install, authenticate, or enable
|
|
apps globally. Existing threads keep their persisted app set; use `/new`,
|
|
`/reset`, or restart the gateway to pick up newly connected or revoked apps.
|
|
|
|
An explicitly disabled configured plugin found in the inventory overrides account-wide app
|
|
access. Because Codex `app/read` omits a disabled workspace plugin's display
|
|
names, OpenClaw uses its `plugin/installed` snapshot and reads only that exact
|
|
configured plugin's details to reserve its owned app IDs. This narrow,
|
|
read-only check does not discover unrelated marketplaces, activate the plugin,
|
|
or grant its apps. If the disabled plugin's ownership cannot be established,
|
|
the account-wide app selection fails closed.
|
|
|
|
Account apps inherit the global `codexPlugins.allow_destructive_actions` value,
|
|
which accepts `true`, `false`, `"auto"`, or `"ask"`. Explicit per-plugin policy
|
|
overrides the global policy for overlapping app ids. Inventory failures fail
|
|
closed instead of falling back to an unrestricted default.
|
|
|
|
## Thread app config
|
|
|
|
OpenClaw injects a restrictive `config.apps` patch for the Codex thread:
|
|
`_default` is disabled, and only apps owned by enabled configured plugins or
|
|
accessible account apps admitted by `allow_all_plugins` are enabled.
|
|
|
|
An app can be installed and authenticated but non-callable in the account-wide
|
|
snapshot while `_default` is disabled. OpenClaw provisionally admits only
|
|
ownership-proven, policy-allowed apps, creates the restrictive thread, and then
|
|
rereads `app/installed` once with the resulting thread ID and
|
|
`forceRefresh: false`. If the snapshot reports an app missing, disabled, or
|
|
non-callable, OpenClaw logs one warning listing the unavailable apps and
|
|
continues with the remaining tools. Codex still enforces the thread's effective
|
|
app, managed, workspace, and tool policies. An unavailable optional app does
|
|
not block unrelated chat or heartbeat runs.
|
|
|
|
If the snapshot request itself fails, the provisional thread is never bound
|
|
or used. OpenClaw deletes a failed persistent provisional thread, unsubscribes
|
|
a failed ephemeral thread, and retires the app-server connection if safe
|
|
cleanup cannot be confirmed.
|
|
|
|
`destructive_enabled` on each app comes from the effective global or
|
|
per-plugin `allow_destructive_actions` policy; `true`, `"auto"`, and `"ask"`
|
|
all set `destructive_enabled: true`, and `false` sets it `false`. Codex still
|
|
evaluates native tool enablement and annotations in the order below.
|
|
`_default` is disabled with `open_world_enabled: false`; enabled plugin apps
|
|
get `open_world_enabled: true`. OpenClaw does not expose a separate
|
|
plugin-level open-world policy knob and does not maintain per-plugin
|
|
destructive tool-name deny lists.
|
|
|
|
## Approval decision order
|
|
|
|
For an ordinary interactive Codex turn, follow these decisions in order:
|
|
|
|
1. **Admission:** OpenClaw selects the plugin/app identities allowed on this
|
|
thread. Unavailable inventory or unproven ownership does not grant access.
|
|
2. **Thread configuration:** OpenClaw overlays its app policy on the target
|
|
app-server's native configuration. Codex administrative requirements still
|
|
apply.
|
|
3. **Tool enablement:** Codex decides whether the particular tool is callable.
|
|
A disabled tool cannot be made callable by approving a prompt.
|
|
4. **Approval mode and reviewer:** Codex decides whether the call needs review
|
|
and whether to use its automatic reviewer or send a user approval request.
|
|
5. **OpenClaw response:** When a plugin approval request reaches OpenClaw, its
|
|
elicitation bridge applies the effective `allow_destructive_actions` value.
|
|
|
|
These are separate decisions. `enabled: true` does not mean automatic approval,
|
|
and `approval_mode: "approve"` does not enable a disabled tool. OpenClaw dynamic
|
|
tools, ordinary MCP forms, and native shell permissions have their own flows;
|
|
see [Native permissions and MCP elicitations](/plugins/codex-harness-runtime/permissions).
|
|
|
|
### Which configuration owns each setting
|
|
|
|
| Setting | Owner and purpose |
|
|
| ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| `plugins.entries.codex.config.codexPlugins` | OpenClaw's admission and plugin elicitation policy. |
|
|
| `codexPlugins.allow_destructive_actions` | Shared OpenClaw default for configured plugins and admitted account apps. |
|
|
| `codexPlugins.plugins.<key>.allow_destructive_actions` | Explicit override for that configured plugin. |
|
|
| Native `apps._default`, `apps.<appId>`, and `apps.<appId>.tools` | Codex app defaults and per-tool settings, after configuration layers and the OpenClaw thread patch are combined. |
|
|
| `plugins.entries.codex.config.appServer.approvalPolicy` and `approvalsReviewer` | General Codex approval posture and reviewer, distinct from app/tool policy. See [Approval and sandbox modes](/plugins/codex-harness-reference/approval-and-sandbox). |
|
|
|
|
OpenClaw resolves the destructive-action setting as:
|
|
|
|
```text
|
|
per-plugin value ?? codexPlugins shared value ?? true
|
|
```
|
|
|
|
Omitting a per-plugin value inherits the shared value. Explicit `false`,
|
|
`true`, `"auto"`, and `"ask"` all override it. In particular, a generated
|
|
per-plugin `"auto"` overrides a shared `false`; `"auto"` is a policy value,
|
|
not an instruction to inherit.
|
|
|
|
The shared default lives in the same OpenClaw configuration as the plugin
|
|
entries. It requires no separate host-wide configuration file. Native Codex
|
|
settings belong to the app-server that runs the tools: the default managed
|
|
local server uses an agent-scoped Codex home; a remote server uses its own
|
|
configuration. Starting Codex from OpenClaw or a deployment manager
|
|
does not remove this native configuration layer. OpenClaw's thread patches
|
|
do not rewrite saved native settings.
|
|
|
|
### Native tool enablement
|
|
|
|
After OpenClaw's admission patch, Codex evaluates an app tool in this order:
|
|
|
|
1. A disabled app blocks all its tools, including explicitly enabled tools.
|
|
Managed app disablement remains authoritative.
|
|
2. An explicit `apps.<appId>.tools.<tool>.enabled` wins for that tool.
|
|
3. Otherwise, an explicit `apps.<appId>.default_tools_enabled` wins.
|
|
4. Otherwise, Codex checks `destructive_enabled` and `open_world_enabled`
|
|
against the tool's annotations. Each category setting falls back from the
|
|
app to `apps._default`, then to `true`. Missing annotations are treated as
|
|
destructive/open-world for this eligibility check.
|
|
|
|
For tool configuration, an exact tool-name entry wins over a tool-title entry.
|
|
Codex selects the whole entry first; it does not fill missing fields from the
|
|
title entry. Omit `enabled` to inherit; TOML has no `null` value.
|
|
|
|
For example, on an admitted app with `destructive_enabled: false`, an omitted
|
|
tool `enabled` leaves destructive tools blocked. Explicit `enabled: true`
|
|
allows that particular tool through this native eligibility check, while
|
|
`enabled: false` blocks it even if the app allows destructive tools. The call
|
|
still has to pass approval and execution checks. This is an exception to an
|
|
app default, not a way to enable an unadmitted app or widen scheduled authority.
|
|
|
|
### Native approval mode
|
|
|
|
For an enabled tool, Codex selects the first applicable approval mode:
|
|
|
|
1. Managed per-tool approval requirement.
|
|
2. The selected native tool entry's `approval_mode`.
|
|
3. The selected connected account's
|
|
`apps.<appId>.links.<linkId>.default_tools_approval_mode`.
|
|
4. `apps.<appId>.default_tools_approval_mode`.
|
|
5. `apps._default.default_tools_approval_mode`.
|
|
6. `"auto"`.
|
|
|
|
The account link is the connected account used for this call, not the
|
|
OpenClaw conversation. The following modes decide whether review is needed;
|
|
they do not themselves promise an OpenClaw prompt:
|
|
|
|
| Native mode | Approval requirement |
|
|
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| `"approve"` | No tool approval request. Other access and execution restrictions still apply. |
|
|
| `"prompt"` | Requires approval, including for read-only tools. |
|
|
| `"writes"` | Requires approval unless the tool explicitly declares itself read-only. |
|
|
| `"auto"` | Uses annotations: explicitly destructive tools require approval; otherwise explicitly read-only tools do not. Remaining tools require approval when destructive/open-world hints are true or missing. |
|
|
|
|
Reviewer selection is separate: the connected account's reviewer overrides
|
|
the app reviewer, then `apps._default.approvals_reviewer`, then the thread
|
|
reviewer. Codex only accepts a configured reviewer allowed by administrative
|
|
requirements; otherwise it uses the thread reviewer. A model-specific
|
|
requirement for automatic review takes precedence. Strict automatic review
|
|
can also require review when a tool's mode would otherwise skip it.
|
|
|
|
Unless OpenClaw policy is explicitly `"ask"`, admitted apps retain their
|
|
native approval mode and reviewer, including app defaults and saved account-link
|
|
or tool overrides. This also applies when resuming a thread or asking a `/btw`
|
|
side question. With no native approval setting, Codex falls back to `"auto"`.
|
|
|
|
Use OpenClaw `allow_destructive_actions: "auto"` to route native human approval
|
|
requests through OpenClaw consent. Native `"prompt"` with the `"auto_review"`
|
|
reviewer stays in Codex's automatic review flow. OpenClaw `true` preserves the
|
|
native mode too, but auto-accepts supported approval requests that reach the
|
|
bridge, as described below.
|
|
|
|
OpenClaw `"ask"` also overlays saved approval fields for current non-read-only
|
|
tool names/aliases and connected accounts, selecting native `"auto"` and a
|
|
human app/account reviewer. It preserves tool enablement. If tool summaries
|
|
are unavailable, it targets all saved tool approval entries. Thus `"ask"`
|
|
requires one-shot consent for the actions Codex sends for approval; it does
|
|
not mean native `"prompt"` for every read. Other apps retain their reviewer.
|
|
|
|
On ordinary native-plugin turns and `/btw` side questions with bound apps,
|
|
OpenClaw enables MCP elicitation delegation even when the general
|
|
`appServer.approvalPolicy` is `"never"`; this does not enable unrelated shell
|
|
approval categories. The app mode, reviewer, and bridge response still
|
|
determine the outcome. General approval policy is not a replacement for the
|
|
per-app/tool settings above.
|
|
|
|
## Destructive action policy
|
|
|
|
Destructive plugin elicitations are allowed by default for configured Codex
|
|
plugins, while unsafe schemas and ambiguous ownership fail closed:
|
|
|
|
- Global `allow_destructive_actions` defaults to `true`.
|
|
- Per-plugin `allow_destructive_actions` overrides the global policy for
|
|
that plugin.
|
|
- `false`: OpenClaw sets native `destructive_enabled: false`; tool eligibility
|
|
follows the native defaults and explicit exceptions described above. Approval
|
|
requests for eligible hosted app tools still go through OpenClaw consent,
|
|
including permitted reads and `/btw` side questions. The bridge does not
|
|
classify tools again or blanket-decline their requests. Plugin-provided MCP
|
|
server approval requests still receive a deterministic decline.
|
|
- `true`: OpenClaw auto-accepts only safe schemas it can map to an approval
|
|
response, such as a boolean approve field.
|
|
- `"auto"`: OpenClaw exposes destructive plugin actions to Codex, then
|
|
turns ownership-proven MCP approval elicitations into OpenClaw plugin
|
|
approvals before returning the Codex approval response.
|
|
- `"ask"`: OpenClaw uses the same Codex write/destructive gating as
|
|
`"auto"`, applies the tool/account approval overlays described above, and
|
|
offers only one-shot approval or denial. Saved native settings stay unchanged,
|
|
and user-config reloads preserve the thread's approval policy. These checks
|
|
also run before reusing a thread or answering a
|
|
`/btw` side question. Changed override keys rebuild the thread with current policy.
|
|
- Missing plugin identity, ambiguous ownership, a missing or mismatched
|
|
turn id, or an unsafe elicitation schema declines instead of prompting.
|
|
|
|
Apps outside the admitted policy stay disabled even if native Codex settings
|
|
enable them. Native settings must be verified before an enabled policy can admit
|
|
app tools. When no app can be admitted, Codex's app tool surface is disabled
|
|
without reading native app settings. Disabling plugin apps also skips app
|
|
inventory discovery. Active legacy managed app settings outrank native thread
|
|
configuration and prevent app admission; move those app settings to a supported
|
|
user or project configuration layer. Native administrative requirements remain
|
|
authoritative.
|
|
|
|
### Approval examples
|
|
|
|
Assume an admitted, authenticated app, no conflicting managed requirement,
|
|
and a human reviewer for calls that need approval. The read tools below declare
|
|
`readOnlyHint: true` and `destructiveHint: false`:
|
|
|
|
| Configuration | Observable result on an ordinary turn |
|
|
| --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| OpenClaw shared `false`, per-plugin `"auto"` | The plugin override wins. Destructive tools are eligible; approval elicitations that reach OpenClaw request consent. |
|
|
| OpenClaw `"auto"`, native app default `"prompt"`, no tool/link override, non-destructive read | Native `"prompt"` survives. The read requests consent; Allow once permits the call and Deny blocks it. |
|
|
| OpenClaw `"auto"`, native read-tool `approval_mode: "prompt"` | The per-tool mode survives. The read requests consent; Allow once permits the call and Deny blocks it. |
|
|
| OpenClaw `false`, native app default `"prompt"`, no tool/link override, non-destructive read | Native eligibility allows the read, and OpenClaw requests consent. Allow once permits the call and Deny blocks it. |
|
|
| OpenClaw `false`, destructive tool explicitly `enabled: true` and `approval_mode: "approve"` | The native tool exception bypasses the category default and requires no tool approval request. The bridge's decline path is not an execution-time category ceiling. |
|
|
| OpenClaw `"ask"`, saved non-read-only tool approval `"approve"` | The thread overlay replaces that saved approval with native `"auto"`; calls needing approval use one-shot consent. |
|
|
|
|
If the reviewer in the native `"prompt"` examples is `"auto_review"` instead
|
|
of `"user"`, Codex performs automatic review rather than displaying an
|
|
OpenClaw consent prompt. Neither reviewer choice enables a tool that failed
|
|
the eligibility check.
|
|
|
|
Remembered approval and explicit enablement are different settings. Codex's
|
|
persistent app-tool approval writes `approval_mode: "approve"`, not
|
|
`enabled: true`; Allow once does not persist either setting. Recheck both when
|
|
explaining why a tool ran or why no prompt appeared.
|
|
|
|
## Troubleshooting
|
|
|
|
| Code | Meaning | Fix |
|
|
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
|
|
| `auth_required` | Migration installed the plugin, but one of its apps still needs authentication. The entry is written disabled until you reauthorize. | Reauthorize the app in Codex, then enable the plugin in OpenClaw. |
|
|
| `app_inaccessible`, `app_disabled`, `app_missing` | With `--verify-plugin-apps`, the source Codex app inventory did not show all owned apps as present, enabled, and accessible. | Reauthorize or enable the app in Codex, then rerun migration with `--verify-plugin-apps`. |
|
|
| `app_inventory_unavailable` | Strict source app verification was requested but the source Codex app inventory refresh failed. | Fix source Codex app-server access, or retry without `--verify-plugin-apps` to accept the faster account-gated plan. |
|
|
| `codex_subscription_required` | The source app-server positively identified an API-key or other non-ChatGPT account. | Log in to the Codex app with subscription auth, then rerun migration. |
|
|
| `codex_account_unavailable` | The source account was missing or `account/read` failed without strict app verification. | Restore source account access, or use `--verify-plugin-apps` when authenticated source app inventory can prove access. |
|
|
| `marketplace_missing`, `plugin_missing` | The exact marketplace or configured plugin is unavailable in the installed snapshot; plugin apps fail closed. | Verify the target app-server's `plugin/installed` response and exact configured plugin identity. |
|
|
| `plugin_detail_unavailable` | OpenClaw could not read the exact configured plugin's ownership details. | Inspect the target app-server's `plugin/installed` and `plugin/read` responses. |
|
|
| `plugin_disabled` | Codex reports the plugin installed but disabled. | Enable the plugin in Codex, or have the owner explicitly install and authorize it again. |
|
|
| `plugin_activation_failed` | Plugin activation did not complete. | Use the attached diagnostic to distinguish marketplace, auth, refresh, or workspace-readiness failures. |
|
|
| `app_inventory_missing`, `app_inventory_stale` | App readiness came from an empty or stale cache. | OpenClaw schedules an async refresh automatically; plugin apps stay excluded until ownership and readiness are known. |
|
|
| `app_ownership_ambiguous` | App inventory only matched by display name. | The app stays hidden from the Codex thread until a later refresh proves ownership. |
|
|
|
|
**Workspace plugin is installed but not visible:** confirm the workspace
|
|
`plugin/installed` snapshot reports the exact configured ID as installed and
|
|
enabled, then confirm `app/installed` returns every owned app for the same
|
|
Codex account and `app/read` returns its metadata. An app disabled only by the
|
|
account-wide default can become callable after OpenClaw starts and verifies
|
|
its explicitly configured thread. Revoked auth, missing metadata, disabled
|
|
workspace plugins, and Codex managed or workspace restrictions still block
|
|
access. Reauthorize or repair those upstream conditions before starting a new
|
|
thread. If you changed that state after the gateway cached app inventory, run
|
|
`/codex plugins refresh`, then use `/new` or `/reset`.
|
|
OpenClaw does not authenticate plugin apps on the owner's behalf.
|
|
|
|
For `plugin_detail_unavailable`, verify that the exact installed marketplace
|
|
and plugin identity select a matching `plugin/read` result. OpenClaw keeps
|
|
owned apps hidden when that selector or ownership detail is unavailable. For
|
|
`plugin_activation_failed`, inspect the marketplace, app authorization, and
|
|
post-install refresh diagnostics. An explicitly approved plugin must be
|
|
installed, enabled, and authenticated before its apps can appear in a thread.
|
|
|
|
**Config changed but the agent cannot see the plugin:** run `/codex plugins
|
|
list` to confirm the configured state, then `/new` or `/reset`. Existing
|
|
Codex thread bindings keep the app config they started with until OpenClaw
|
|
establishes a new harness session or replaces a stale binding.
|
|
|
|
**Destructive action is declined:** check the global and per-plugin
|
|
`allow_destructive_actions` values. Even with `true`, `"auto"`, or `"ask"`,
|
|
unsafe elicitation schemas and ambiguous plugin identity still fail closed.
|
|
|
|
## Related
|
|
|
|
- [Codex harness](/plugins/codex-harness)
|
|
- [Codex harness reference](/plugins/codex-harness-reference)
|
|
- [Codex harness runtime](/plugins/codex-harness-runtime)
|
|
- [Configuration reference](/gateway/config-extensions#codex-harness-plugin-config)
|
|
- [Migrate CLI](/cli/migrate)
|