沙箱
OpenClaw 可以在 Docker 容器内运行工具以缩小影响范围。 此功能是可选的,通过配置控制(agents.defaults.sandbox 或
agents.list[].sandbox)。如果沙箱未启用,工具将在宿主机上运行。
Gateway网关始终在宿主机上运行;启用沙箱后,工具执行将在隔离的沙箱中进行。
这并非完美的安全边界,但在模型执行了错误操作时,能有效限制文件系统和进程访问。
哪些内容会被沙箱隔离
- 工具执行(
exec、read、write、edit、apply_patch、process等)。 - 可选的沙箱浏览器(
agents.defaults.sandbox.browser)。- 默认情况下,沙箱浏览器会在浏览器工具需要时自动启动(确保 CDP 可达)。
通过
agents.defaults.sandbox.browser.autoStart和agents.defaults.sandbox.browser.autoStartTimeoutMs进行配置。 agents.defaults.sandbox.browser.allowHostControl允许沙箱会话显式访问宿主机浏览器。- 可选的允许列表控制
target: "custom":allowedControlUrls、allowedControlHosts、allowedControlPorts。
- 默认情况下,沙箱浏览器会在浏览器工具需要时自动启动(确保 CDP 可达)。
通过
- Gateway网关进程本身。
- 任何被显式允许在宿主机上运行的工具(例如
tools.elevated)。- 提权 exec 在宿主机上运行,会绕过沙箱。
- 如果沙箱未启用,
tools.elevated不会改变执行方式(本身已在宿主机上)。参见提权模式。
模式
agents.defaults.sandbox.mode 控制何时使用沙箱:
"off":不使用沙箱。"non-main":仅对非主会话启用沙箱(如果你希望普通聊天在宿主机上运行,这是默认值)。"all":所有会话都在沙箱中运行。 注意:"non-main"基于session.mainKey(默认为"main"),而非智能体 ID。 群组/渠道会话使用各自的键,因此它们被视为非主会话,会被沙箱隔离。
作用域
agents.defaults.sandbox.scope 控制创建多少个容器:
"session"(默认):每个会话一个容器。"agent":每个智能体一个容器。"shared":所有沙箱会话共享一个容器。
工作区访问
agents.defaults.sandbox.workspaceAccess 控制沙箱能看到什么:
"none"(默认):工具在~/.openclaw/sandboxes下的沙箱工作区中运行。"ro":以只读方式将智能体工作区挂载到/agent(禁用write/edit/apply_patch)。"rw":以读写方式将智能体工作区挂载到/workspace。
media/inbound/*)。
Skills 说明:read 工具以沙箱为根目录。当 workspaceAccess: "none" 时,
OpenClaw 会将符合条件的 Skills 镜像到沙箱工作区(.../skills)中以便读取。当设为 "rw" 时,工作区 Skills 可从
/workspace/skills 读取。
自定义绑定挂载
agents.defaults.sandbox.docker.binds 将额外的宿主机目录挂载到容器中。
格式:host:container:mode(例如 "/home/user/source:/source:rw")。
全局和每个智能体的绑定挂载会被合并(而非替换)。在 scope: "shared" 下,每个智能体的绑定挂载会被忽略。
示例(只读源码 + Docker 套接字):
- 绑定挂载会绕过沙箱文件系统:它们以你设置的模式(
:ro或:rw)暴露宿主机路径。 - 敏感挂载(例如
docker.sock、密钥、SSH 密钥)应使用:ro,除非确实需要写入。 - 如果你只需要对工作区的读取权限,可与
workspaceAccess: "ro"配合使用;绑定模式保持独立。 - 参见沙箱 vs 工具策略 vs 提权了解绑定挂载如何与工具策略和提权 exec 交互。
镜像 + 设置
默认镜像:openclaw-sandbox:bookworm-slim
构建一次即可:
sandbox.docker.setupCommand 安装(需要网络出口 + 可写根文件系统 +
root 用户)。
沙箱浏览器镜像:
agents.defaults.sandbox.docker.network 覆盖。
Docker 安装和容器化 Gateway网关的说明在这里:
Docker
setupCommand(一次性容器设置)
setupCommand 在沙箱容器创建后仅运行一次(不会每次运行时都执行)。
它通过 sh -lc 在容器内执行。
路径:
- 全局:
agents.defaults.sandbox.docker.setupCommand - 每个智能体:
agents.list[].sandbox.docker.setupCommand
- 默认
docker.network为"none"(无出口),因此包安装会失败。 readOnlyRoot: true会阻止写入;请设置readOnlyRoot: false或构建自定义镜像。- 包安装需要 root 用户(省略
user或设置user: "0:0")。 - 沙箱 exec 不会继承宿主机的
process.env。请使用agents.defaults.sandbox.docker.env(或自定义镜像)来设置 Skills API 密钥。
工具策略 + 逃逸机制
工具的允许/拒绝策略仍在沙箱规则之前生效。如果某个工具在全局或智能体级别被拒绝,沙箱不会将其恢复。tools.elevated 是一个显式的逃逸机制,在宿主机上运行 exec。
/exec 指令仅对授权发送者生效,且在每个会话中持续有效;要彻底禁用
exec,请使用工具策略拒绝(参见沙箱 vs 工具策略 vs 提权)。
调试:
- 使用
openclaw sandbox explain检查当前生效的沙箱模式、工具策略和修复配置项。 - 参见沙箱 vs 工具策略 vs 提权了解”为什么被阻止了?“的思维模型。 保持锁定状态。
多智能体覆盖
每个智能体可以覆盖沙箱和工具配置:agents.list[].sandbox 和 agents.list[].tools(以及 agents.list[].tools.sandbox.tools 用于沙箱工具策略)。
参见多智能体沙箱与工具了解优先级。