Sandboxing
OpenClaw 可以在 Docker 容器内运行工具来减少影响范围。这是可选的,通过配置控制(agents.defaults.sandbox 或 agents.list[].sandbox)。如果关闭 Sandbox,工具会在宿主机上运行。Gateway 始终在宿主机上运行;启用后,工具执行会在隔离的 Sandbox 中进行。
这不是完美的安全边界,但当模型做出不当操作时,它能有效限制文件系统和进程访问。
哪些会被沙箱化
- 工具执行(
exec、read、write、edit、apply_patch、process等)。 - 可选的 Sandbox 浏览器(
agents.defaults.sandbox.browser)。- 默认情况下,当浏览器工具需要时,Sandbox 浏览器会自动启动(确保 CDP 可访问)。
通过
agents.defaults.sandbox.browser.autoStart和agents.defaults.sandbox.browser.autoStartTimeoutMs配置。 agents.defaults.sandbox.browser.allowHostControl允许 Sandbox Session 明确指向宿主机浏览器。- 可选的白名单控制
target: "custom":allowedControlUrls、allowedControlHosts、allowedControlPorts。
- 默认情况下,当浏览器工具需要时,Sandbox 浏览器会自动启动(确保 CDP 可访问)。
通过
不会被沙箱化的:
- Gateway 进程本身。
- 任何明确允许在宿主机上运行的工具(例如
tools.elevated)。- Elevated exec 在宿主机上运行,绕过 Sandbox。
- 如果 Sandbox 关闭,
tools.elevated不会改变执行方式(本来就在宿主机上)。参见 Elevated 模式。
模式
agents.defaults.sandbox.mode 控制何时使用 Sandbox:
"off":不使用 Sandbox。"non-main":仅对非主 Session 使用 Sandbox(如果你想让普通对话在宿主机上运行,这是默认选择)。"all":每个 Session 都在 Sandbox 中运行。 注意:"non-main"基于session.mainKey(默认为"main"),而不是 Agent ID。 群组/频道 Session 使用自己的 key,所以它们算作非主 Session,会被沙箱化。
作用域
agents.defaults.sandbox.scope 控制创建多少个容器:
"session"(默认):每个 Session 一个容器。"agent":每个 Agent 一个容器。"shared":所有 Sandbox Session 共享一个容器。
Workspace 访问
agents.defaults.sandbox.workspaceAccess 控制 Sandbox 能看到什么:
"none"(默认):工具看到的是~/.openclaw/sandboxes下的 Sandbox Workspace。"ro":以只读方式将 Agent Workspace 挂载到/agent(禁用write/edit/apply_patch)。"rw":以读写方式将 Agent Workspace 挂载到/workspace。
入站媒体文件会被复制到活动的 Sandbox Workspace(media/inbound/*)。
Skill 说明:read 工具以 Sandbox 为根目录。当 workspaceAccess: "none" 时,OpenClaw 会将符合条件的 Skill 镜像到 Sandbox Workspace(.../skills)以便读取。当设为 "rw" 时,Workspace Skill 可以从 /workspace/skills 读取。
自定义绑定挂载
agents.defaults.sandbox.docker.binds 可以将额外的宿主机目录挂载到容器中。
格式:host:container:mode(例如 "/home/user/source:/source:rw")。
全局和单个 Agent 的绑定会合并(不是替换)。在 scope: "shared" 下,单个 Agent 的绑定会被忽略。
示例(只读源码 + Docker socket):
{
agents: {
defaults: {
sandbox: {
docker: {
binds: ["/home/user/source:/source:ro", "/var/run/docker.sock:/var/run/docker.sock"],
},
},
},
list: [
{
id: "build",
sandbox: {
docker: {
binds: ["/mnt/cache:/cache:rw"],
},
},
},
],
},
}
安全注意事项:
- 绑定会绕过 Sandbox 文件系统:它们以你设置的模式(
:ro或:rw)暴露宿主机路径。 - 敏感挂载(例如
docker.sock、密钥、SSH 密钥)应该设为:ro,除非绝对必要。 - 如果你只需要对 Workspace 的读取权限,可以结合
workspaceAccess: "ro";绑定模式保持独立。 - 参见 Sandbox vs Tool Policy vs Elevated 了解绑定如何与工具策略和 elevated exec 交互。
镜像 + 设置
默认镜像:openclaw-sandbox:bookworm-slim
构建一次:
scripts/sandbox-setup.sh
注意:默认镜像不包含 Node。如果 Skill 需要 Node(或其他运行时),可以构建自定义镜像或通过 sandbox.docker.setupCommand 安装(需要网络出站 + 可写根目录 + root 用户)。
Sandbox 浏览器镜像:
scripts/sandbox-browser-setup.sh
默认情况下,Sandbox 容器运行时没有网络。
可以通过 agents.defaults.sandbox.docker.network 覆盖。
Docker 安装和容器化 Gateway 的文档在这里: Docker
setupCommand(一次性容器设置)
setupCommand 在 Sandbox 容器创建后运行一次(不是每次运行都执行)。
它通过 sh -lc 在容器内执行。
路径:
- 全局:
agents.defaults.sandbox.docker.setupCommand - 单个 Agent:
agents.list[].sandbox.docker.setupCommand
常见问题:
- 默认
docker.network是"none"(无出站网络),所以包安装会失败。 readOnlyRoot: true会阻止写入;设置readOnlyRoot: false或构建自定义镜像。user必须是 root 才能安装包(省略user或设置user: "0:0")。- Sandbox exec 不会继承宿主机的
process.env。使用agents.defaults.sandbox.docker.env(或自定义镜像)来设置 Skill API 密钥。
工具策略 + 逃逸通道
工具的允许/拒绝策略仍然在 Sandbox 规则之前应用。如果一个工具在全局或单个 Agent 上被拒绝,Sandbox 不会让它恢复。
tools.elevated 是一个明确的逃逸通道,它在宿主机上运行 exec。
/exec 指令仅对授权发送者有效,并在每个 Session 中持久化;要彻底禁用 exec,使用工具策略拒绝(参见 Sandbox vs Tool Policy vs Elevated)。
调试:
- 使用
openclaw sandbox explain检查有效的 Sandbox 模式、工具策略和修复配置键。 - 参见 Sandbox vs Tool Policy vs Elevated 了解”为什么被阻止?“的思维模型。 保持锁定状态。
多 Agent 覆盖
每个 Agent 可以覆盖 Sandbox + 工具配置:
agents.list[].sandbox 和 agents.list[].tools(以及 agents.list[].tools.sandbox.tools 用于 Sandbox 工具策略)。
参见 Multi-Agent Sandbox & Tools 了解优先级。
最小启用示例
{
agents: {
defaults: {
sandbox: {
mode: "non-main",
scope: "session",
workspaceAccess: "none",
},
},
},
}