给 Agent 配置沙箱的人,迟早会遇到一个需求:某个任务确实需要触碰宿主机。于是你找到了 elevated(提升权限模式)。
它看起来像一个开关:关着,命令就待在容器里;打开,命令就能跑到宿主机上。但真正用起来会发现,这个开关背后是一条相当克制的责任链------打开它并不直接赋予你权限,而是赋予你"申请权限的资格"。
本文将讲透这条链:elevated 在 OpenClaw 权限模型中的确切位置、它和 Exec Approval 之间的仲裁关系、Tool Policy 为何能压住它,以及一个几乎所有人都会误判的问题------为什么 elevated=false 的命令仍然可能以 root 身份运行。
文中的所有结论均在 OpenClaw 2026.7.1-2 上验证过,关键结论均附实测输出。
权限不是一个开关,是五个关卡
先勾勒整体图景。从"模型决定要执行一条命令"到"操作系统真的动手",中间隔着五个各司其职的关卡:

这五个关卡的顺序不能颠倒,职责也不能互相替代:
rust
Tool Policy -> 模型是否具备 exec 这个能力
Elevated -> exec 能否离开沙箱
Exec Approval -> 本次执行是否被批准
Exec Host -> 最终落在哪台机器上执行
Linux UID -> 最终拥有什么系统权限
大多数误判都源于把其中两个混为一谈。比如:"我关掉了 elevated,所以命令是低权限的"------这句话把第二关和第五关搞混了,后文会详细解释它错在哪里。
一、Elevated 是 exec 专用的"逃生舱"
官方对它的定义相当克制(来源:Elevated mode):
当 Agent 运行在沙箱中时,它的
exec命令被限制在沙箱环境内。Elevated 模式让 Agent 得以突破这一限制、在沙箱之外执行命令,并配有可调节的审批闸门。
以下三个限定条件值得单独拎出来:
1. 它只对 exec 生效。
elevated 不是一个通用的"权限等级",而是一个专属于 exec 的逃生舱。它不会让工具清单里多出任何一个工具------你原本没有 write,开了 elevated 依然没有。
2. 它仅在沙箱化时才有意义。
对于未启用沙箱的 Agent,exec 本来就运行在宿主机上,此时 elevated 不会改变任何行为。
3. 它决定"去哪",不决定"以谁的身份"。
这是它和 sudo 最本质的区别。
一个还算贴切的类比:沙箱是访客休息室,宿主机是机房。elevated 是申请进入机房的那张门禁卡------但发不发卡由制度决定;进了机房能干什么,取决于你本来的工牌级别。
elevated 在会话级有四个档位,通过斜杠指令切换:
| 指令 | 作用 |
|---|---|
/elevated off |
回到沙箱内执行 |
/elevated on(别名 ask) |
到宿主机执行,保留审批 |
/elevated full |
到宿主机执行,仅在审批策略本身已完全放开时才跳过审批 |
full 那一行的限定语非常关键,第三节将专门展开------这是整套设计中最容易被误读的地方。
二、闸门是两层的,只开一个不够
把 tools.elevated.enabled 设为 true,然后请求一次 elevated=true 的 exec,你可能会收到这样的拒绝信息:
ini
elevated is not available right now (runtime=sandboxed).
Failing gates: allowFrom (tools.elevated.allowFrom.webchat)
这并非版本问题,而是设计如此:总开关之外,还有一道"发送者白名单"。
rust
tools.elevated.enabled -> 总开关,必须为 true
tools.elevated.allowFrom.<渠道> -> 发送者白名单,必须匹配
两层都通过,elevated 才可用;任何一层不过,一律按"不可用"处理。官方还特别注明:渠道插件理论上可以提供回退白名单,但目前没有任何内置渠道实现这个钩子,因此每个渠道都需要显式配置 allowFrom。
如果你使用的是多 Agent 配置,还额外存在两道 per-agent 闸门(agents.entries.*.tools.elevated.*)。它们只能进一步收紧、不能放宽------全局和 per-agent 必须同时通过。
三种状态下的实际表现如下:

值得留意的是中间那一行:闸门未通过时,命令是在执行之前 被拒绝的,runtime 直接返回 elevated 不可用,宿主机上的探针文件从未被创建 。这和 Exec Approval 的 Deny 路径性质相同------被拦下的命令不产生任何副作用,而非执行后再回滚。
闸门全开之后,同一条命令的输出就变了:主机名从容器 ID 变回宿主机名,宿主机 /tmp 下的哨兵文件从不可见变为可见,写入成功。exec 确实离开了沙箱。
三、/elevated full 不等于"跳过审批"
这是整套机制中最反直觉的一处。
发送 /elevated full,界面会回显一句 Elevated mode set to full (auto-approve)。字面上看,审批似乎已经被跳过了。但如果你的 Host 审批策略是 security=allowlist + ask=always,接下来的 exec 仍然会弹出审批卡片------而且卡片上明确写着"有效的批准策略要求每次都批准,因此『始终允许』不可用",连按钮都只剩"允许一次"和"拒绝"。
将 Elevated 级别与审批策略交叉比对,规律便清晰了:

官方对 full 的描述是这样的:只有当解析后的 exec mode / host 审批策略本身已经完全放开 (即 security=full 且 ask=off)时,审批才会被跳过;否则,正常的审批策略照常生效。而 on / ask 模式下,配置的审批规则始终生效。
因此,准确的理解是:
bash
/elevated full ≠ 跳过审批
/elevated full = 当审批策略本来已完全放开时,不再额外加一道审批
换言之,会话级的设置只能收紧权限,不能放松 Host 侧的策略。 这与 Exec Approval 那条"有效策略取更严格者"是同一原则:权限旋钮在不同层级之间取严不取松。
这套设计的价值在于:没有任何一个会话级开关,能单方面调低系统的安全基线。一个被说服的模型、或者一段被注入的提示词,即使成功发出 /elevated full,也动不了 Host 审批策略。
顺带一个实践提醒:界面上的 (auto-approve) 是简化表述,真正决定是否弹出审批卡片的是 Host 审批策略。判断当前安全状态,要看 openclaw approvals get --gateway --json,而不是聊天窗口的回执。
四、上游拦得住,下游拦不住
Elevated 在责任链中的位置,可以从两个方向来理解。

向上:Tool Policy 是硬停止
把 tools.deny 设为 ["exec"],然后在会话中发送 /elevated full,再要求执行 hostname------结果是 Transcript 中没有任何 exec Tool Call ,exec 根本不在工具清单里,模型只能回答"本会话没有 exec 工具"。
这与官方描述一致:工具策略是硬停止 。如果 exec 被工具策略拒绝,elevated 无法覆盖它;沙箱同样不会把一个被删除的工具变回来。顺序很清晰:
rust
Tool Policy -> 决定"有没有这个工具" ← 更上游
Elevated -> 决定"已有的 exec 怎么执行"
Elevated 只能改变已有 exec 的执行方式,不能凭空恢复一个被删除的能力。要彻底关掉 exec,请用 tool policy deny,而不是指望把 elevated 关着。
向下:工具清单管不住 Shell
反过来的一面同样重要,且更容易被忽略。
在一个 workspaceAccess=ro、工具清单里只有 read 和 exec(没有 write )的会话中,让 Agent 执行一条 touch------文件创建成功。
结论是一句值得贴在墙上的话:
Tool API 权限 ≠ 操作系统文件能力。
write / edit / apply_patch 管的是"工具层面能否写入",而 exec 一旦落到宿主机,Shell 自然就能产生写入的副作用。官方也明确说明:工具策略按名字过滤工具可用性,它不检查 exec 内部的副作用。
因此,"这个 Agent 是只读的"是一句需要同时满足六个条件才能成立的断言:
perl
write / edit / apply_patch 是否可用
exec 是否可用
Elevated 是否开启
Exec Host 指向哪里
Workspace 以什么模式挂载
Gateway 以哪个 OS 用户运行
漏掉任何一条,这个判断都站不住脚。
五、为什么 elevated=false 仍然可能是 root
回到开头那个最常见的误判。
elevated 决定的是执行位置 (沙箱内 vs 沙箱外),而不是系统身份 。当一条命令最终落到宿主机执行时,它继承的是 Gateway 进程本身的 Linux 用户 。如果 Gateway 以 root 运行,那么宿主侧的 exec 就是 UID=0------这跟 elevated 是 true 还是 false 没有关系。
同理,沙箱容器里看到的 UID=0 是容器内的 root ,和宿主机的 root 完全是两回事。因此,判断权限时,单独看 id -u 没有意义,必须结合 hostname 和执行位置一起看。
要想真正降权,需要从别处入手:
- 让 Gateway 以非 root 用户运行;
- 或者使用带非特权用户的沙箱镜像。
而不是指望 elevated=false。第五关(Linux UID)从来就不归 elevated 管。
六、一张对照表收尾
将常见说法与实际情况并置对照,大致如下:
| 常见说法 | 实际情况 |
|---|---|
开了 elevated 就有权限了 |
只是获得了申请资格,还要过白名单和审批 |
/elevated full 会跳过审批 |
仅当 Host 审批策略本身已完全放开时才跳过 |
elevated 能绕过 tool policy |
不能,被 deny 的 exec 变不回来 |
删掉 write 工具,Agent 就只读了 |
exec 落到宿主机后,Shell 照样能写 |
elevated=false 是低权限 |
UID 取决于 Gateway 以谁的身份运行 |
| 看聊天窗口回执判断当前状态 | 要看 approvals get 和 sandbox explain |
如果只记一句话:
Elevated管的是"去哪执行",不是"能执行什么",更不是"以谁的身份执行"。
这三件事分别由 Tool Policy、Exec Approval 和 Gateway 的运行身份决定。理解 OpenClaw 的权限模型,本质上就是把这三者分开看。
几条实践建议
- 将
security=full+ask=off视为高危组合 ------只有在这个前提下,/elevated full才会变成无人值守的宿主机执行; - 需要"真只读"的 Agent 时,先问一句:
exec还在工具清单里吗? - 排查"为什么被挡了"时,用
openclaw sandbox explain,它会直接给出失败的闸门名和对应的配置键; - 实验性的权限配置不要长期写在
agents.defaults里,它会被所有 Agent 和 Cron 任务继承。
官方扩展阅读(简体中文)
- Elevated mode · 提权模式 --- 指令档位、两层闸门、解析顺序,以及
elevated不控制什么。 - Sandbox vs Tool Policy vs Elevated --- 三道闸门在一次工具调用中如何组合。
- Exec approvals · 执行审批 ---
security/ask/askFallback与审批流。 - Exec tool · 执行工具 ---
host解析规则与ask模式的仲裁。 - Sandboxing · 沙箱 --- 沙箱模式、挂载与工具策略的关系。
一句话总览
go
Elevated -> `exec` 专用的出沙箱申请,仅在沙箱化时生效
两层闸门 -> `tools.elevated.enabled` + `allowFrom.渠道`,全通过才可用
/elevated on -> 到宿主机执行,审批保留
/elevated full -> 仅当审批策略已完全放开时才跳过审批;只能收紧不能放松
硬停止 -> Tool Policy `deny` 掉的 `exec`,`elevated` 也变不回来
易错点 -> 删掉 `write` ≠ 只读;`elevated=false` ≠ 系统降权