Exec 批准
Exec 批准是伴侣应用 / 节点主机防护,用于让沙箱化代理在真实主机(gateway 或 node)上运行命令。把它想象成安全联锁:仅当策略 + 白名单 +(可选)用户批准都同意时才允许命令。
Exec 批准是工具策略和提权门控的补充(除非提权设置 full,它会跳过批准)。
有效策略是 tools.exec.* 和批准默认值的更严格者;如果省略批准字段,则使用 tools.exec 值。
如果伴侣应用 UI 不可用,任何需要提示的请求都由 ask 回退解决(默认:拒绝)。
它适用于哪里
Exec 批准在执行主机上本地强制执行。
- gateway 主机 - gateway 机器上的
openclaw进程 - node 主机 - 节点运行器(macOS 伴侣应用或无头节点主机)
信任模型说明:
- Gateway 认证的调用者是 Gateway 的受信任操作员。
- 配对节点将受信任操作员能力扩展到节点主机。
- Exec 批准降低意外执行风险,但不是每个用户 auth 边界。
macOS 分离:
- node 主机服务通过本地 IPC 将
system.run转发到 macOS 应用。 - macOS 应用在 UI 上下文中执行批准 + 执行命令。
设置和存储
批准存放在执行主机上的本地 JSON 文件中:
~/.openclaw/exec-approvals.json
示例模式:
{
"version": 1,
"socket": {
"path": "~/.openclaw/exec-approvals.sock",
"token": "base64url-token"
},
"defaults": {
"security": "deny",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": false
},
"agents": {
"main": {
"security": "allowlist",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": true,
"allowlist": [
{
"id": "B0C8C0B3-2C2D-4F8A-9A3C-5A4B3C2D1E0F",
"pattern": "~/Projects/**/bin/rg",
"lastUsedAt": 1737150000000,
"lastUsedCommand": "rg -n TODO",
"lastResolvedPath": "/Users/user/Projects/.../bin/rg"
}
]
}
}
}
策略旋钮
安全(exec.security?
- deny:阻止所有主?exec 请求?
- allowlist:仅允许白名单中的命令?
- full:允许一切(等同于提权)?
询问(exec.ask?
- off:从不提示?
- on-miss:仅当白名单不匹配时提示?
- always:每个命令都提示?
询问回退(askFallback?
如果需要提示但没有 UI 可达,回退决定?
- deny:阻止?
- allowlist:仅当白名单匹配时允许?
- full:允许?
白名单(每个代理?
白名单是每个代理的。如果存在多个代理,?macOS 应用中切换你正在编辑的代理。模式是不区分大小写?glob 匹配?
模式应解析为**二进制路?*(仅 basename 条目被忽略)?
旧版 agents.default 条目在加载时迁移?agents.main?
示例?
~/Projects/**/bin/peekaboo~/.local/bin/*/opt/homebrew/bin/rg
每个白名单条目跟踪:
- id 用于 UI 标识的稳?UUID(可选)
- last used 时间?
- last used command
- last resolved path
自动允许技?CLI
?*自动允许技?CLI**启用时,已知技能引用的可执行文件在节点上被视为白名单(macOS 节点或无头节点主机)。这使用 Gateway RPC 上的 skills.bins 获取技?bin 列表。如果你想要严格的手动白名单,请禁用此功能?
重要的信任说明:
- 这是一?隐式便利白名?,与手动路径白名单条目分开?
- 它适用?Gateway 和节点在同一信任边界内的受信任操作员环境?
- 如果你需要严格的显式信任,保?
autoAllowSkills: false并仅使用手动路径白名单条目?
安全 bins(仅 stdin?
tools.exec.safeBins 定义了一小部?*?stdin** 二进制文件(例如 jq),可以在白名单模式下运?*无需**显式白名单条目。安?bins 拒绝位置文件参数和类似路径的标记,因此它们只能对传入流进行操作?
将其视为流过滤器的狭窄快速路径,而不是一般信任列表?
不要添加解释器或运行时二进制文件(例?python3、node、ruby、bash、sh、zsh)到 safeBins?
如果命令可以评估代码、执行子命令,或按设计读取文件,优先使用显式白名单条目并保持批准提示启用?
自定义安?bins 必须?tools.exec.safeBinProfiles.<bin> 中定义显式配置文件?
验证仅从 argv 形状确定性地进行(无主机文件系统存在检查),这可以防止文件存在 oracle 行为导致 allow/deny 差异?
面向文件的选项被拒绝用于默认安?bins(例?sort -o、sort --output、sort --files0-from、sort --compress-program、sort --random-source、sort --temporary-directory/-T、wc --files0-from、jq -f/--from-file、grep -f/--file)?
安全 bins 还为破坏?stdin 行为的选项强制执行显式每二进制标志策略(例?sort -o/--output/--compress-program ?grep 递归标志)?
在安?bin 模式下,长选项验证失败关闭:未知标志和模糊缩写被拒绝?
按安?bin 配置文件的拒绝标志:
grep:--dereference-recursive,--directories,--exclude-from,--file,--recursive,-R,-d,-f,-rjq:--argfile,--from-file,--library-path,--rawfile,--slurpfile,-L,-fsort:--compress-program,--files0-from,--output,--random-source,--temporary-directory,-T,-owc:--files0-from
安全 bins 还强制在执行时将 argv 标记视为字面文本(无 globbing 和无 $VARS 扩展)用于仅 stdin 段,因此?* ?$HOME/... 这样的模式不能用于走私文件读取?
安全 bins 还必须从受信任的二进制目录解析(系统默认值加上可选的 tools.exec.safeBinTrustedDirs)。PATH 条目永远不会被自动信任?
默认受信任安?bin 目录故意最小化:/bin、/usr/bin?
如果你的安全 bin 可执行文件位于包管理?用户路径(例?/opt/homebrew/bin、/usr/local/bin、/opt/local/bin、/snap/bin),将它们显式添加到 tools.exec.safeBinTrustedDirs?
在白名单模式下,shell 链接和重定向不会自动允许?
当每个顶级段满足白名单(包括安全 bins 或技能自动允许)时,允许 shell 链接(&&、||、;)。重定向在白名单模式下仍然不支持?
在白名单解析期间拒绝命令替换($() / 反引号),包括双引号内部;如果你需要字面的 $() 文本,使用单引号?
?macOS 伴侣应用批准上,包含 shell 控制或扩展语法(&&、||、;、|、`$、$、<、>、(、))的原始 shell 文本被视为白名单未命中,除非 shell 本身在白名单中?
对于 shell 包装器(bash|sh|zsh ... -c/-lc),请求作用域环境覆盖减少为一个小显式白名单(TERM、LANG、LC_*、COLORTERM、NO_COLOR、FORCE_COLOR)?
对于白名单模式中的始终允许决定,已知调度包装器(env、nice、nohup、stdbuf、timeout)保持内部可执行文件路径而不是包装器路径。Shell 多路复用器(busybox、toybox)也?shell 小程序(sh、ash 等)展开,因此内部可执行文件保持而不是多路复用器二进制文件。如果包装器或多路复用器不能安全展开,不会自动持久化白名单条目?
默认安全 bins:jq、cut、uniq、head、tail、tr、wc?
grep ?sort 不在默认列表中。如果你选择加入,为它们的非 stdin 工作流保持显式白名单条目?
对于安全 bin 模式下的 grep,使?-e/--regexp 提供模式;拒绝位置模式形式,因此文件操作数不能作为模糊位置参数走私?
安全 bins 与白名单
| 主题 | tools.exec.safeBins | 白名单(exec-approvals.json? |
|---|---|---|
| 目标 | 自动允许狭窄?stdin 过滤? | 显式信任特定可执行文? |
| 匹配类型 | 可执行文件名 + 安全 bin argv 策略 | 解析的可执行文件路径 glob 模式 |
| 参数范围 | 受安?bin 配置文件和字面标记规则限? | 仅路径匹配;否则参数是你的责? |
| 典型示例 | jq、head、tail、wc | python3、node、ffmpeg、自定义 CLI |
| 最佳用? | 管道中的低风险文本转? | 具有更广泛行为或副作用的任何工具 |
配置位置?
safeBins来自配置(tools.exec.safeBins或每代理agents.list[].tools.exec.safeBins)?safeBinTrustedDirs来自配置(tools.exec.safeBinTrustedDirs或每代理agents.list[].tools.exec.safeBinTrustedDirs)?safeBinProfiles来自配置(tools.exec.safeBinProfiles或每代理agents.list[].tools.exec.safeBinProfiles)。每代理配置文件键覆盖全局键?- 白名单条目存在于主机本地
~/.openclaw/exec-approvals.json下的agents.<id>.allowlist(或通过 Control UI /openclaw approvals allowlist ...)? openclaw security audit当解释器/运行?bins 出现?safeBins中而没有显式配置文件时,用tools.exec.safe_bins_interpreter_unprofiled发出警告?openclaw doctor --fix可以脚手架缺失的自定?safeBinProfiles.<bin>条目?{}(之后检查并收紧)。解释器/运行?bins 不会自动脚手架?
自定义配置文件示例:
{
tools: {
exec: {
safeBins: ["jq", "myfilter"],
safeBinProfiles: {
myfilter: {
minPositional: 0,
maxPositional: 0,
allowedValueFlags: ["-n", "--limit"],
deniedFlags: ["-f", "--file", "-c", "--command"],
},
},
},
},
}
Control UI 编辑
使用 Control UI ?Nodes ?Exec 批准卡片编辑默认值、每代理覆盖和白名单。选择作用域(Defaults 或代理),调整策略,添加/删除白名单模式,然后保存。UI 显示每个模式?*最后使?*元数据,以便你可以保持列表整洁?
目标选择器选择 Gateway(本地批准)?Node。节点必须宣?system.execApprovals.get/set(macOS 应用或无头节点主机)?
如果节点尚未宣传 exec 批准,直接编辑其本地 ~/.openclaw/exec-approvals.json?
CLI:openclaw approvals 支持 gateway 或节点编辑(见批准 CLI)?
批准流程
当需要提示时,gateway 向操作员客户端广?exec.approval.requested。Control UI ?macOS 应用通过 exec.approval.resolve 解决,然?gateway 将批准的请求转发到节点主机?
当需要批准时,exec 工具立即返回一个批?id。使用该 id 关联后续系统事件(Exec finished / Exec denied)。如果超时前没有决定到达,请求被视为批准超时并显示为拒绝原因?
确认对话框包括:
- 命令 + 参数
- cwd
- 代理 id
- 解析的可执行文件路径
- 主机 + 策略元数?
操作?
- *允许一? ?现在运行
- 始终允许 ?添加到白名单 + 运行
- 拒绝 ?阻止
批准转发到聊天频?
你可以将 exec 批准提示转发到任何聊天频道(包括插件频道)并?/approve 批准。这使用正常的出站投递管道?
配置?
{
approvals: {
exec: {
enabled: true,
mode: "session", // "session" | "targets" | "both"
agentFilter: ["main"],
sessionFilter: ["discord"], // substring or regex
targets: [
{ channel: "slack", to: "U12345678" },
{ channel: "telegram", to: "123456789" },
],
},
},
}
在聊天中回复?
/approve <id> allow-once
/approve <id> allow-always
/approve <id> deny
macOS IPC 流程
Gateway -> Node Service (WS)
| IPC (UDS + token + HMAC + TTL)
v
Mac App (UI + approvals + system.run)
安全说明?
- Unix socket 模式 0600,令牌存储在
exec-approvals.json中? - ?UID 对等检查?
- 挑战/响应(nonce + HMAC 令牌 + 请求哈希? ?TTL?
系统事件
Exec 生命周期显示为系统消息:
Exec running(仅当命令超过运行通知阈值时?Exec finishedExec denied
这些在节点报告事件后发布到代理的会话。Gateway 主机 exec 批准在命令完成时发出相同的生命周期事件(以及可选地在超过阈值时运行更长时)?
带批准的 exec 重用批准 id 作为这些消息中的 runId,以便轻松关联?
影响
- full 很强大;尽可能优先使用白名单?
- ask 让你保持参与,同时仍然允许快速批准?
- 每代理白名单防止一个代理的批准泄漏到其他代理?
- 批准仅适用于来?*授权发送?*的主?exec 请求。未经授权的发送者不能发?
/exec? /exec security=full是授权操作员的会话级便利,设计上跳过批准? 要硬阻止主机 exec,将批准安全性设?deny或通过工具策略拒绝exec工具?
相关?