2026年 OpenClaw Exec Approvals(执行审批)在独占远程 Mac(SSH 无头)怎么落地?tools.exec 策略、审批状态文件与无 UI 保守回退的可复现决策矩阵 + FAQ
把「本地/远端 shell 执行」从模型的一厢情愿,收敛成可审计、可过期、可在无图形界面下运维的策略闭环:tools.exec 只是最后一棒,前面是审批与状态文件。
1. 独占远程 Mac + SSH 无头:你要解决的真正问题
Exec Approvals 的目标不是「多弹一个窗」,而是让 Gateway 在执行前拿到可验证的外部决策。在独占节点上,常见坑是:同一用户下同时跑 CI、Gateway 与手工 ssh,审批状态文件被并发写坏;或 launchd 与交互式 shell 的 HOME、工作目录不一致,导致「以为批了、其实读到另一份状态」。
建议把环境拆成三条不变量写进 Runbook:谁的用户身份跑 Gateway、状态文件只放该用户可写目录、审批令牌与工单 ID 一一对应且带 TTL。若你仍在对齐节点配对与 CLI 能力位,可先对照 节点配对、node 子命令与审批流对照表 ,避免把 PATH/版本漂移误判成审批失效。
2. tools.exec 策略:默认拒绝 + 分级放行
把策略想成四层,越往下越「不可逆」,越需要显式审批或更短 TTL:
- L0 只读探测:
pwd、git status等——可走自动 allowlist,但仍建议记录 trace。 - L1 构建与包管理:
npm ci、xcodebuild——绑定固定工作副本与锁文件,限制并发与超时。 - L2 写系统与凭据:钥匙串、
sudo、修改 launchd——默认拒绝,除非工单 + 双人复核流程已定义。 - L3 出站与数据外泄面:
curl上传、任意 URL——与出站代理/白名单联动,执行前必须 Exec Approval。
与 Plugin Hooks 的「准入层」配合时,可以让 Hooks 做参数摘要与哈希,Exec Approvals 只管是否允许进入 exec 驱动;这样审计字段不会散落在多个插件里。需要端到端 Tool 审计样例时可延伸阅读 Plugin Hooks 与 Tool Call 审计教程。
3. 审批状态文件:路径、原子写、TTL 与观测
无 UI 时,「状态文件」就是人机协作的地面真相。推荐形态(字段名随你使用的 OpenClaw 版本调整,语义保持一致即可):
- 路径:放在 Gateway 运行用户下的固定目录,例如
~/.openclaw/approvals/,禁止软链到共享卷除非明确需要跨会话共享。 - 原子写:先写
.tmp再rename,避免读到半截 JSON;拒绝多进程同时改同一 ticket 文件时不做文件锁的版本。 - TTL:
expires_at必须早于工单 SLA;过期后执行体应 fail-closed 并打明确指标approval_expired。 - 绑定维度:至少绑定
gateway_id+session_id+tool_invocation_id(或等价 trace),防止「一张批条被挪用到另一条会话」。
在 SSH 无头上,用 ls -l、stat 与网关日志中的同一 invocation id 做三联验证,应写进值班手册的第一页。
4. 无 UI 的保守回退:宁可停跑,也不要静默越权
当审批通道不可用(IM 机器人掉线、工单系统 503、令牌旋转失败)时,回退策略只有两类是生产可接受的:
- Fail-closed:
tools.exec对 L2/L3 一律拒绝,模型收到结构化错误,任务进入「待人工」队列。 - 降级到只读工具包:预先声明的 L0/L1 白名单仍可执行,其他工具返回同一错误码,避免模型用侧信道绕过。
不推荐:把审批写进「永远 true」的环境变量方便调试却忘了删;或在无头机上临时 chmod 777 状态目录——这会把独占节点的安全边界一次性撕掉。第一次上机可参考
远程 Mac mini 上最小依赖跑通 OpenClaw
把目录权限与启动身份先钉死,再挂审批。
5. 可复现决策矩阵(节选)
| 场景 | 是否有有效审批文件 | tools.exec 决策 | 用户可见行为 / 指标 |
|---|---|---|---|
| L0 只读命令 | 不需要 | Allow(allowlist 命中) | 审计 INFO;无审批文件 |
| L2 写钥匙串 / sudo | 需要且未过期 | Allow + 单次消费令牌(若支持) | 审计 WARN;exec_high_risk 计数 +1 |
| L2/L3 任意 | 缺失 / 解析失败 | Deny | 错误码 APPROVAL_REQUIRED;不入执行体 |
| 审批服务不可用 | 无法签发新令牌 | Deny(L2+);L0/L1 可保留 | approval_backend_down;触发值班页 |
| 状态文件被篡改(签名校验失败) | — | Deny + 吊销本会话后续 exec | approval_integrity_fail;安全工单 |
矩阵应纳入版本控制:每次 OpenClaw 小版本升级后重跑一遍「矩阵行」的自动化契约测试,防止默认值从 opt-in 变为 opt-out。
6. SSH 无头上的最小验收脚本(思路)
- 用非交互 SSH 触发一次 应拒绝 的 L3 调用,断言日志与返回体都含
APPROVAL_REQUIRED。 - 模拟签发最小审批 JSON(含 TTL),再触发同一调用,断言 仅一次 成功(若实现单次消费)。
- 把系统时间拨快过 TTL(或在测试环境缩短 TTL),断言过期后 fail-closed。
- 并发两路会话争用同一 ticket id,断言一路失败且文件不被撕毁。
7. FAQ
Q:没有桌面,审批是不是只能手工改文件?
A:生产上更推荐「工单系统 / ChatOps / 签名 URL」生成令牌,由受控脚本原子写入状态文件;纯手工适合 break-glass,并要双人复核与更短 TTL。
Q:模型能否自己写审批文件绕过?
A:若模型能写该目录,你就已经输了。状态目录必须对模型进程不可写,仅网关或独立 sidecar 可写;模型只能携带「令牌字符串」,由网关校验后再落盘。
Q:和 node 子命令审批是不是一回事?
A:不同层面。node 配对/能力位管「谁能连上哪台网关」;Exec Approvals 管「连上之后能不能动 shell」。两者要在 Runbook 里分章节写清。
Q:审批太慢导致任务总失败?
A:把长任务改成队列作业(先落盘计划,再异步执行),并对模型侧显式返回「等待审批」状态,避免无限重试打爆网关。
在 Mac mini 上固化审批链更省事
Exec Approvals 与 tools.exec 依赖长期稳定的进程身份、磁盘与 launchd:独占远程 Mac 上若频繁换机或混用交互/守护环境,审批状态文件最容易出现「读错目录」类事故。Apple Silicon Mac mini 在同价位下通常具备更好的能效与统一内存带宽,适合同时跑 Gateway、轻量审计落盘与令牌校验 sidecar,而待机功耗可维持在很低水平,适合小团队 7×24 常驻。
从安全与总拥有成本看,macOS 的 Gatekeeper、SIP 与 FileVault 让无人值守节点的基线更清晰;静音与低故障率也能减少 SSH 排障时间。若你希望把本文的决策矩阵与无头回退策略落在最省心、最省电的硬件上,Mac mini M4 是目前非常值得考虑的起点——现在即可入手,让执行审批真正可审计、可复现。