第 15 章
工具策略:Allow/Deny 规则、沙箱三级配置与 elevated 标志
第15章:工具策略——Allow/Deny 规则、沙箱三级配置与 elevated 标志
概述
OpenClaw 的工具策略系统是整个安全架构的核心。它通过 Allow/Deny 规则控制哪些工具可以被使用,通过沙箱控制代码执行的隔离级别,通过 elevated 标志允许受信任的特定命令绕过沙箱限制。理解这套机制,是在安全与生产力之间找到正确平衡的关键。
15.1 deny > allow 优先级规则
核心设计原则
OpenClaw 的工具策略遵循安全优先设计:
全局 deny > 全局 allow > per-agent allow > per-agent deny
具体而言:
- 全局 deny 的权重最高,无论任何 Agent 配置,被全局拒绝的工具永远不可用
- 全局 allow 为所有 Agent 提供基线可用工具集
- per-agent allow 在全局基础上为特定 Agent 追加权限
- per-agent deny 在全局基础上为特定 Agent 额外限制权限
安全意义
这一设计的安全意义在于:管理员可以通过全局 deny 设置不可突破的安全边界,即使某个 Agent 的配置被恶意篡改(Prompt Injection),攻击者也无法绕过全局 deny 来访问被禁止的工具。
攻击者尝试通过 Prompt Injection 启用 exec 工具
|
v
Agent 配置中 per-agent 添加了 exec allow
|
v
系统检查全局策略:exec 在全局 deny 列表中
|
v
请求被拒绝,Prompt Injection 无效
15.2 全局工具策略配置
基础配置格式
{
"tool_policy": {
"global": {
"deny": [
"exec",
"bash",
"process",
"node_*"
],
"allow": [
"read",
"write",
"edit",
"web_search",
"message",
"memory_search",
"memory_get"
]
}
}
}
通配符支持
{
"tool_policy": {
"global": {
"deny": [
"node_*", // 禁止所有 node_ 前缀的工具
"canvas_*" // 禁止所有 canvas_ 前缀的工具
],
"allow": [
"*" // 允许所有未被 deny 的工具
]
}
}
}
最小权限原则(推荐生产配置)
{
"tool_policy": {
"global": {
"deny": ["*"],
"allow": []
}
}
}
当全局 deny 为 ["*"] 时,默认禁止所有工具,每个 Agent 必须显式申请所需工具权限。
15.3 Per-Agent 工具例外配置
继承 + 覆盖机制
{
"agents": {
"file-processor": {
"tool_policy": {
"inherit_global": true,
"allow": ["read", "write", "edit"],
"deny": ["exec", "bash"]
}
},
"code-executor": {
"tool_policy": {
"inherit_global": true,
"allow": ["read", "exec", "bash"],
"deny": ["browser", "web_search"]
}
},
"web-scraper": {
"tool_policy": {
"inherit_global": true,
"allow": ["browser", "web_search", "write"],
"deny": ["exec", "bash", "process"]
}
}
}
}
层级应用示例
假设全局配置为:
{
"global": {
"deny": ["process", "node_*"],
"allow": ["read", "write", "web_search"]
}
}
各 Agent 工具可用性推导:
| 工具 | 全局策略 | file-processor | code-executor |
|---|---|---|---|
| read | allow | allow(继承) | allow(继承) |
| write | allow | allow(继承) | -- |
| exec | 未配置 | deny(显式) | allow(显式) |
| bash | 未配置 | deny(显式) | allow(显式) |
| process | deny | deny(继承) | deny(继承,无法覆盖) |
| web_search | allow | -- | deny(显式) |
| browser | 未配置 | -- | deny(显式) |
关键点:全局 deny 的
process无法被任何 per-agent 配置覆盖。
15.4 沙箱三级配置
沙箱级别
OpenClaw 提供三种沙箱执行级别:
off ──────► 主机直接执行,无隔离
non-main ──► 主 Agent 在主机,子 Agent 在容器
all ───────► 全部 Agent(含主 Agent)在容器中运行
级别一:off(无沙箱)
{
"sandbox": {
"level": "off"
}
}
适用场景:
- 本地开发环境,完全信任的操作
- 需要访问主机资源(GPU、硬件设备)的场景
- 对性能要求极高,不能接受容器化开销
风险:Agent 的 exec/bash 命令直接在主机执行,存在文件系统破坏风险。
级别二:non-main(次级沙箱)
{
"sandbox": {
"level": "non-main",
"container_backend": "docker",
"image": "openclaw/agent-sandbox:latest"
}
}
执行模型:
主 Agent(主机执行)
|
+--> sessions_spawn --> 子 Agent(容器执行)
| |
| +--> exec(在容器内)
| +--> bash(在容器内)
|
+--> exec(在主机上)⚠️ 注意
适用场景:
- 主 Agent 需要访问主机资源
- 由主 Agent spawn 的子 Agent 需要隔离
级别三:all(全沙箱)
{
"sandbox": {
"level": "all",
"container_backend": "docker",
"image": "openclaw/agent-sandbox:latest",
"resource_limits": {
"cpu": "2",
"memory": "4g",
"disk": "10g",
"network": "limited"
}
}
}
适用场景:
- 处理不可信代码或用户输入
- 多租户场景,需要严格隔离
- 安全合规要求强隔离
执行模型:
主 Agent(容器A中执行)
|
+--> exec(在容器A内)✓ 隔离
+--> bash(在容器A内)✓ 隔离
|
+--> sessions_spawn --> 子 Agent(容器B中执行)✓ 双重隔离
三级沙箱对比
| 维度 | off | non-main | all |
|---|---|---|---|
| 主 Agent exec 隔离 | 否 | 否 | 是 |
| 子 Agent exec 隔离 | 否 | 是 | 是 |
| 性能开销 | 最低 | 中等 | 最高 |
| 主机资源访问 | 完全 | 主 Agent 可访问 | 受限 |
| 适用安全等级 | 低 | 中 | 高 |
| 生产推荐 | 否 | 是(受控场景) | 是(不信任输入) |
15.5 沙箱 Scope 三种隔离粒度
沙箱 Scope 控制容器的共享/隔离范围:
{
"sandbox": {
"level": "all",
"scope": "session"
}
}
session scope(会话隔离)
用户会话 A --> [独立容器 A]
用户会话 B --> [独立容器 B]
(会话间完全隔离)
适用场景:多用户同时使用,每个用户的操作互不影响。
agent scope(Agent 隔离)
会话 A:
主 Agent --> [容器 A1]
子 Agent 1 --> [容器 A2]
子 Agent 2 --> [容器 A3]
(同一会话内不同 Agent 互相隔离)
适用场景:高安全性场景,防止子 Agent 之间互相干扰。
shared scope(共享容器)
主 Agent ─┐
子 Agent 1 ├──► [共享容器]
子 Agent 2 ─┘
(同一会话所有 Agent 共享一个容器)
适用场景:需要 Agent 间共享文件系统和进程的协作场景。
Scope 对比
| Scope | 隔离级别 | 性能 | 适用场景 |
|---|---|---|---|
session |
会话间隔离 | 中 | 多用户服务 |
agent |
Agent 间隔离 | 低(最多容器) | 高安全需求 |
shared |
同会话共享 | 高(最少容器) | 协作式多 Agent |
15.6 沙箱后端三种选择
Docker 后端(推荐)
{
"sandbox": {
"backend": "docker",
"docker": {
"image": "openclaw/agent-sandbox:3.0",
"pull_policy": "if-not-present",
"network_mode": "bridge",
"volumes": [
{
"host": "/workspace",
"container": "/workspace",
"mode": "rw"
}
],
"env": {
"PYTHONPATH": "/workspace"
}
}
}
}
优势:
- 标准化,跨平台
- 丰富的镜像生态
- 精细的资源限制
- 网络隔离能力强
SSH 后端(远程执行)
{
"sandbox": {
"backend": "ssh",
"ssh": {
"host": "sandbox.internal.company.com",
"port": 22,
"user": "agent",
"key_file": "/etc/openclaw/agent_ssh_key",
"known_hosts": "/etc/openclaw/known_hosts"
}
}
}
适用场景:
- 在专用的安全服务器上执行命令
- 访问特定网络环境(如生产数据库服务器)
- 需要特定硬件资源的远程服务器
OpenShell 后端(轻量隔离)
{
"sandbox": {
"backend": "openshell",
"openshell": {
"namespace": "agent-ns",
"user": "nobody",
"chroot": "/var/openclaw/chroot"
}
}
}
适用场景:
- 不支持 Docker 的环境(如部分嵌入式系统)
- 需要比裸机执行更多隔离,但无法使用容器
- 轻量级沙箱需求
三种后端对比
| 后端 | 隔离强度 | 启动速度 | 资源开销 | 适用场景 |
|---|---|---|---|---|
| Docker | 强 | 中(秒级) | 中 | 通用生产环境 |
| SSH | 中(依赖远端) | 慢(连接建立) | 低(本地) | 远程安全执行 |
| OpenShell | 弱 | 快(毫秒级) | 极低 | 嵌入式/轻量 |
15.7 elevated 标志
作用
elevated 标志允许特定命令或工具调用绕过沙箱的文件系统和网络限制,但不绕过工具策略。
重要区分:
- elevated 可以让命令访问沙箱外的路径
- elevated 不能让被 deny 的工具变为可用
配置方式
{
"tools": {
"exec": {
"elevated_commands": [
{
"pattern": "docker build *",
"reason": "需要访问 Docker socket"
},
{
"pattern": "systemctl reload nginx",
"reason": "重载 Nginx 配置"
}
]
}
}
}
elevated 使用示例
{
"tool": "exec",
"input": {
"command": "docker build -t myapp:latest /workspace",
"elevated": true
}
}
elevated 的风险
| 风险 | 说明 | 缓解措施 |
|---|---|---|
| 主机文件系统访问 | 可读写沙箱外的路径 | 使用 pattern 白名单限制命令 |
| 权限提升 | 以较高权限执行命令 | 配合 SSH 后端限制用户权限 |
| 审计困难 | elevated 操作难以追踪 | 启用 elevated 操作日志 |
elevated 最佳实践
{
"tools": {
"exec": {
"elevated_commands": [
{
"pattern": "^docker (build|push|pull) [a-zA-Z0-9/_:-]+$",
"reason": "CI/CD Docker 操作",
"audit_log": true,
"require_approval": false
}
],
"elevated_audit_log": "/var/log/openclaw/elevated.log"
}
}
}
15.8 危险环境变量剥离机制
被剥离的环境变量
在执行 exec 或 bash 之前,OpenClaw 自动剥离以下危险环境变量:
DYLD_INSERT_LIBRARIES // macOS 动态库注入
DYLD_LIBRARY_PATH // macOS 动态库路径劫持
DYLD_FRAMEWORK_PATH // macOS 框架路径劫持
LD_PRELOAD // Linux 共享库预加载
LD_LIBRARY_PATH // Linux 库路径
NODE_OPTIONS // Node.js 选项注入(可执行任意代码)
PYTHONSTARTUP // Python 启动脚本注入
PERL5OPT // Perl 选项注入
RUBYOPT // Ruby 选项注入
为什么这些变量危险
# 攻击示例:通过 NODE_OPTIONS 在任何 Node.js 进程中执行任意代码
export NODE_OPTIONS="--require /tmp/malicious.js"
node legitimate-script.js
# 此时 malicious.js 会在 legitimate-script.js 执行前被加载
# OpenClaw 会在执行前删除 NODE_OPTIONS
# 即使 Agent 被注入了这个变量,它也不会生效
自定义剥离规则
{
"security": {
"strip_env_vars": {
"builtin": true,
"custom_patterns": [
"SECRET_*",
"INTERNAL_*",
"AWS_SECRET_*"
]
}
}
}
15.9 最小权限原则实践配置示例
场景一:纯文档处理 Agent
{
"agent": {
"name": "doc-processor",
"tool_policy": {
"allow": ["read", "write", "edit", "memory_search"],
"deny": ["exec", "bash", "process", "browser", "web_search"]
},
"sandbox": {
"level": "off"
},
"allowed_paths": ["/workspace/docs/**", "/output/**"]
}
}
场景二:受控代码执行 Agent
{
"agent": {
"name": "code-runner",
"tool_policy": {
"allow": ["read", "exec", "bash", "message"],
"deny": ["write", "browser", "process", "web_search"]
},
"sandbox": {
"level": "all",
"backend": "docker",
"scope": "agent",
"docker": {
"image": "python:3.12-slim",
"network_mode": "none",
"resource_limits": {
"cpu": "1",
"memory": "512m"
}
}
}
}
}
场景三:网络爬虫 Agent(高隔离)
{
"agent": {
"name": "web-crawler",
"tool_policy": {
"allow": ["browser", "web_search", "write", "message"],
"deny": ["exec", "bash", "process", "read", "edit"]
},
"sandbox": {
"level": "all",
"backend": "docker",
"scope": "session",
"docker": {
"image": "openclaw/browser-sandbox:latest",
"network_mode": "bridge",
"resource_limits": {
"cpu": "2",
"memory": "2g"
}
}
}
}
}
场景四:多租户 SaaS 平台配置
{
"tool_policy": {
"global": {
"deny": ["process", "node_*", "canvas_*"],
"allow": []
}
},
"sandbox": {
"level": "all",
"backend": "docker",
"scope": "session",
"image": "openclaw/agent-sandbox:latest"
},
"security": {
"strip_env_vars": {
"builtin": true,
"custom_patterns": ["TENANT_SECRET_*", "INTERNAL_*"]
},
"audit_log": {
"enabled": true,
"path": "/var/log/openclaw/audit.log",
"include_tool_inputs": false
}
}
}
15.10 工具策略审计与监控
启用审计日志
{
"security": {
"audit": {
"enabled": true,
"log_path": "/var/log/openclaw/tool_audit.log",
"log_level": "info",
"include": {
"tool_calls": true,
"tool_denials": true,
"elevated_calls": true,
"sandbox_violations": true
}
}
}
}
审计日志格式
{
"timestamp": "2026-04-26T10:23:41Z",
"agent": "code-runner",
"session": "sess_abc123",
"event": "tool_denied",
"tool": "process",
"reason": "global_deny_policy",
"input_summary": "action=start, command=malicious-cmd"
}
实时监控命令
# 监控工具拒绝事件
openclaw monitor --event tool_denied --tail
# 查看 elevated 操作历史
openclaw audit --filter elevated --since 24h
# 导出安全报告
openclaw audit --format json --output security-report.json
15.11 策略继承树完整示例
全局策略
├── deny: [process, node_*]
├── allow: [read, write, web_search]
│
├── Agent: customer-service
│ ├── 继承全局 allow
│ ├── 额外 allow: [message, memory_search]
│ └── 额外 deny: [exec, bash, browser]
│
├── Agent: data-analyst
│ ├── 继承全局 allow
│ ├── 额外 allow: [exec, bash, memory_search]
│ └── 额外 deny: [browser]
│
└── Agent: web-scraper
├── 继承全局 allow
├── 额外 allow: [browser]
└── 额外 deny: [exec, bash, process]
(process 已在全局 deny,重复声明不影响)
本章小结
- deny > allow 优先级是安全边界的基石:全局 deny 无法被任何 Agent 配置突破
- Per-agent 例外 基于继承+覆盖机制,在全局策略基础上精细化控制
- 三级沙箱(off/non-main/all)覆盖从开发到生产的全部场景
- 三种 Scope(session/agent/shared)控制容器隔离粒度
- 三种后端(Docker/SSH/OpenShell)适配不同的基础设施环境
- elevated 标志允许绕过沙箱文件系统限制,但不绕过工具策略,需谨慎使用
- 危险环境变量剥离是防止供应链攻击和注入攻击的重要防线
- 最小权限原则应贯穿所有 Agent 配置:从全局 deny all 开始,按需授权
通过本章的工具策略体系,你可以构建既灵活又安全的 OpenClaw Agent 部署,在生产力与安全性之间找到最佳平衡点。