Exec 审批与白名单

Exec 审批与白名单

适用范围

本页面适用于以下场景:

  • 配置 exec 审批或白名单
  • 在 macOS 应用中实现 exec 审批 UX
  • 审查沙箱逃逸提示及其影响

Exec 审批是配套应用/节点主机护栏,用于允许沙箱化代理在真实主机(gatewaynode)上运行命令。可以将其视为安全互锁:只有当策略 + 白名单 +(可选)用户批准全部一致时,才允许执行命令。

Exec 审批是工具策略和提权门控的额外保护层(除非提权设置为 full,此时会跳过审批)。 有效策略是 tools.exec.* 和审批默认值中更严格的那个;如果省略审批字段,则使用 tools.exec 的值。

如果配套应用 UI 不可用,任何需要提示的请求都将由**询问回退(ask fallback)**解决(默认:拒绝)。

适用位置

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

  • gateway 主机 → 网关机器上的 clawdbot 进程
  • node 主机 → 节点运行器(macOS 配套应用或无头节点主机)

macOS 分离:

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

设置与存储

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

~/.clawdbot/exec-approvals.json

示例 schema:

{
  "version": 1,
  "socket": {
    "path": "~/.clawdbot/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 匹配。 模式应解析为二进制路径(仅包含基本名称的条目将被忽略)。 旧的 agents.default 条目会在加载时迁移到 agents.main

示例:

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

每个白名单条目跟踪:

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

自动允许技能 CLI

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

安全二进制(仅 stdin)

tools.exec.safeBins 定义了一小部分仅 stdin的二进制文件(例如 jq),它们可以在白名单模式下运行,无需显式白名单条目。安全二进制拒绝位置文件参数和类路径标记,因此它们只能操作传入的流。

Shell 链接和重定向在白名单模式下不会自动允许。

当每个顶层段都满足白名单(包括安全二进制或技能自动允许)时,允许 Shell 链接(&&||;)。白名单模式下仍不支持重定向。

默认安全二进制:jqgrepcutsortuniqheadtailtrwc

控制界面编辑

使用控制界面 → 节点 → Exec 审批卡片来编辑默认值、按代理覆盖和白名单。选择范围(默认值或某个代理),调整策略,添加/删除白名单模式,然后保存。界面显示每个模式的最后使用元数据,以便保持列表整洁。

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

CLI:clawdbot approvals 支持网关或节点编辑(参见 Approvals CLI)。

审批流程

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

当需要审批时,exec 工具会立即返回一个审批 id。使用该 id 关联后续的系统事件(Exec finished / Exec denied)。如果在超时前未收到决定,该请求将被视为审批超时并作为拒绝原因呈现。

确认对话框包括:

  • 命令 + 参数
  • 工作目录
  • 代理 id
  • 解析的可执行文件路径
  • 主机 + 策略元数据

操作:

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

审批转发到聊天频道

你可以将 exec 审批提示转发到任何聊天频道(包括插件频道),并使用 /approve 批准。这使用正常的出站传递管道。

配置:

{
  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

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

这些在节点报告事件后发布到代理的会话。 网关主机 exec 审批在命令完成时(以及可选地在运行时间超过阈值时)发出相同的生命周期事件。 带审批门控的 exec 在这些消息中重用审批 id 作为 runId,以便于关联。

影响说明

  • full 很强大;尽可能优先使用白名单。
  • ask 让你保持知情,同时仍然允许快速审批。
  • 按代理白名单可防止一个代理的审批泄漏到其他代理。

相关内容: