mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 09:39:25 +00:00
docs: explain Codex app approval precedence (#155089)
* docs: explain Codex app approval precedence * docs: describe pending Codex approval fixes
This commit is contained in:
parent
58c4dfe03d
commit
1d1691663c
3 changed files with 184 additions and 21 deletions
|
|
@ -10,6 +10,11 @@ sidebarTitle: "Approval and sandbox"
|
|||
|
||||
The approval and sandbox posture of a Codex turn, and where native execution runs. Part of the [Codex harness reference](/plugins/codex-harness-reference); [Where each section moved](/plugins/codex-harness-reference#where-each-section-moved) lists every section.
|
||||
|
||||
For native plugin/app tools, also follow the
|
||||
[app approval decision order](/plugins/codex-native-plugins#approval-decision-order).
|
||||
App admission, tool enablement, per-tool approval modes, and OpenClaw's
|
||||
elicitation response are separate from the general presets below.
|
||||
|
||||
## Approval and sandbox modes
|
||||
|
||||
Local stdio app-server sessions default to YOLO mode:
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ Plugin, account, Computer Use, and MCP approval classification runs before
|
|||
ordinary input handling. A denied policy or unmappable approval schema returns
|
||||
an explicit decline and never becomes a general-purpose form.
|
||||
|
||||
For native app tools, see the
|
||||
[approval decision order](/plugins/codex-native-plugins#approval-decision-order)
|
||||
for OpenClaw defaults, native per-tool overrides, remembered approvals, and
|
||||
how eligible hosted app tools reach consent while disabled tools remain blocked.
|
||||
|
||||
OpenClaw supports app-server MCP elicitation modes `form`, `openai/form`, and
|
||||
`url`. Standard and extended forms can contain at most 12 fields. OpenClaw
|
||||
normalizes field names to Gateway-safe question IDs, retains the original names
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ read_when:
|
|||
- 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
|
||||
|
|
@ -212,6 +213,15 @@ 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
|
||||
|
|
@ -533,20 +543,140 @@ 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
|
||||
enforces destructive tool metadata from its native app tool annotations.
|
||||
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.
|
||||
|
||||
Admitted apps retain their native Codex approval mode and reviewer, including
|
||||
app defaults and saved link or tool overrides. With no native approval setting,
|
||||
Codex uses its `auto` approval mode, and read-only tools usually run without a prompt.
|
||||
Use `allow_destructive_actions: "auto"` to route native human approval requests
|
||||
through OpenClaw; native `prompt` with the `auto_review` reviewer stays within
|
||||
Codex's automatic review flow. These settings also apply when resuming a thread
|
||||
or asking a `/btw` side question. Explicit OpenClaw `"ask"` policy overrides saved
|
||||
native approvals as described below; `false` still disables destructive tools.
|
||||
## 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
|
||||
|
||||
|
|
@ -556,25 +686,23 @@ 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 excludes destructive hosted app tools before execution.
|
||||
Native approval requests for permitted tools still go through OpenClaw consent,
|
||||
including during a `/btw` side question. Plugin-provided MCP server approval
|
||||
requests receive a deterministic decline.
|
||||
- `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"`, overrides saved per-tool and per-account approvals in the native
|
||||
thread's configuration, 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
|
||||
`"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.
|
||||
For each admitted app using `"ask"`, OpenClaw selects Codex's human approvals
|
||||
reviewer for that app so Codex sends its approval elicitations to
|
||||
OpenClaw; other apps and non-app thread approvals keep their configured
|
||||
reviewer and policy.
|
||||
- Missing plugin identity, ambiguous ownership, a missing or mismatched
|
||||
turn id, or an unsafe elicitation schema declines instead of prompting.
|
||||
|
||||
|
|
@ -587,6 +715,31 @@ 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 |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue