安全加固(二):工具权限与沙箱
一句话目标:把处理不可信内容的 agent 从「默认全权」改成「最小权限 + 人工审批 + OpenClaw 沙箱」,让高危工具根本调不到。
准备
- 已完成上一课《安全加固(一):访问控制与身份》,Gateway 正常运行。
- 能编辑 Gateway 配置文件,并清楚哪些 agent 会接触外部内容(聊天消息、网页、文件)。会用浏览器控制的 agent(见《浏览器控制:让 Claw 替你上网操作》)尤其算在内。
- 分清两类边界:
deny是直接拒绝;审批是受限模式下的另一层,两者叠加生效。
跟我做
第 1 步:默认拒绝高危工具
对任何会接触不可信内容的 agent 或入口(surface),在配置中加一份 deny 列表:
{
tools: {
deny: ["gateway", "cron", "sessions_spawn", "sessions_send"],
},
}理由来自官方文档:gateway 能读取配置(可能暴露密钥与主机拓扑)、发起更新、重启和清理回滚副本;cron 创建的定时任务在原会话结束后仍持续运行;sessions_spawn 与 sessions_send 涉及跨会话派生与消息传递。
预期结果:该 agent 调用这四个工具时被直接拒绝,连审批流程都不进入。
第 2 步:关闭重启与更新的命令入口
在配置里把 commands.restart 设为 false,从命令层面再封一道:
{
commands: {
restart: false,
},
}预期结果:/restart、/update、外部聊天中的 gateway 更新/重启动作、外部 SIGUSR2 重启请求全部失效。注意:清理(cleanup)不会停止 Gateway,也不依赖这个开关,它走 owner/operator 与工具策略门。
第 3 步:把受限运行放进 OpenClaw 沙箱
OpenClaw 沙箱默认关闭:不配置 agents.defaults.sandbox(全局)或 agents.entries.*.sandbox(单个 agent),工具执行就直接跑在宿主机上。开启后 Gateway 进程仍留在宿主,只有工具执行被挪进沙箱后端。官方也明说这不是完美的安全边界,但能在模型犯傻时实质限制它对文件系统与进程的访问。
先加一份最小启用配置:
{
agents: {
defaults: {
sandbox: {
mode: "non-main", // 群/渠道等非主会话进沙箱
scope: "session", // 沙箱环境按会话隔离
workspaceAccess: "none", // 沙箱对 agent workspace 无访问权限
},
},
},
}只想给某个接触不可信内容的 agent 开?把同样的 sandbox 块写到 agents.entries.<id>.sandbox 下。
两层关系要分清:工具策略在沙箱规则之前生效,第 1 步 deny 掉的工具不会因为进了沙箱而复活;反过来 tools.elevated 是显式逃生口,会让 exec 在沙箱外执行,这类 agent 不要开。
沙箱与审批也是叠加的:把该 agent 的会话权限模式设为受限(restricted,即 read-only、guarded、workspace 这类非 Full Access 模式),它请求持久配置或生命周期变更时需要人工审批;Full Access(含 Default)下允许的变更则免审批直接执行。
工具、文件系统、沙箱、操作四类限制相互独立、叠加生效,宿主在执行前还会重新校验实时权限。
沙箱后端有 docker、podman、ssh、openshell、crabbox 等,各后端的具体配置项与隔离级别未在本次采集范围内,请以 docs.openclaw.ai 对应沙箱页面(`docs/gateway/sandboxing/` 及其子页)为准。配好后用 CLI 确认沙箱真的生效:
openclaw sandbox list # 列出沙箱容器、状态与对应会话/agent
openclaw sandbox explain --agent <agent-id> # 查看生效的沙箱模式、workspace 与工具策略预期结果:该 agent 的工具执行发生在沙箱内,对宿主文件系统与进程的访问被限制;它请求持久配置或生命周期变更时弹出人工审批;openclaw sandbox list 能看到对应的沙箱容器。即使某层限制被绕过,其余层仍在。
验证
逐条试一遍:
- 让受限 agent 调用
gateway读配置 → 被 deny 列表直接拒绝。 - 发送
/restart→ 提示已禁用或无响应。 - 让受限 agent 请求一次持久配置变更 → 弹出人工审批,而不是直接执行。
- 让该 agent 在群/渠道会话里执行一次工具(比如抓一个网页),再运行
openclaw sandbox list→ 列表里出现它的沙箱容器与状态。
常见坑
- 把 deny 当成「要审批」:deny 是硬拒绝,审批只发生在受限模式的允许范围内,别混用。
- 以为关掉
commands.restart就锁死了更新:清理(cleanup)等维护动作不依赖这个开关,也不会停止 Gateway,仍由 owner/operator 与工具策略门控。 - agent 默认是 Full Access 还觉得安全:Full Access(含 Default)下允许的变更不弹审批,第 1 步的 deny 列表才是真正的硬边界。
- 以为开了沙箱就能撤掉 deny 列表:工具策略在沙箱规则之前生效,被 deny 的工具不会因为沙箱而恢复;
tools.elevated逃生口更会让exec直接在沙箱外跑。别因为「反正有沙箱」就撤掉第 1 步的硬拒绝。
下一课
工具权限管住了「Claw 能做什么」,OpenClaw 沙箱管住了「在哪跑、能碰到什么」;下一课《安全加固(三):提示注入防御与安全审计》转向「内容能诱导 Claw 做什么」。