Skip to content

Exec 审批

Exec 审批是配套应用/节点宿主的安全门,允许沙箱代理在真实宿主机(gatewaynode)上运行命令。可以把它看作一个安全联锁:只有当策略 + allowlist + (可选的)用户审批三者都同意时,命令才会被允许执行。Exec 审批在工具策略和 elevated 门控之上额外生效(除非 elevated 设置为 full 来跳过审批)。有效策略取较严格的一方:tools.exec.* 与审批默认值,若审批字段未设置,则使用 tools.exec 的值。

如果配套应用 UI 不可用,任何需要提示的请求都由 ask 回退处理(默认:deny)。

适用范围

Exec 审批在执行宿主本地执行:

  • Gateway 宿主 → Gateway 机器上的 openclaw 进程
  • 节点宿主 → 节点运行器(macOS 配套应用或无头节点宿主)

信任模型说明:

  • Gateway 身份验证的调用者是该 Gateway 的受信任操作员
  • 配对节点将受信任的操作员能力延伸到节点宿主
  • Exec 审批降低意外执行风险,但不是每用户的身份验证边界
  • 批准的节点宿主运行绑定规范执行上下文:规范 cwd、精确 argv、存在时的 env 绑定,以及可用时的固定可执行路径
  • 对于 Shell 脚本和直接解释器/运行时文件调用,OpenClaw 还会尝试绑定一个具体的本地文件操作数。如果该文件在审批后但执行前发生变化,运行将被拒绝

macOS 分工:

  • 节点宿主服务通过本地 IPC 将 system.run 转发给 macOS 应用
  • macOS 应用执行审批 + 在 UI 上下文中运行命令

设置与存储

审批存储在执行宿主的本地 JSON 文件中:

~/.openclaw/exec-approvals.json

示例结构:

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:只允许已 allowlist 的命令
  • full:允许一切(等同于 elevated)

