Exec 批准

Exec 批准是伴侣应用 / 节点主机防护,用于让沙箱化代理在真实主机(gatewaynode)上运行命令。把它想象成安全联锁:仅当策略 + 白名单 +(可选)用户批准都同意时才允许命令。 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 拒绝位置文件参数和类似路径的标记,因此它们只能对传入流进行操作? 将其视为流过滤器的狭窄快速路径,而不是一般信任列表? 不要添加解释器或运行时二进制文件(例?python3noderubybashshzsh)到 safeBins? 如果命令可以评估代码、执行子命令,或按设计读取文件,优先使用显式白名单条目并保持批准提示启用? 自定义安?bins 必须?tools.exec.safeBinProfiles.<bin> 中定义显式配置文件? 验证仅从 argv 形状确定性地进行(无主机文件系统存在检查),这可以防止文件存在 oracle 行为导致 allow/deny 差异? 面向文件的选项被拒绝用于默认安?bins(例?sort -osort --outputsort --files0-fromsort --compress-programsort --random-sourcesort --temporary-directory/-Twc --files0-fromjq -f/--from-filegrep -f/--file)? 安全 bins 还为破坏?stdin 行为的选项强制执行显式每二进制标志策略(例?sort -o/--output/--compress-program ?grep 递归标志)? 在安?bin 模式下,长选项验证失败关闭:未知标志和模糊缩写被拒绝? 按安?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

安全 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),请求作用域环境覆盖减少为一个小显式白名单(TERMLANGLC_*COLORTERMNO_COLORFORCE_COLOR)? 对于白名单模式中的始终允许决定,已知调度包装器(envnicenohupstdbuftimeout)保持内部可执行文件路径而不是包装器路径。Shell 多路复用器(busyboxtoybox)也?shell 小程序(shash 等)展开,因此内部可执行文件保持而不是多路复用器二进制文件。如果包装器或多路复用器不能安全展开,不会自动持久化白名单条目?

默认安全 bins:jqcutuniqheadtailtrwc?

grep ?sort 不在默认列表中。如果你选择加入,为它们的非 stdin 工作流保持显式白名单条目? 对于安全 bin 模式下的 grep,使?-e/--regexp 提供模式;拒绝位置模式形式,因此文件操作数不能作为模糊位置参数走私?

安全 bins 与白名单

主题tools.exec.safeBins白名单(exec-approvals.json?
目标自动允许狭窄?stdin 过滤?显式信任特定可执行文?
匹配类型可执行文件名 + 安全 bin argv 策略解析的可执行文件路径 glob 模式
参数范围受安?bin 配置文件和字面标记规则限?仅路径匹配;否则参数是你的责?
典型示例jqheadtailwcpython3nodeffmpeg、自定义 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 finished
  • Exec denied

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

影响

  • full 很强大;尽可能优先使用白名单?
  • ask 让你保持参与,同时仍然允许快速批准?
  • 每代理白名单防止一个代理的批准泄漏到其他代理?
  • 批准仅适用于来?*授权发送?*的主?exec 请求。未经授权的发送者不能发?/exec?
  • /exec security=full 是授权操作员的会话级便利,设计上跳过批准? 要硬阻止主机 exec,将批准安全性设?deny 或通过工具策略拒绝 exec 工具?

相关?