Skip to content
广告 · 本站推荐广告

Exec 审批

Exec 审批

Exec 审批是伴侣应用 / 节点主机的安全防护,允许沙箱智能体在真实主机(gatewaynode)上运行命令。可以把它想象成一个安全联锁装置:只有当策略 + 允许列表 + (可选的)用户审批全部通过时,命令才被允许执行。

Exec 审批是在工具策略和提升模式控制之外的附加层(除非 elevated 设置为 full,这会跳过审批)。有效策略取 tools.exec.** 和审批默认值中更严格的那个;如果审批字段被省略,则使用 tools.exec 的值。如果伴侣应用 UI 不可用,任何需要提示的请求都由 ask 回退策略(默认:deny)处理。

适用范围

Exec 审批在执行主机上本地执行:

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

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"
        }
      ]
    }
  }
}

策略控制

Security(exec.security

  • deny:阻止所有主机 exec 请求。
  • allowlist:仅允许已列入允许列表的命令。
  • full:允许一切(等同于提升模式)。

Ask(exec.ask

  • off:从不提示。
  • on-miss:仅在允许列表不匹配时提示。
  • always:每个命令都提示。

Ask 回退(askFallback

如果需要提示但无 UI 可用,回退策略决定:

  • deny:阻止。
  • allowlist:仅在允许列表匹配时允许。
  • full:允许。

允许列表(按智能体)

允许列表按智能体管理。如果存在多个智能体,在 macOS 应用中切换要编辑的智能体。模式为不区分大小写的 glob 匹配。模式应解析为二进制路径(仅基本名称的条目会被忽略)。旧版 agents.default 条目在加载时会迁移到 agents.main

示例:

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

每个允许列表条目跟踪:

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

自动允许技能 CLI

启用自动允许技能 CLI 后,已知技能引用的可执行文件在节点上(macOS 节点或无头节点主机)被视为已列入允许列表。这通过 Gateway RPC 的 skills.bins 获取技能二进制列表。如果你需要严格的手动允许列表,请禁用此功能。

安全二进制文件(仅限 stdin)

tools.exec.safeBins 定义了一小组仅限 stdin 的二进制文件(例如 jq),可以在允许列表模式下无需显式允许列表条目即可运行。安全二进制文件拒绝位置文件参数和类路径标记,因此它们只能操作输入流。验证仅从 argv 形状确定(不做主机文件系统存在性检查),这防止了由允许/拒绝差异导致的文件存在性探测行为。

文件导向的选项对默认安全二进制文件被拒绝(例如 sort -osort --outputsort --files0-fromsort --compress-programwc --files0-fromjq -f/--from-filegrep -f/--file)。安全二进制文件还对破坏仅 stdin 行为的选项执行显式的每二进制标志策略(例如 sort -o/--output/--compress-program 和 grep 递归标志)。

安全二进制文件还强制 argv 标记在执行时被视为字面文本(对 stdin-only 段无 globbing 和 $VARS 展开),因此像 *$HOME/... 这样的模式不能被用来偷读文件。安全二进制文件还必须从可信二进制目录(系统默认值加上启动时 gateway 进程的 PATH)解析。这阻止了请求范围的 PATH 劫持尝试。

在允许列表模式下,shell 链式操作和重定向不会自动允许。当每个顶层段都满足允许列表时(包括安全二进制文件或技能自动允许),shell 链式操作(&&||;)被允许。重定向在允许列表模式下仍不受支持。命令替换($() / 反引号)在允许列表解析期间被拒绝,包括在双引号内;如果需要字面的 $() 文本,请使用单引号。

在 macOS 伴侣应用审批中,包含 shell 控制或展开语法(&&||;|`$<>())的原始 shell 文本被视为允许列表未命中,除非 shell 二进制本身已被列入允许列表。

默认安全二进制文件:jqcutuniqheadtailtrwcgrepsort 不在默认列表中。如果你选择加入,请为其非 stdin 工作流保留显式允许列表条目。对于安全二进制模式下的 grep,请使用 -e/--regexp 提供模式;位置模式形式被拒绝,以防止文件操作数被伪装为模糊位置参数。

控制 UI 编辑

使用控制 UI → Nodes → Exec 审批卡片来编辑默认值、每智能体覆盖和允许列表。选择一个范围(默认或某个智能体),调整策略,添加/删除允许列表模式,然后保存。UI 显示每个模式的最后使用时间元数据,方便你保持列表整洁。

目标选择器选择 Gateway(本地审批)或节点。节点必须声明 system.execApprovals.get/set(macOS 应用或无头节点主机)。如果节点尚未声明 exec 审批,请直接编辑其本地 ~/.openclaw/exec-approvals.json

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

审批流程

当需要提示时,gateway 向操作者客户端广播 exec.approval.requested。控制 UI 和 macOS 应用通过 exec.approval.resolve 解决,然后 gateway 将已批准的请求转发给节点主机。当需要审批时,exec 工具立即返回一个审批 ID。使用该 ID 关联后续系统事件(Exec finished / Exec denied)。如果在超时前未收到决定,请求被视为审批超时并作为拒绝原因呈现。

确认对话框包含:

  • 命令 + 参数
  • 工作目录
  • 智能体 ID
  • 解析后的可执行文件路径
  • 主机 + 策略元数据

操作:

  • 允许一次 → 立即运行
  • 始终允许 → 添加到允许列表 + 运行
  • 拒绝 → 阻止

审批转发到聊天频道

你可以将 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 allow-once
/approve allow-always
/approve deny

macOS IPC 流程

Gateway -> Node Service (WS)
           |
           v
         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

这些消息在节点报告事件后发送到智能体的会话中。Gateway 主机的 exec 审批在命令完成时(以及可选地在运行超过阈值时)发出相同的生命周期事件。需要审批的 exec 将审批 ID 复用为这些消息中的 runId,以便于关联。

注意事项

  • full 权限很大;尽可能使用允许列表。
  • ask 让你保持知情,同时仍允许快速审批。
  • 每智能体的允许列表防止一个智能体的审批泄露到其他智能体。
  • 审批仅适用于来自已授权发送者的主机 exec 请求。未授权发送者无法发出 /exec
  • /exec security=full 是授权操作者的会话级便利功能,按设计跳过审批。要彻底阻止主机 exec,请将审批安全设置为 deny 或通过工具策略拒绝 exec 工具。

相关文档:

基于MIT协议开源 | 内容翻译自 官方文档,同步更新