询问模式(exec.ask

  • off:从不提示
  • on-miss:只在 allowlist 不匹配时提示
  • always:每次命令都提示

询问回退(askFallback

如果需要提示但无法联系到 UI,由回退决定:

  • deny:阻止
  • allowlist:只在 allowlist 匹配时允许
  • full:允许

内联解释器 eval 加固(tools.exec.strictInlineEval

tools.exec.strictInlineEval=true 时,OpenClaw 将内联代码 eval 形式视为仅审批允许,即使解释器二进制本身已在 allowlist 中。

示例:

  • python -c
  • node -enode --evalnode -p
  • ruby -e
  • perl -eperl -E
  • php -r
  • lua -e
  • osascript -e

在严格模式下:这些命令仍需明确审批;allow-always 不会自动为其持久化新 allowlist 条目。

Allowlist(每代理)

Allowlist 是每代理的。若存在多个代理,在 macOS 应用中切换要编辑的代理。模式为不区分大小写的 glob 匹配,应解析为二进制路径(仅 basename 的条目会被忽略)。

示例:

  • ~/Projects/**/bin/peekaboo
  • ~/.local/bin/*
  • /opt/homebrew/bin/rg

每个 allowlist 条目记录:

  • id:用于 UI 标识的稳定 UUID(可选)
  • 最后使用时间戳
  • 最后使用的命令
  • 最后解析的路径

自动允许技能 CLI

启用自动允许技能 CLI 后,已知技能引用的可执行文件在节点(macOS 节点或无头节点宿主)上被视为已 allowlist。这通过 Gateway RPC 使用 skills.bins 获取技能 bin 列表。若需要严格的手动 allowlist,请禁用此选项。

重要信任说明:

  • 这是一个隐式便利 allowlist,与手动路径 allowlist 条目分开
  • 适用于 Gateway 和节点在同一信任边界的受信任操作员环境
  • 如需严格的显式信任,保持 autoAllowSkills: false 并仅使用手动路径 allowlist 条目

Safe Bins(仅 stdin)

tools.exec.safeBins 定义一小组仅 stdin 的二进制文件(如 cut),它们可以在 allowlist 模式下运行,无需显式 allowlist 条目。Safe bins 拒绝位置文件参数和类路径标记,因此只能对传入流进行操作。将其视为流过滤器的窄快速路径,而非通用信任列表。不要safeBins 中添加解释器或运行时二进制文件(如 python3noderubybash)。

默认安全 bin:

cutuniqheadtailtrwc

grepsort 不在默认列表中。如果选择加入,请为其非 stdin 工作流保留显式 allowlist 条目。

被拒绝的 safe bin 标志(按二进制文件):

  • grep--dereference-recursive--directories--exclude-from--file--recursive-R-d-f-r
  • jq--argfile--from-file--library-path--rawfile--slurpfile-L-f
  • sort--compress-program--files0-from--output--random-source--temporary-directory-T-o
  • wc--files0-from

默认受信任 safe bin 目录仅为 /bin/usr/bin。如果 safe bin 可执行文件位于包管理器/用户路径(如 /opt/homebrew/bin),请将其显式添加到 tools.exec.safeBinTrustedDirs

Safe Bins 与 Allowlist 对比

主题tools.exec.safeBinsAllowlist(exec-approvals.json
目标自动允许窄 stdin 过滤器显式信任特定可执行文件
匹配类型可执行文件名 + safe-bin argv 策略已解析的可执行路径 glob 模式
参数范围受 safe-bin 配置和字面量标记规则限制仅路径匹配;参数由您负责
典型示例headtailtrwcjqpython3nodeffmpeg、自定义 CLI
最佳用途管道中的低风险文本转换任何有更广泛行为或副作用的工具

自定义配置示例:

json5
{
  tools: {
    exec: {
      safeBins: ["jq", "myfilter"],
      safeBinProfiles: {
        myfilter: {
          minPositional: 0,
          maxPositional: 0,
          allowedValueFlags: ["-n", "--limit"],
          deniedFlags: ["-f", "--file", "-c", "--command"],
        },
      },
    },
  },
}

小龙虾安全提示:养龙虾时最容易踩的坑是把 safeBins 当通用白名单用——把 python3node 丢进去,结果代理可以跑任意代码。正确做法是用 allowlist 明确信任,配合 strictInlineEval=true 加固。

控制 UI 编辑

使用控制 UI → Nodes → Exec approvals 卡片编辑默认值、每代理覆盖和 allowlist。选择范围(Defaults 或某个代理),调整策略,添加/删除 allowlist 模式,然后保存。UI 显示每个模式的最后使用元数据,方便保持列表整洁。

CLI:openclaw approvals 支持 gateway 或节点编辑(参见审批 CLI)。

审批流程

需要提示时,Gateway 向操作员客户端广播 exec.approval.requested。控制 UI 和 macOS 应用通过 exec.approval.resolve 解决,然后 Gateway 将批准的请求转发到节点宿主。

对于 host=node,审批请求包含规范的 systemRunPlan 载荷。Gateway 在转发批准的 system.run 请求时,以该计划作为权威命令/cwd/会话上下文。

解释器/运行时命令

批准支持的解释器/运行时运行是保守的:

  • 始终绑定精确的 argv/cwd/env 上下文
  • 直接 Shell 脚本和直接运行时文件形式会尽力绑定到一个具体的本地文件快照
  • 常见包管理器包装形式(如 pnpm execnpm exec)在绑定前会被解包

审批等待时,exec 工具立即返回审批 id。使用该 id 关联后续系统事件(Exec finished / Exec denied)。

确认对话框包含:

  • 命令 + 参数
  • cwd
  • 代理 id
  • 解析的可执行路径
  • 宿主 + 策略元数据

操作:

  • Allow once → 立即运行
  • Always allow → 添加到 allowlist + 运行
  • Deny → 阻止

审批转发到聊天频道

可以将 exec 审批提示转发到任意聊天频道,并通过 /approve 批准。这使用标准出站传递管道。

配置:

json5
{
  approvals: {
    exec: {
      enabled: true,
      mode: "session", // "session" | "targets" | "both"
      agentFilter: ["main"],
      sessionFilter: ["discord"], // 子字符串或正则
      targets: [
        { channel: "slack", to: "U12345678" },
        { channel: "telegram", to: "123456789" },
      ],
    },
  },
}

在聊天中回复:

/approve <id> allow-once
/approve <id> allow-always
/approve <id> deny

/approve 命令同时处理 exec 审批和插件审批。如果 ID 不匹配待处理的 exec 审批,它会自动检查插件审批。

插件审批转发

插件审批转发使用与 exec 审批相同的传递管道,但有自己独立的 approvals.plugin 配置。

json5
{
  approvals: {
    plugin: {
      enabled: true,
      mode: "targets",
      agentFilter: ["main"],
      targets: [
        { channel: "slack", to: "U12345678" },
        { channel: "telegram", to: "123456789" },
      ],
    },
  },
}

支持交互式 exec 审批按钮的频道(如 Telegram)也会为插件审批渲染按钮。

内置聊天审批客户端

Discord 和 Telegram 也可以作为显式 exec 审批客户端:

  • Discord:channels.discord.execApprovals.*
  • Telegram:channels.telegram.execApprovals.*

这些客户端是可选加入的。如果频道未启用 exec 审批,OpenClaw 不会将该频道视为审批界面。

共同行为:

  • 只有配置的审批者才能批准或拒绝
  • 请求者不需要是审批者
  • 启用频道传递时,审批提示包含命令文本
  • 如果没有操作员 UI 或配置的审批客户端可接受请求,提示回退到 askFallback

macOS IPC 流程

Gateway -> Node Service (WS)
                 |  IPC (UDS + token + HMAC + TTL)
                 v
             Mac App (UI + approvals + system.run)

安全说明:

  • Unix socket 模式 0600,token 存储在 exec-approvals.json
  • 同 UID 对等检查
  • 挑战/响应(nonce + HMAC token + 请求哈希)+ 短 TTL

系统事件

Exec 生命周期以系统消息形式展示:

  • Exec running(只有命令超过运行通知阈值时)
  • Exec finished
  • Exec denied

这些消息在节点报告事件后发布到代理会话。

影响说明

  • full 权限很强;尽可能优先使用 allowlist
  • ask 让您参与循环,同时仍允许快速审批
  • 每代理 allowlist 防止一个代理的审批泄漏到其他代理
  • 审批只适用于授权发送者发起的宿主 exec 请求
  • /exec security=full 是授权操作员的会话级便利,设计上跳过审批

相关文档