执行被拦下了?四层控制下的 exec 排障路径
本文是面向维护者的原创排障指南。事实依据来自本站沙箱、工具策略与提权与执行审批两页(对照 2026-11-06 固定官方快照核对),本文不引入新的外部断言;示例命令均为说明性、未实机运行。
“我想让它跑个命令,被拦了”——OpenClaw 里一次执行可能被多层控制中的某一层拦下,每层的报错形态、检查命令和解法都不同。先分清层,再按症状查。
一、四层模型:哪些层在管你的这次执行
四层控制不是每次执行都要依次通过的"四道审批"——哪些层生效取决于你的配置:沙箱默认关闭(需显式开启),审批策略按主机与模式而定,提权是可选通道。它们各自回答一个问题:
| 层 | 管什么 | 何时参与 |
|---|---|---|
① 工具策略(tools.*) | exec 工具是否存在/可调 | 永远生效(配置了策略时) |
② 沙箱(agents.*.sandbox.*) | 工具在哪里跑(沙箱后端 vs 主机) | 默认关闭;显式开启(或创建者角色强制)时生效 |
③ exec 审批(tools.exec.* + 主机审批文档) | 主机执行要不要匹配允许列表/弹审批 | 生效 ask/security 由配置决定(ask 合法值 off/on-miss/always) |
④ 提权(tools.elevated.*) | 是否脱离沙箱跑(仅影响 exec) | 可选通道,须显式启用 |
两条贯穿性规则:deny 永远优先;工具策略是硬性停止——/exec 与提权都不能覆盖被拒的 exec 工具,提权也不能绕过创建者角色强制要求的沙箱。
二、症状 → 检查 → 原因 → 处理 → 验证
症状 1:“Tool X blocked by sandbox tool policy”
- 检查:
openclaw sandbox explain(看生效的沙箱工具 allow/deny 来自哪层);openclaw logs找agents/tool-policy审计条目(记录了是 allow 还是 deny 规则拦的)。 - 原因:已开启沙箱时,该工具被
tools.sandbox.tools.deny排除或不在allow列表。注意tools.sandbox.tools.*按工具名过滤(如exec);rg这样的可执行程序属于审批层的允许列表条目,两个列表不要混用。 - 处理(三选一,按意图):从
tools.sandbox.tools.deny移除该工具;加入tools.sandbox.tools.allow(沙箱内 MCP 工具还要考虑alsoAllow,如group:plugins);确实要关闭普通沙箱时agents.entries.*.sandbox.mode=off(不能覆盖创建者角色的强制沙箱)。 - 验证:重跑同一命令;
sandbox explain输出与预期一致。
症状 2:工具根本不在列表 / 被拒
- 检查:
openclaw exec-policy show(解释本地排除项与策略来源);核对tools.allow/tools.deny/tools.profile及按智能体覆盖。 - 原因:工具策略层把
exec(或目标工具)过滤掉了——注意工具策略只按名称过滤,若exec被允许,拒绝write/edit不会让 shell 命令变只读。 - 处理:调整对应层的 allow/deny/profile;
deny优先,先查 deny。 - 验证:
exec-policy show --session <key>预览;实际执行一次。
症状 3:该弹审批却没弹,直接被拒
- 检查:主机审批文档的
askFallback(UI 不可达时的回退,默认deny);审批客户端(Control UI/macOS 应用)是否连接。 - 原因:需要提示但无可达 UI(或提示超时),
askFallback: "deny"把它拒了。 - 处理:连接一个审批界面重试。无人值守场景想减少提示,正确条件是:生效
ask为off(不提示)或on-miss且命令命中允许列表时才免提示——ask: "always"下即使持久allow-always信任也仍会提示;确需无人值守回退时按风险显式设置askFallback(理解full的含义再设,它不是一般性故障修复)。 - 验证:重新触发;审批卡出现并能 Allow/Deny,或按上述条件确认免提示路径成立。
症状 4:审批通过了,命令没执行
- 检查:审批记录与 Gateway 日志里的绑定拒绝信息。
- 原因:绑定校验失败——获批后、执行前可执行文件解析结果变化(含
PATH上出现新二进制)、绑定的脚本文件内容变化,都会拒绝执行而不是跑已漂移的内容。这是防篡改设计。 - 处理:确认环境未被中途改动(依赖安装、路径调整都会触发);重跑命令走一遍新审批。
- 验证:再次执行成功且无绑定拒绝日志。
症状 5:开了提权却"没效果"或被拒
- 检查:
tools.elevated.enabled与allowFrom.<provider>;创建者角色是否强制沙箱。 - 原因:提权仅影响
exec、不授予额外工具、不覆盖工具 allow/deny;创建者角色强制要求的沙箱拒绝提权执行;本来就是直连运行时提权近似空操作(仍受门控)。 - 处理:按真实需求选层——要改工具集合去工具策略层,要换执行位置去沙箱层,只有"这次 exec 要在主机跑"才用提权。区分两档:
/elevated on脱离沙箱但审批仍可能适用;/elevated full是跳过 exec 审批的紧急通道,且仅当请求策略与主机审批文档都解析为security: "full"且ask: "off"时才生效。 - 验证:
/elevated on后重跑;sandbox explain确认实际生效状态。
三、正常 / 拒绝对照
同一条命令 rg pattern(说明性示例)在不同配置下的行为对照——前提列是生效的 security/ask:
| 生效配置(前提) | 工具策略 | 沙箱 | exec 审批 | 结果 |
|---|---|---|---|---|
| 沙箱默认关闭,未配审批 | exec 允许 | 未开启 | 默认 full/off(gateway/node) | 主机直接运行 |
已显式开启沙箱,exec 在沙箱 allow | 允许 | 沙箱内 | 不涉及主机执行 | 沙箱内运行 |
已开启沙箱,tools.sandbox.tools deny 了 exec | 允许 | deny(按工具名) | — | 拒绝(症状 1;rg 这类程序名属于审批层允许列表,不是本层条目) |
主机执行,security: allowlist 且允许列表含该 rg 路径条目,ask: off 或 on-miss | 允许 | 请求主机 | 命中(条目还绑定具体路径/argv——目录绑定的"Always allow here"只在该目录生效) | 直接运行 |
同上但 ask: "always" | 允许 | 请求主机 | 仍提示(allow-always 不抑制 always) | 待人决定 |
主机执行,未命中且 ask: on-miss | 允许 | 请求主机 | 弹审批 | 待人决定 |
审批超时、askFallback: "deny"(默认) | 允许 | 请求主机 | 回退拒绝 | 拒绝(症状 3) |
四、检查命令速查
openclaw sandbox explain # 沙箱模式/范围/沙箱工具 allow-deny 生效来源
openclaw exec-policy show # 终端工具策略 + 本地命令审批;--session 预览会话
openclaw approvals get # 请求策略/主机策略来源/生效结果(--node 查节点)
openclaw logs # 含 agents/tool-policy 审计条目深入参考:沙箱、工具策略与提权(层间关系与修复键)、执行审批(审批文档、允许列表与 YOLO 边界)。