diff --git a/docs/zh-CN/cli/devices.md b/docs/zh-CN/cli/devices.md index 1a6800f45..b0e41bb1a 100644 --- a/docs/zh-CN/cli/devices.md +++ b/docs/zh-CN/cli/devices.md @@ -2,15 +2,15 @@ read_when: - 你正在批准设备配对请求 - 你需要轮换或撤销设备令牌 -summary: '`openclaw devices` 的 CLI 参考(设备配对 + 令牌轮换/撤销)' +summary: '`openclaw devices` 的 CLI 参考(设备配对 + 令牌轮换/吊销)' title: 设备 x-i18n: - generated_at: "2026-04-27T14:14:31Z" - model: gpt-5.4 + generated_at: "2026-05-03T00:43:02Z" + model: gpt-5.5 provider: openai - source_hash: df105135a12ec733e45a67792e8447628f1538fc2536a008d615d46d1eaff5c8 + source_hash: fa92fd3ffc671c827fa98870bf9df89f3be90adec167fd8ea32698cf2e69991a source_path: cli/devices.md - workflow: 15 + workflow: 16 --- # `openclaw devices` @@ -28,13 +28,13 @@ openclaw devices list openclaw devices list --json ``` -当设备已配对时,待处理请求的输出会在该设备当前已批准的访问权限旁显示所请求的访问权限。这样可以明确展示作用域/角色升级,而不是看起来像配对已丢失。 +当设备已经配对时,待处理请求的输出会在设备当前已批准访问权限旁显示请求的访问权限。这样可以明确呈现作用域/角色升级,而不会看起来像配对已丢失。 ### `openclaw devices remove ` -删除一个已配对设备条目。 +移除一个已配对设备条目。 -当你使用已配对设备令牌进行身份验证时,非管理员调用方只能删除**自己的**设备条目。删除其他设备需要 `operator.admin`。 +当你使用已配对设备令牌进行身份验证时,非管理员调用方只能移除**自己的**设备条目。移除其他设备需要 `operator.admin`。 ``` openclaw devices remove @@ -53,15 +53,15 @@ openclaw devices clear --yes --pending --json ### `openclaw devices approve [requestId] [--latest]` -通过精确的 `requestId` 批准待处理的设备配对请求。如果省略 `requestId` 或传入 `--latest`,OpenClaw 只会打印所选的待处理请求并退出;在核实详细信息后,请使用精确的请求 ID 重新运行批准命令。 +通过精确的 `requestId` 批准待处理的设备配对请求。如果省略 `requestId` 或传入 `--latest`,OpenClaw 只会打印选中的待处理请求并退出;验证详情后,使用精确的请求 ID 重新运行批准命令。 -如果设备使用变更后的认证详情(角色、作用域或公钥)重试配对,OpenClaw 会取代之前的待处理条目并签发一个新的 `requestId`。请在批准前立即运行 `openclaw devices list` 以使用当前 ID。 +如果设备使用更改后的身份验证详情(角色、作用域或公钥)重试配对,OpenClaw 会取代先前的待处理条目并签发新的 `requestId`。请在批准前立即运行 `openclaw devices list`,以使用当前 ID。 -如果设备已配对且请求更宽泛的作用域或更高的角色,OpenClaw 会保留现有批准状态,并创建一个新的待处理升级请求。在批准前,请查看 `openclaw devices list` 中的 `Requested` 与 `Approved` 列,或使用 `openclaw devices approve --latest` 预览精确的升级内容。 +如果设备已经配对,并请求更宽的作用域或更高的角色,OpenClaw 会保留现有批准,并创建新的待处理升级请求。查看 `openclaw devices list` 中的 `Requested` 与 `Approved` 列,或使用 `openclaw devices approve --latest` 在批准前预览精确的升级内容。 -如果 Gateway 网关 已显式配置 `gateway.nodes.pairing.autoApproveCidrs`,来自匹配客户端 IP 的首次 `role: node` 请求可能会在出现在此列表之前就被批准。该策略默认禁用,且绝不会应用于 operator/browser 客户端或升级请求。 +如果 Gateway 网关显式配置了 `gateway.nodes.pairing.autoApproveCidrs`,来自匹配客户端 IP 的首次 `role: node` 请求可以在出现在此列表之前被批准。该策略默认禁用,并且绝不适用于操作员/浏览器客户端或升级请求。 ``` openclaw devices approve @@ -79,59 +79,58 @@ openclaw devices reject ### `openclaw devices rotate --device --role [--scope ]` -为特定角色轮换设备令牌(可选地更新作用域)。 -目标角色必须已存在于该设备已批准的配对契约中;轮换不能铸造新的未批准角色。 -如果你省略 `--scope`,之后使用已存储的轮换后令牌重新连接时,会复用该令牌缓存的已批准作用域。如果你传入显式的 `--scope` 值,这些值将成为未来缓存令牌重新连接时所使用的已存储作用域集合。 +为特定角色轮换设备令牌(可选择更新作用域)。 +目标角色必须已经存在于该设备已批准的配对契约中;轮换不能生成新的未批准角色。 +如果省略 `--scope`,之后使用存储的已轮换令牌重新连接时,会复用该令牌缓存的已批准作用域。如果传入显式的 `--scope` 值,这些值会成为未来缓存令牌重新连接时存储的作用域集合。 非管理员已配对设备调用方只能轮换**自己的**设备令牌。 -目标令牌的作用域集合必须保持在调用方当前会话自身的 operator 作用域范围内;轮换不能铸造或保留比调用方当前拥有的更宽泛的 operator 令牌。 +目标令牌作用域集合必须保持在调用方会话自身的操作员作用域内;轮换不能生成或保留比调用方现有权限更宽的操作员令牌。 ``` openclaw devices rotate --device --role operator --scope operator.read --scope operator.write ``` -以 JSON 格式返回轮换元数据。如果调用方正在轮换自己的令牌,且当前使用该设备令牌进行身份验证,则响应还会包含替换令牌,以便客户端在重新连接前持久化保存。共享/管理员轮换不会回显 bearer token。 +以 JSON 返回轮换元数据。如果调用方在使用该设备令牌进行身份验证时轮换自己的令牌,响应还会包含替换令牌,以便客户端在重新连接前持久化它。共享/管理员轮换不会回显 bearer 令牌。 ### `openclaw devices revoke --device --role ` 撤销特定角色的设备令牌。 -非管理员已配对设备调用方只能撤销**自己的**设备令牌。 -撤销其他设备的令牌需要 `operator.admin`。 -目标令牌的作用域集合也必须符合调用方当前会话自身的 operator 作用域;仅具备配对权限的调用方不能撤销 admin/write operator 令牌。 +非管理员已配对设备调用方只能撤销**自己的**设备令牌。撤销其他设备的令牌需要 `operator.admin`。 +目标令牌作用域集合也必须适配调用方会话自身的操作员作用域;仅配对调用方不能撤销管理员/写入操作员令牌。 ``` openclaw devices revoke --device --role node ``` -以 JSON 格式返回撤销结果。 +以 JSON 返回撤销结果。 ## 常用选项 -- `--url `:Gateway 网关 WebSocket URL(配置时默认使用 `gateway.remote.url`)。 +- `--url `:Gateway 网关 WebSocket URL(配置后默认为 `gateway.remote.url`)。 - `--token `:Gateway 网关令牌(如果需要)。 -- `--password `:Gateway 网关密码(密码认证)。 +- `--password `:Gateway 网关密码(密码身份验证)。 - `--timeout `:RPC 超时。 - `--json`:JSON 输出(推荐用于脚本)。 -当你设置 `--url` 时,CLI 不会回退到配置或环境变量凭证。请显式传入 `--token` 或 `--password`。如果缺少显式凭证,将报错。 +当你设置 `--url` 时,CLI 不会回退到配置或环境凭证。请显式传入 `--token` 或 `--password`。缺少显式凭证是错误。 -## 说明 +## 注释 -- 令牌轮换会返回一个新令牌(敏感信息)。请像对待密钥一样对待它。 -- 这些命令需要 `operator.pairing`(或 `operator.admin`)作用域。 -- `gateway.nodes.pairing.autoApproveCidrs` 是一项可选启用的 Gateway 网关策略,仅适用于新的节点设备配对;它不会改变 CLI 的批准权限。 -- 令牌轮换和撤销始终限制在该设备已批准的配对角色集合和已批准的作用域基线之内。一个游离的缓存令牌条目不会授予令牌管理目标。 -- 对于已配对设备令牌会话,跨设备管理仅限管理员:`remove`、`rotate` 和 `revoke` 仅限操作自身,除非调用方具有 `operator.admin`。 -- 令牌变更同样受调用方作用域限制:仅具备配对权限的会话不能轮换或撤销当前携带 `operator.admin` 或 `operator.write` 的令牌。 -- `devices clear` 被有意通过 `--yes` 进行保护。 -- 如果 local loopback 上不可用配对作用域(且未传入显式 `--url`),`list`/`approve` 可以使用本地配对回退。 -- `devices approve` 在铸造令牌前需要显式请求 ID;省略 `requestId` 或传入 `--latest` 只会预览最新的待处理请求。 +- 令牌轮换会返回新令牌(敏感)。请像对待密钥一样处理它。 +- 这些命令需要 `operator.pairing`(或 `operator.admin`)作用域。某些批准还要求调用方持有目标设备将生成或继承的操作员作用域;请参阅[操作员作用域](/zh-CN/gateway/operator-scopes)。 +- `gateway.nodes.pairing.autoApproveCidrs` 是一个仅用于新节点设备配对的可选 Gateway 网关策略;它不会更改 CLI 批准权限。 +- 令牌轮换和撤销会保持在该设备已批准的配对角色集合和已批准作用域基线内。零散的缓存令牌条目不会授予令牌管理目标权限。 +- 对于已配对设备令牌会话,跨设备管理仅限管理员:除非调用方具有 `operator.admin`,否则 `remove`、`rotate` 和 `revoke` 只能作用于自身。 +- 令牌变更也受调用方作用域约束:仅配对会话不能轮换或撤销当前携带 `operator.admin` 或 `operator.write` 的令牌。 +- `devices clear` 有意由 `--yes` 保护。 +- 如果 local loopback 上不可用配对作用域(且未传入显式的 `--url`),list/approve 可以使用本地配对回退。 +- `devices approve` 在生成令牌前需要显式请求 ID;省略 `requestId` 或传入 `--latest` 只会预览最新的待处理请求。 ## 令牌漂移恢复检查清单 -当 Control UI 或其他客户端持续因 `AUTH_TOKEN_MISMATCH` 或 `AUTH_DEVICE_TOKEN_MISMATCH` 失败时,请使用此清单。 +当控制 UI 或其他客户端持续因 `AUTH_TOKEN_MISMATCH` 或 `AUTH_DEVICE_TOKEN_MISMATCH` 失败时使用此清单。 1. 确认当前 Gateway 网关令牌来源: @@ -145,13 +144,13 @@ openclaw config get gateway.auth.token openclaw devices list ``` -3. 为受影响设备轮换 operator 令牌: +3. 为受影响设备轮换操作员令牌: ```bash openclaw devices rotate --device --role operator ``` -4. 如果轮换仍不足以解决问题,请移除过期配对并重新批准: +4. 如果轮换仍不足以解决问题,移除过期配对并再次批准: ```bash openclaw devices remove @@ -161,14 +160,14 @@ openclaw devices approve 5. 使用当前共享令牌/密码重试客户端连接。 -说明: +注释: -- 正常重连认证优先级依次为:显式共享令牌/密码,然后是显式 `deviceToken`,然后是已存储设备令牌,最后是引导令牌。 -- 可信的 `AUTH_TOKEN_MISMATCH` 恢复在一次受限重试中,可以临时同时发送共享令牌和已存储设备令牌。 +- 正常重新连接的身份验证优先级是先显式共享令牌/密码,然后显式 `deviceToken`,然后存储的设备令牌,最后是引导令牌。 +- 受信任的 `AUTH_TOKEN_MISMATCH` 恢复可以在一次有界重试中临时同时发送共享令牌和存储的设备令牌。 -相关内容: +相关: -- [Dashboard 认证故障排除](/zh-CN/web/dashboard#if-you-see-unauthorized-1008) +- [仪表板身份验证故障排除](/zh-CN/web/dashboard#if-you-see-unauthorized-1008) - [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting#dashboard-control-ui-connectivity) ## 相关 diff --git a/docs/zh-CN/gateway/operator-scopes.md b/docs/zh-CN/gateway/operator-scopes.md new file mode 100644 index 000000000..3f7614c0c --- /dev/null +++ b/docs/zh-CN/gateway/operator-scopes.md @@ -0,0 +1,113 @@ +--- +read_when: + - 调试缺少操作员作用域的错误 + - 查看设备或节点配对审批 + - 添加或分类 Gateway 网关 RPC 方法 +summary: Gateway 网关客户端的操作员角色、作用域和批准时检查 +title: 操作员作用域 +x-i18n: + generated_at: "2026-05-03T00:43:07Z" + model: gpt-5.5 + provider: openai + source_hash: 48f59f96b41333af9124ad4083ac5442eedb2d6cebdfff74e3ba256f06d36add + source_path: gateway/operator-scopes.md + workflow: 16 +--- + +Operator 作用域定义了 Gateway 网关客户端在认证后可以执行什么操作。 +它们是一个受信任 Gateway 网关 operator 域内的控制平面防护栏, +不是敌意多租户隔离。如果你需要在人员、团队或机器之间实现强隔离, +请在不同 OS 用户或主机下运行独立的 Gateway 网关。 + +相关:[安全](/zh-CN/gateway/security)、[Gateway 网关协议](/zh-CN/gateway/protocol)、 +[Gateway 网关配对](/zh-CN/gateway/pairing)、[设备 CLI](/zh-CN/cli/devices)。 + +## 角色 + +Gateway 网关 WebSocket 客户端以一种角色连接: + +- `operator`:控制平面客户端,例如 CLI、Control UI、自动化以及 + 受信任的辅助进程。 +- `node`:能力主机,例如 macOS、iOS、Android,或通过 + `node.invoke` 暴露命令的无头节点。 + +Operator RPC 方法要求 `operator` 角色。节点发起的方法 +要求 `node` 角色。 + +## 作用域级别 + +| 作用域 | 含义 | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `operator.read` | 只读 Status、列表、目录、日志、会话读取,以及其他不会变更控制平面的调用。 | +| `operator.write` | 常规可变更 operator 操作,例如发送消息、调用工具、更新 talk/voice 设置,以及节点命令转发。也满足 `operator.read`。 | +| `operator.admin` | 管理性控制平面访问。满足每个 `operator.*` 作用域。配置变更、更新、原生钩子、敏感保留命名空间和高风险批准都需要它。 | +| `operator.pairing` | 设备和节点配对管理,包括列出、批准、拒绝、移除、轮换和撤销配对记录或设备令牌。 | +| `operator.approvals` | Exec 和插件批准 API。 | +| `operator.talk.secrets` | 读取包含密钥的 Talk 配置。 | + +未知的未来 `operator.*` 作用域需要精确匹配,除非调用方拥有 +`operator.admin`。 + +## 方法作用域只是第一道门槛 + +每个 Gateway 网关 RPC 都有一个最小权限方法作用域。该方法作用域决定 +请求是否可以到达处理程序。然后,一些处理程序会根据具体要批准或变更的对象, +在批准时应用更严格的检查。 + +示例: + +- `device.pair.approve` 可通过 `operator.pairing` 访问,但批准 + operator 设备时,只能签发或保留调用方已经持有的作用域。 +- `node.pair.approve` 可通过 `operator.pairing` 访问,然后从待处理的节点命令列表中 + 派生额外的批准作用域。 +- `chat.send` 通常是写入作用域方法,但持久化的 `/config set` + 和 `/config unset` 在命令级别要求 `operator.admin`。 + +这让较低作用域的 operator 可以执行低风险配对操作,而不必让 +所有配对批准都只能由管理员执行。 + +## 设备配对批准 + +设备配对记录是已批准角色和作用域的持久来源。 +已配对设备不会静默获得更广泛访问权限:重新连接时如果请求 +更广泛角色或更广泛作用域,会创建新的待处理升级请求。 + +批准设备请求时: + +- 没有 operator 角色的请求不需要 operator 令牌作用域批准。 +- 请求 `operator.read`、`operator.write`、`operator.approvals`、 + `operator.pairing` 或 `operator.talk.secrets` 时,调用方必须持有 + 这些作用域,或持有 `operator.admin`。 +- 请求 `operator.admin` 时需要 `operator.admin`。 +- 没有显式作用域的修复请求可以继承现有 operator + 令牌作用域。如果该现有令牌具有 admin 作用域,批准仍然需要 + `operator.admin`。 + +对于已配对设备令牌会话,除非调用方也拥有 `operator.admin`, +否则管理操作受自身作用域限制:非管理员调用方只能轮换、撤销或移除 +自己的设备条目。 + +## 节点配对批准 + +旧版 `node.pair.*` 使用单独的 Gateway 网关拥有的节点配对存储。WS 节点 +使用带有 `role: node` 的设备配对,但适用相同的批准级别词汇。 + +`node.pair.approve` 使用待处理请求命令列表来派生额外的 +必需作用域: + +- 无命令请求:`operator.pairing` +- 非 exec 节点命令:`operator.pairing` + `operator.write` +- `system.run`、`system.run.prepare` 或 `system.which`: + `operator.pairing` + `operator.admin` + +节点配对建立身份和信任。它不会替代节点自身的 +`system.run` exec 批准策略。 + +## 共享密钥认证 + +共享 gateway 令牌/密码认证会被视为该 Gateway 网关的受信任 operator 访问。 +OpenAI 兼容 HTTP 接口和 `/tools/invoke` 会为共享密钥 bearer 认证 +恢复正常的完整 operator 默认作用域集合,即使调用方发送了更窄的声明作用域。 + +带身份的模式,例如受信任代理认证或私有入口 `none`, +仍然可以遵守显式声明的作用域。对于真正的信任边界隔离,请使用独立的 Gateway 网关。 diff --git a/docs/zh-CN/gateway/pairing.md b/docs/zh-CN/gateway/pairing.md index 5e8cd41cc..2ef008824 100644 --- a/docs/zh-CN/gateway/pairing.md +++ b/docs/zh-CN/gateway/pairing.md @@ -1,40 +1,45 @@ --- read_when: - - 无需 macOS 界面实现节点配对审批 + - 实现无需 macOS 界面的节点配对批准 - 添加用于批准远程节点的 CLI 流程 - - 扩展 Gateway 网关协议以支持节点管理 -summary: 适用于 iOS 和其他远程节点的 Gateway 网关所有节点配对(选项 B) + - 使用节点管理扩展 Gateway 网关协议 +summary: 适用于 iOS 和其他远程节点的 Gateway 网关托管节点配对(选项 B) title: Gateway 网关负责的配对 x-i18n: - generated_at: "2026-04-28T11:53:19Z" + generated_at: "2026-05-03T00:43:10Z" model: gpt-5.5 provider: openai - source_hash: 5c662b8f5c1bb44cfc306d42ae19ba1c8bc36e0d96130d730b322ee07e02cad8 + source_hash: f0ce46d487990860ac572c27cc9dd83839e87329132e2624944660bafaf723de source_path: gateway/pairing.md workflow: 16 --- -在 Gateway 网关拥有的配对中,**Gateway 网关** 是允许哪些节点加入的事实来源。UI(macOS 应用、未来的客户端)只是用于批准或拒绝待处理请求的前端。 +在 Gateway 网关负责的配对中,**Gateway 网关**是决定哪些节点 +被允许加入的事实来源。UI(macOS 应用、未来客户端)只是用于 +批准或拒绝待处理请求的前端。 -**重要:** WS 节点在 `connect` 期间使用**设备配对**(角色 `node`)。`node.pair.*` 是单独的配对存储,并**不会**限制 WS 握手。只有显式调用 `node.pair.*` 的客户端才使用此流程。 +**重要:** WS 节点在 `connect` 期间使用**设备配对**(角色 `node`)。 +`node.pair.*` 是单独的配对存储,**不会**作为 WS 握手的准入门槛。 +只有显式调用 `node.pair.*` 的客户端才会使用此流程。 ## 概念 - **待处理请求**:节点请求加入;需要批准。 -- **已配对节点**:已批准并签发了认证令牌的节点。 -- **传输协议**:Gateway 网关 WS 端点会转发请求,但不决定成员资格。(旧版 TCP 桥接支持已移除。) +- **已配对节点**:已获批准并签发了身份验证令牌的节点。 +- **传输协议**:Gateway 网关 WS 端点会转发请求,但不决定 + 成员资格。(旧版 TCP 桥接支持已移除。) -## 配对的工作方式 +## 配对如何工作 1. 节点连接到 Gateway 网关 WS 并请求配对。 2. Gateway 网关存储一个**待处理请求**并发出 `node.pair.requested`。 3. 你批准或拒绝该请求(CLI 或 UI)。 4. 批准后,Gateway 网关签发一个**新令牌**(重新配对时会轮换令牌)。 -5. 节点使用该令牌重新连接,此时即为“已配对”。 +5. 节点使用令牌重新连接,此时即为“已配对”。 待处理请求会在 **5 分钟**后自动过期。 -## CLI 工作流(适合无头环境) +## CLI 工作流(适合无界面环境) ```bash openclaw nodes pending @@ -60,64 +65,74 @@ openclaw nodes rename --node --name "Living Room iPad" - `node.pair.list` — 列出待处理 + 已配对节点(`operator.pairing`)。 - `node.pair.approve` — 批准待处理请求(签发令牌)。 - `node.pair.reject` — 拒绝待处理请求。 -- `node.pair.remove` — 移除陈旧的已配对节点条目。 +- `node.pair.remove` — 移除过时的已配对节点条目。 - `node.pair.verify` — 验证 `{ nodeId, token }`。 -注意事项: +注意: -- `node.pair.request` 对每个节点都是幂等的:重复调用会返回同一个待处理请求。 -- 对同一个待处理节点的重复请求也会刷新已存储的节点元数据,以及最新的允许列表内已声明命令快照,供操作员查看。 -- 批准**始终**会生成新令牌;`node.pair.request` 永远不会返回令牌。 +- `node.pair.request` 对每个节点是幂等的:重复调用会返回同一个 + 待处理请求。 +- 同一待处理节点的重复请求也会刷新已存储的节点 + 元数据,以及最新的已声明命令允许列表快照,供操作者查看。 +- 批准**总是**生成全新令牌;`node.pair.request` + 永远不会返回令牌。 +- 操作者作用域级别和批准时检查总结在 + [操作者作用域](/zh-CN/gateway/operator-scopes)中。 - 请求可以包含 `silent: true`,作为自动批准流程的提示。 -- `node.pair.approve` 使用待处理请求声明的命令来强制执行额外的批准作用域: +- `node.pair.approve` 使用待处理请求中声明的命令来强制执行 + 额外批准作用域: - 无命令请求:`operator.pairing` - 非 exec 命令请求:`operator.pairing` + `operator.write` - `system.run` / `system.run.prepare` / `system.which` 请求: `operator.pairing` + `operator.admin` -节点配对是信任与身份流程,并会签发令牌。它**不会**按节点固定实时节点命令表面。 +节点配对是一套信任和身份流程,并会签发令牌。它**不会**按节点固定实时节点命令表面。 - 实时节点命令来自节点在连接时声明的内容,并且会先应用 Gateway 网关的全局节点命令策略(`gateway.nodes.allowCommands` 和 `denyCommands`)。 -- 按节点的 `system.run` 允许与询问策略位于节点上的 `exec.approvals.node.*`,不在配对记录中。 +- 每个节点的 `system.run` 允许和询问策略位于节点上的 `exec.approvals.node.*`,不在配对记录中。 -## 节点命令限制(2026.3.31+) +## 节点命令门控(2026.3.31+) -**破坏性变更:** 从 `2026.3.31` 开始,节点命令会被禁用,直到节点配对获得批准。仅完成设备配对已不足以暴露已声明的节点命令。 +**重大变更:** 从 `2026.3.31` 开始,节点命令会被禁用,直到节点配对获得批准。仅完成设备配对已不足以暴露声明的节点命令。 -当节点首次连接时,会自动请求配对。在配对请求获批之前,该节点的所有待处理节点命令都会被过滤,并且不会执行。一旦通过配对批准建立信任,节点声明的命令就会在正常命令策略约束下可用。 +当节点首次连接时,会自动请求配对。在配对请求获得批准之前,来自该节点的所有待处理节点命令都会被过滤,并且不会执行。一旦通过配对批准建立信任,节点声明的命令就会在正常命令策略约束下可用。 这意味着: -- 以前仅依赖设备配对来暴露命令的节点,现在必须完成节点配对。 -- 配对批准之前排队的命令会被丢弃,而不是延后执行。 +- 之前仅依赖设备配对来暴露命令的节点,现在必须完成节点配对。 +- 配对批准前排队的命令会被丢弃,而不是延后执行。 ## 节点事件信任边界(2026.3.31+) -**破坏性变更:** 节点发起的运行现在会停留在缩减后的受信任表面上。 +**重大变更:** 节点发起的运行现在会停留在缩减后的可信表面上。 -节点发起的摘要及相关会话事件会被限制在预期的受信任表面内。以前依赖更广泛主机或会话工具访问权限的通知驱动流程或节点触发流程可能需要调整。此加固可确保节点事件无法提升到超出节点信任边界允许范围的主机级工具访问权限。 +节点发起的摘要和相关会话事件会被限制在预期的可信表面内。之前依赖更广泛主机或会话工具访问权限的通知驱动或节点触发流程,可能需要调整。此加固确保节点事件无法提升为超出节点信任边界所允许范围的主机级工具访问。 -持久的节点在线状态更新遵循相同的身份边界。`node.presence.alive` 事件仅接受来自已认证节点设备会话的事件,并且只有当设备/节点身份已经配对时才会更新配对元数据。自行声明的 `client.id` 值不足以写入最后在线状态。 +持久节点在线状态更新遵循相同的身份边界。`node.presence.alive` 事件 +只接受来自已认证节点设备会话的事件,并且仅在 +设备/节点身份已经配对时更新配对元数据。自声明的 `client.id` 值不足以写入 +最后在线状态。 ## 自动批准(macOS 应用) -macOS 应用在以下情况下可以选择尝试**静默批准**: +macOS 应用可以在以下情况下选择尝试**静默批准**: - 请求被标记为 `silent`,并且 - 应用可以使用同一用户验证到 Gateway 网关主机的 SSH 连接。 -如果静默批准失败,它会回退到正常的“批准/拒绝”提示。 +如果静默批准失败,它会回退到常规的“批准/拒绝”提示。 -## 受信任 CIDR 设备自动批准 +## 可信 CIDR 设备自动批准 -`role: node` 的 WS 设备配对默认仍为手动。对于 Gateway 网关已信任网络路径的私有节点网络,操作员可以通过显式 CIDR 或精确 IP 选择启用: +`role: node` 的 WS 设备配对默认仍为手动。对于 Gateway 网关已经信任网络路径的私有 +节点网络,操作者可以通过显式 CIDR 或精确 IP 选择启用: ```json5 { @@ -134,25 +149,42 @@ macOS 应用在以下情况下可以选择尝试**静默批准**: 安全边界: - 未设置 `gateway.nodes.pairing.autoApproveCidrs` 时禁用。 -- 不存在泛化的 LAN 或私有网络自动批准模式。 +- 不存在 blanket LAN 或私有网络自动批准模式。 - 只有没有请求作用域的新 `role: node` 设备配对符合条件。 -- 操作员、浏览器、Control UI 和 WebChat 客户端仍为手动。 -- 角色、作用域、元数据和公钥升级仍为手动。 -- 同主机 loopback 受信任代理标头路径不符合条件,因为本地调用方可以伪造该路径。 +- 操作者、浏览器、Control UI 和 WebChat 客户端仍保持手动。 +- 角色、作用域、元数据和公钥升级仍保持手动。 +- 同主机 local loopback 可信代理标头路径不符合条件,因为该 + 路径可能被本地调用方伪造。 ## 元数据升级自动批准 -当已配对设备重新连接且仅包含非敏感元数据变更(例如显示名称或客户端平台提示)时,OpenClaw 会将其视为 `metadata-upgrade`。静默自动批准的范围很窄:它仅适用于受信任的非浏览器本地重连,且这些重连已经证明拥有本地或共享凭证,包括同主机原生应用在 OS 版本元数据变更后的重连。浏览器/Control UI 客户端和远程客户端仍使用显式重新批准流程。作用域升级(从读取到写入/管理员)和公钥变更**不**符合元数据升级自动批准条件,它们仍作为显式重新批准请求处理。 +当已配对设备重新连接且只有非敏感元数据 +变更(例如显示名称或客户端平台提示)时,OpenClaw 会将其视为 +`metadata-upgrade`。静默自动批准的范围很窄:它只适用于已经证明拥有本地 +或共享凭证的可信非浏览器本地重连,包括同主机原生应用在 OS +版本元数据变更后的重新连接。浏览器/Control UI 客户端和远程客户端仍然 +使用显式重新批准流程。作用域升级(从读取到写入/admin)和 +公钥变更**不**符合元数据升级自动批准条件 — +它们仍保持为显式重新批准请求。 ## QR 配对辅助工具 -`/pair qr` 会将配对负载渲染为结构化媒体,以便移动端和浏览器客户端可以直接扫描。 +`/pair qr` 会将配对载荷渲染为结构化媒体,使移动端和 +浏览器客户端可以直接扫描。 -删除设备也会清理该设备 ID 的任何陈旧待处理配对请求,因此撤销后 `nodes pending` 不会显示孤立行。 +删除设备也会清理该 +设备 ID 的所有过时待处理配对请求,因此 `nodes pending` 在撤销后不会显示孤立行。 ## 本地性与转发标头 -Gateway 网关配对只有在原始 socket 和任何上游代理证据一致时,才会将连接视为 loopback。如果请求抵达 loopback,但携带的 `X-Forwarded-For` / `X-Forwarded-Host` / `X-Forwarded-Proto` 标头指向非本地来源,则该转发标头证据会使 loopback 本地性声明失效。随后配对路径会要求显式批准,而不是静默地将请求视为同主机连接。有关操作员认证的等效规则,请参阅[受信任代理认证](/zh-CN/gateway/trusted-proxy-auth)。 +Gateway 网关配对只有在原始套接字 +和任何上游代理证据都一致时,才会将连接视为 loopback。如果请求到达 loopback,但 +携带指向非本地来源的 `X-Forwarded-For` / `X-Forwarded-Host` / `X-Forwarded-Proto` 标头, +该转发标头证据会使 +loopback 本地性声明失效。随后配对路径会要求显式批准, +而不是静默地将该请求视为同主机连接。等效的 +操作者身份验证规则见 +[可信代理身份验证](/zh-CN/gateway/trusted-proxy-auth)。 ## 存储(本地,私有) @@ -161,20 +193,20 @@ Gateway 网关配对只有在原始 socket 和任何上游代理证据一致时 - `~/.openclaw/nodes/paired.json` - `~/.openclaw/nodes/pending.json` -如果你覆盖 `OPENCLAW_STATE_DIR`,`nodes/` 文件夹也会随之移动。 +如果你覆盖 `OPENCLAW_STATE_DIR`,`nodes/` 文件夹会随之移动。 安全注意事项: -- 令牌是机密;请将 `paired.json` 视为敏感文件。 +- 令牌是机密;应将 `paired.json` 视为敏感文件。 - 轮换令牌需要重新批准(或删除节点条目)。 ## 传输协议行为 -- 传输协议是**无状态的**;它不存储成员资格。 +- 传输协议是**无状态**的;它不存储成员资格。 - 如果 Gateway 网关离线或配对被禁用,节点无法配对。 - 如果 Gateway 网关处于远程模式,配对仍会针对远程 Gateway 网关的存储执行。 -## 相关内容 +## 相关 - [渠道配对](/zh-CN/channels/pairing) - [节点](/zh-CN/nodes) diff --git a/docs/zh-CN/gateway/protocol.md b/docs/zh-CN/gateway/protocol.md index e27c0caff..ca06ee0a9 100644 --- a/docs/zh-CN/gateway/protocol.md +++ b/docs/zh-CN/gateway/protocol.md @@ -2,25 +2,25 @@ read_when: - 实现或更新 Gateway 网关 WS 客户端 - 调试协议不匹配或连接失败 - - 重新生成协议架构/模型 + - 正在重新生成协议架构/模型 summary: Gateway 网关 WebSocket 协议:握手、帧、版本控制 title: Gateway 网关协议 x-i18n: - generated_at: "2026-05-02T13:34:01Z" + generated_at: "2026-05-03T00:43:02Z" model: gpt-5.5 provider: openai - source_hash: bc8bd6bae485f13bbd0e8762d30abdfab7e2aee635f8ebac1a38798493239798 + source_hash: 06f6e1f2188860362bff481e646bd1c4bae4cf8f9a9ccae4fbd5ceea434d2247 source_path: gateway/protocol.md workflow: 16 --- -Gateway 网关 WS 协议是 OpenClaw 的**单一控制平面 + 节点传输协议**。所有客户端(CLI、Web UI、macOS 应用、iOS/Android 节点、无头节点)都通过 WebSocket 连接,并在握手时声明其**角色** + **作用域**。 +Gateway 网关 WS 协议是 OpenClaw 的**单一控制平面 + 节点传输协议**。所有客户端(CLI、Web UI、macOS 应用、iOS/Android 节点、无头节点)都通过 WebSocket 连接,并在握手时声明其 **role** + **scope**。 -## 传输 +## 传输协议 -- WebSocket,使用带 JSON 载荷的文本帧。 +- WebSocket,文本帧使用 JSON 载荷。 - 第一帧**必须**是 `connect` 请求。 -- 连接前帧上限为 64 KiB。握手成功后,客户端应遵循 `hello-ok.policy.maxPayload` 和 `hello-ok.policy.maxBufferedBytes` 限制。启用诊断后,过大的入站帧和缓慢的出站缓冲区会在 Gateway 网关关闭或丢弃受影响帧之前发出 `payload.large` 事件。这些事件会保留大小、限制、表面和安全原因代码。它们不会保留消息正文、附件内容、原始帧正文、令牌、Cookie 或机密值。 +- 连接前帧大小上限为 64 KiB。握手成功后,客户端应遵循 `hello-ok.policy.maxPayload` 和 `hello-ok.policy.maxBufferedBytes` 限制。启用诊断时,过大的入站帧和缓慢的出站缓冲区会在 Gateway 网关关闭或丢弃受影响帧之前发出 `payload.large` 事件。这些事件会保留大小、限制、表面和安全原因代码。它们不会保留消息正文、附件内容、原始帧正文、令牌、Cookie 或密钥值。 ## 握手(connect) @@ -95,7 +95,7 @@ Gateway 网关 → 客户端: } ``` -当 Gateway 网关仍在完成启动 sidecar 时,`connect` 请求可能返回可重试的 `UNAVAILABLE` 错误,并将 `details.reason` 设为 `"startup-sidecars"`,同时带有 `retryAfterMs`。客户端应在其整体连接预算内重试该响应,而不是将其呈现为终止性握手失败。 +当 Gateway 网关仍在完成启动 sidecar 时,`connect` 请求可能返回可重试的 `UNAVAILABLE` 错误,其中 `details.reason` 设置为 `"startup-sidecars"`,并带有 `retryAfterMs`。客户端应在其总体连接预算内重试该响应,而不是将其暴露为终止性握手失败。 `server`、`features`、`snapshot` 和 `policy` 都是 schema(`src/gateway/protocol/schema/frames.ts`)要求的字段。`auth` 也是必需的,并报告协商后的角色/作用域。`canvasHostUrl` 是可选的。 @@ -110,7 +110,7 @@ Gateway 网关 → 客户端: } ``` -受信任的同进程后端客户端(`client.id: "gateway-client"`、`client.mode: "backend"`)在使用共享 Gateway 网关令牌/密码认证时,可以在直接 local loopback 连接上省略 `device`。此路径保留给内部控制平面 RPC,并避免过期的 CLI/设备配对基线阻塞本地后端工作,例如子智能体会话更新。远程客户端、浏览器来源客户端、节点客户端,以及显式设备令牌/设备身份客户端,仍使用正常的配对和作用域升级检查。 +受信任的同进程后端客户端(`client.id: "gateway-client"`、`client.mode: "backend"`)在使用共享 Gateway 网关令牌/密码进行认证时,可在直接 local loopback 连接上省略 `device`。此路径保留给内部控制平面 RPC,并防止过期的 CLI/设备配对基线阻塞本地后端工作,例如子智能体会话更新。远程客户端、浏览器源客户端、节点客户端,以及显式设备令牌/设备身份客户端仍使用正常的配对和作用域升级检查。 签发设备令牌时,`hello-ok` 还会包含: @@ -143,7 +143,7 @@ Gateway 网关 → 客户端: } ``` -对于内置的节点/operator 引导流程,主节点令牌保持 `scopes: []`,任何交接的 operator 令牌都会限制在引导 operator 允许列表(`operator.approvals`、`operator.read`、`operator.talk.secrets`、`operator.write`)内。引导作用域检查保持角色前缀化:operator 条目只满足 operator 请求,非 operator 角色仍需要其自身角色前缀下的作用域。 +对于内置的节点/操作员引导流程,主节点令牌保持为 `scopes: []`,任何交接的操作员令牌都保持限制在引导操作员允许列表(`operator.approvals`、`operator.read`、`operator.talk.secrets`、`operator.write`)内。引导作用域检查保持以角色为前缀:操作员条目只能满足操作员请求,非操作员角色仍需要其自身角色前缀下的作用域。 ### 节点示例 @@ -180,24 +180,26 @@ Gateway 网关 → 客户端: } ``` -## 帧格式 +## 成帧 - **请求**:`{type:"req", id, method, params}` - **响应**:`{type:"res", id, ok, payload|error}` - **事件**:`{type:"event", event, payload, seq?, stateVersion?}` -有副作用的方法需要**幂等键**(见 schema)。 +有副作用的方法需要**幂等键**(参见 schema)。 ## 角色 + 作用域 +关于完整的操作员作用域模型、审批时检查和共享密钥语义,请参阅 [操作员作用域](/zh-CN/gateway/operator-scopes)。 + ### 角色 - `operator` = 控制平面客户端(CLI/UI/自动化)。 - `node` = 能力宿主(camera/screen/canvas/system.run)。 -### 作用域(operator) +### 作用域(操作员) -常见作用域: +常用作用域: - `operator.read` - `operator.write` @@ -208,11 +210,11 @@ Gateway 网关 → 客户端: 带有 `includeSecrets: true` 的 `talk.config` 需要 `operator.talk.secrets`(或 `operator.admin`)。 -插件注册的 Gateway 网关 RPC 方法可以请求它们自己的 operator 作用域,但保留的核心 admin 前缀(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终解析为 `operator.admin`。 +插件注册的 Gateway 网关 RPC 方法可以请求其自己的操作员作用域,但保留的核心管理员前缀(`config.*`、`exec.approvals.*`、`wizard.*`、`update.*`)始终解析为 `operator.admin`。 -方法作用域只是第一道门。一些通过 `chat.send` 到达的斜杠命令会在其上应用更严格的命令级检查。例如,持久化的 `/config set` 和 `/config unset` 写入需要 `operator.admin`。 +方法作用域只是第一道门槛。某些通过 `chat.send` 到达的斜杠命令会在其上应用更严格的命令级检查。例如,持久化的 `/config set` 和 `/config unset` 写入需要 `operator.admin`。 -`node.pair.approve` 在基础方法作用域之上,还有额外的批准时作用域检查: +`node.pair.approve` 在基础方法作用域之上还有额外的审批时作用域检查: - 无命令请求:`operator.pairing` - 带非 exec 节点命令的请求:`operator.pairing` + `operator.write` @@ -220,23 +222,23 @@ Gateway 网关 → 客户端: ### 能力/命令/权限(节点) -节点在连接时声明能力声明: +节点在连接时声明能力主张: - `caps`:高级能力类别。 - `commands`:用于调用的命令允许列表。 - `permissions`:细粒度开关(例如 `screen.record`、`camera.capture`)。 -Gateway 网关会将这些视为**声明**,并强制执行服务器端允许列表。 +Gateway 网关将这些视为**主张**,并强制执行服务端允许列表。 ## 在线状态 -- `system-presence` 返回以设备身份为键的条目。 -- 在线状态条目包含 `deviceId`、`roles` 和 `scopes`,因此 UI 可以为每个设备显示单行,即使它同时以 **operator** 和**节点**身份连接。 -- `node.list` 包含可选的 `lastSeenAtMs` 和 `lastSeenReason` 字段。已连接节点会报告其当前连接时间作为 `lastSeenAtMs`,原因是 `connect`;当受信任节点事件更新其配对元数据时,已配对节点也可以报告持久的后台在线状态。 +- `system-presence` 返回按设备身份键控的条目。 +- 在线状态条目包括 `deviceId`、`roles` 和 `scopes`,因此即使同一设备同时以**操作员**和**节点**身份连接,UI 也可以为每个设备显示一行。 +- `node.list` 包含可选的 `lastSeenAtMs` 和 `lastSeenReason` 字段。已连接节点会将其当前连接时间报告为 `lastSeenAtMs`,原因为 `connect`;当受信任节点事件更新其配对元数据时,已配对节点也可以报告持久的后台在线状态。 ### 节点后台存活事件 -节点可以调用 `node.event`,并传入 `event: "node.presence.alive"`,以记录已配对节点在后台唤醒期间处于存活状态,而不将其标记为已连接。 +节点可以调用 `node.event` 并使用 `event: "node.presence.alive"`,记录某个已配对节点在后台唤醒期间处于存活状态,但不将其标记为已连接。 ```json { @@ -245,7 +247,7 @@ Gateway 网关会将这些视为**声明**,并强制执行服务器端允许 } ``` -`trigger` 是封闭枚举:`background`、`silent_push`、`bg_app_refresh`、`significant_location`、`manual` 或 `connect`。未知触发字符串会在持久化前由 Gateway 网关规范化为 `background`。该事件仅对已认证的节点设备会话持久;无设备或未配对会话返回 `handled: false`。 +`trigger` 是闭合枚举:`background`、`silent_push`、`bg_app_refresh`、`significant_location`、`manual` 或 `connect`。未知的触发器字符串在持久化前会由 Gateway 网关规范化为 `background`。该事件仅对已认证的节点设备会话持久化;无设备或未配对会话返回 `handled: false`。 成功的 Gateway 网关返回结构化结果: @@ -258,42 +260,42 @@ Gateway 网关会将这些视为**声明**,并强制执行服务器端允许 } ``` -较旧的 Gateway 网关仍可能对 `node.event` 返回 `{ "ok": true }`;客户端应将其视为已确认的 RPC,而不是持久在线状态的持久化。 +旧版 Gateway 网关对 `node.event` 仍可能返回 `{ "ok": true }`;客户端应将其视为已确认的 RPC,而不是持久在线状态已保存。 ## 广播事件作用域限定 -服务器推送的 WebSocket 广播事件受作用域门控,因此配对作用域或仅节点会话不会被动接收会话内容。 +服务端推送的 WebSocket 广播事件受作用域门控,因此配对作用域或仅节点会话不会被动接收会话内容。 - **聊天、智能体和工具结果帧**(包括流式 `agent` 事件和工具调用结果)至少需要 `operator.read`。没有 `operator.read` 的会话会完全跳过这些帧。 -- **插件定义的 `plugin.*` 广播**会根据插件注册方式,被门控为 `operator.write` 或 `operator.admin`。 -- **Status 和传输事件**(`heartbeat`、`presence`、`tick`、连接/断开连接生命周期等)保持不受限制,以便每个已认证会话都能观察传输健康状态。 -- **未知广播事件族**默认受作用域门控(失败关闭),除非注册的处理程序显式放宽它们。 +- **插件定义的 `plugin.*` 广播**会根据插件注册方式被门控到 `operator.write` 或 `operator.admin`。 +- **Status 和传输事件**(`heartbeat`、`presence`、`tick`、连接/断开生命周期等)保持不受限制,因此每个已认证会话都可以观察传输健康状态。 +- **未知广播事件族**默认受作用域门控(失败关闭),除非已注册处理程序显式放宽限制。 -每个客户端连接都会保留自己的按客户端序列号,因此即使不同客户端看到事件流中不同的作用域过滤子集,广播也会在该套接字上保持单调顺序。 +每个客户端连接都会保留自己的每客户端序列号,因此即使不同客户端看到事件流中不同的作用域过滤子集,广播也能在该 socket 上保持单调顺序。 ## 常见 RPC 方法族 -公共 WS 表面比上面的握手/认证示例更广。这不是生成的转储,`hello-ok.features.methods` 是一个保守的设备发现列表,由 `src/gateway/server-methods-list.ts` 加上已加载的插件/渠道方法导出构建。请将其视为功能设备发现,而不是 `src/gateway/server-methods/*.ts` 的完整枚举。 +公共 WS 表面比上面的握手/认证示例更广。这不是生成的转储,`hello-ok.features.methods` 是一个保守的发现列表,由 `src/gateway/server-methods-list.ts` 加上已加载的插件/渠道方法导出构建。请将其视为功能发现,而不是 `src/gateway/server-methods/*.ts` 的完整枚举。 - `health` 返回缓存的或新探测的 Gateway 网关健康快照。 - - `diagnostics.stability` 返回最近的有界诊断稳定性记录器。它保留事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID 等操作元数据。它不会保留聊天文本、Webhook 正文、工具输出、原始请求或响应正文、令牌、Cookie 或机密值。需要 operator 读取作用域。 - - `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅对 admin 作用域的 operator 客户端包含。 + - `diagnostics.stability` 返回最近的有界诊断稳定性记录器。它保留操作元数据,例如事件名称、计数、字节大小、内存读数、队列/会话状态、渠道/插件名称和会话 ID。它不会保留聊天文本、webhook 正文、工具输出、原始请求或响应正文、令牌、Cookie 或密钥值。需要操作员读取作用域。 + - `status` 返回 `/status` 风格的 Gateway 网关摘要;敏感字段仅包含给具有管理员作用域的操作员客户端。 - `gateway.identity.get` 返回中继和配对流程使用的 Gateway 网关设备身份。 - - `system-presence` 返回已连接 operator/节点设备的当前在线状态快照。 - - `system-event` 追加系统事件,并可以更新/广播在线状态上下文。 + - `system-presence` 返回已连接操作员/节点设备的当前在线状态快照。 + - `system-event` 追加系统事件,并可更新/广播在线状态上下文。 - `last-heartbeat` 返回最新持久化的 Heartbeat 事件。 - - `set-heartbeats` 切换 Gateway 网关上的 Heartbeat 处理。 + - `set-heartbeats` 在 Gateway 网关上切换 Heartbeat 处理。 - - - `models.list` 返回运行时允许的模型目录。传入 `{ "view": "configured" }` 可获取适合选择器展示的已配置模型(先是 `agents.defaults.models`,然后是 `models.providers.*.models`),或传入 `{ "view": "all" }` 获取完整目录。 + + - `models.list` 返回运行时允许的模型目录。传入 `{ "view": "configured" }` 可获取适合选择器展示的已配置模型(先是 `agents.defaults.models`,再是 `models.providers.*.models`),或传入 `{ "view": "all" }` 获取完整目录。 - `usage.status` 返回提供商用量窗口/剩余额度摘要。 - - `usage.cost` 返回某个日期范围内聚合的费用用量摘要。 - - `doctor.memory.status` 返回当前默认智能体工作区的向量记忆 / 缓存嵌入就绪状态。仅当调用方明确想要实时 ping 嵌入提供商时,才传入 `{ "probe": true }` 或 `{ "deep": true }`。 - - `doctor.memory.remHarness` 为远程控制平面客户端返回有界、只读的 REM harness 预览。它可以包含工作区路径、记忆片段、渲染后的有依据 markdown,以及深度提升候选项,因此调用方需要 `operator.read`。 + - `usage.cost` 返回某个日期范围的聚合成本用量摘要。 + - `doctor.memory.status` 返回活动默认 Agent 工作区的向量记忆/缓存嵌入就绪状态。仅当调用方明确想要实时探测嵌入提供商时,才传入 `{ "probe": true }` 或 `{ "deep": true }`。 + - `doctor.memory.remHarness` 为远程控制平面客户端返回有界、只读的 REM harness 预览。它可能包含工作区路径、记忆片段、渲染后的有依据 Markdown,以及深度提升候选项,因此调用方需要 `operator.read`。 - `sessions.usage` 返回每个会话的用量摘要。 - `sessions.usage.timeseries` 返回一个会话的时间序列用量。 - `sessions.usage.logs` 返回一个会话的用量日志条目。 @@ -302,44 +304,44 @@ Gateway 网关会将这些视为**声明**,并强制执行服务器端允许 - `channels.status` 返回内置 + 捆绑渠道/插件的 Status 摘要。 - - `channels.logout` 在渠道支持退出登录时,退出某个特定渠道/账号。 + - `channels.logout` 在渠道支持退出登录时,退出特定渠道/账号。 - `web.login.start` 为当前支持二维码的 Web 渠道提供商启动二维码/Web 登录流程。 - - `web.login.wait` 等待该二维码/Web 登录流程完成,并在成功后启动该渠道。 + - `web.login.wait` 等待该二维码/Web 登录流程完成,并在成功后启动渠道。 - `push.test` 向已注册的 iOS 节点发送测试 APNs 推送。 - `voicewake.get` 返回已存储的唤醒词触发器。 - - `voicewake.set` 更新唤醒词触发器并广播更改。 + - `voicewake.set` 更新唤醒词触发器并广播变更。 - - `send` 是在聊天运行器之外面向渠道/账号/线程目标发送消息的直接出站投递 RPC。 - - `logs.tail` 使用游标/限制和最大字节控制,返回已配置的 Gateway 网关文件日志尾部内容。 + - `send` 是在聊天运行器之外,面向渠道/账号/线程目标发送的直接出站投递 RPC。 + - `logs.tail` 返回已配置 Gateway 网关文件日志尾部,支持游标/限制和最大字节控制。 - `talk.config` 返回生效的 Talk 配置载荷;`includeSecrets` 需要 `operator.talk.secrets`(或 `operator.admin`)。 - `talk.mode` 为 WebChat/Control UI 客户端设置/广播当前 Talk 模式状态。 - - `talk.speak` 通过当前活动的 Talk 语音提供商合成语音。 - - `tts.status` 返回 TTS 启用状态、当前活动提供商、后备提供商以及提供商配置状态。 + - `talk.speak` 通过活动的 Talk 语音提供商合成语音。 + - `tts.status` 返回 TTS 启用状态、活动提供商、回退提供商,以及提供商配置状态。 - `tts.providers` 返回可见的 TTS 提供商清单。 - `tts.enable` 和 `tts.disable` 切换 TTS 偏好状态。 - `tts.setProvider` 更新首选 TTS 提供商。 - - `tts.convert` 执行一次性文本转语音转换。 + - `tts.convert` 运行一次性文本转语音转换。 - - `secrets.reload` 重新解析活动 SecretRefs,并且仅在完全成功时替换运行时密钥状态。 - - `secrets.resolve` 为特定命令/目标集合解析命令目标密钥分配。 + - `secrets.reload` 重新解析活动的 SecretRefs,并且仅在完全成功时替换运行时密钥状态。 + - `secrets.resolve` 解析特定命令/目标集合的命令目标密钥分配。 - `config.get` 返回当前配置快照和哈希。 - - `config.set` 写入经过验证的配置载荷。 + - `config.set` 写入已验证的配置载荷。 - `config.patch` 合并部分配置更新。 - `config.apply` 验证并替换完整配置载荷。 - - `config.schema` 返回 Control UI 和 CLI 工具使用的实时配置 schema 载荷:schema、`uiHints`、版本和生成元数据;当运行时可以加载时,还包括插件 + 渠道 schema 元数据。该 schema 包含字段 `title` / `description` 元数据,这些元数据来自 UI 使用的相同标签和帮助文本;当存在匹配的字段文档时,还包括嵌套对象、通配符、数组项,以及 `anyOf` / `oneOf` / `allOf` 组合分支。 - - `config.schema.lookup` 为一个配置路径返回按路径限定的查找载荷:规范化路径、浅层 schema 节点、匹配的提示 + `hintPath`,以及用于 UI/CLI 下钻的直接子项摘要。查找 schema 节点会保留面向用户的文档和常见验证字段(`title`、`description`、`type`、`enum`、`const`、`format`、`pattern`、数字/字符串/数组/对象边界,以及 `additionalProperties`、`deprecated`、`readOnly`、`writeOnly` 等标志)。子项摘要会暴露 `key`、规范化后的 `path`、`type`、`required`、`hasChildren`,以及匹配的 `hint` / `hintPath`。 - - `update.run` 运行 Gateway 网关更新流程,并且仅在更新本身成功时安排重启。包管理器更新会在包替换后强制执行非延迟、无冷却的更新重启,以便旧 Gateway 网关进程不会继续从已替换的 `dist` 树中延迟加载。 - - `update.status` 返回最新缓存的更新重启哨兵;如果可用,还包括重启后的运行版本。 + - `config.schema` 返回 Control UI 和 CLI 工具使用的实时配置 schema 载荷:schema、`uiHints`、版本和生成元数据;当运行时可以加载时,还包括插件 + 渠道 schema 元数据。该 schema 包含从 UI 使用的相同标签和帮助文本派生的字段 `title` / `description` 元数据;当存在匹配的字段文档时,也包括嵌套对象、通配符、数组项,以及 `anyOf` / `oneOf` / `allOf` 组合分支。 + - `config.schema.lookup` 为一个配置路径返回路径作用域的查找载荷:规范化路径、浅层 schema 节点、匹配的提示 + `hintPath`,以及用于 UI/CLI 下钻的直接子项摘要。查找 schema 节点保留面向用户的文档和常见验证字段(`title`、`description`、`type`、`enum`、`const`、`format`、`pattern`、数值/字符串/数组/对象边界,以及 `additionalProperties`、`deprecated`、`readOnly`、`writeOnly` 等标记)。子项摘要暴露 `key`、规范化 `path`、`type`、`required`、`hasChildren`,以及匹配的 `hint` / `hintPath`。 + - `update.run` 运行 Gateway 网关更新流程,并且仅在更新本身成功时安排重启。包管理器更新会在包替换后强制执行非延迟、无冷却的更新重启,以免旧 Gateway 网关进程继续从已被替换的 `dist` 树中延迟加载。 + - `update.status` 返回最新缓存的更新重启哨兵;可用时包括重启后的运行版本。 - `wizard.start`、`wizard.next`、`wizard.status` 和 `wizard.cancel` 通过 WS RPC 暴露新手引导向导。 @@ -348,54 +350,54 @@ Gateway 网关会将这些视为**声明**,并强制执行服务器端允许 - `agents.list` 返回已配置的智能体条目,包括生效模型和运行时元数据。 - `agents.create`、`agents.update` 和 `agents.delete` 管理智能体记录和工作区接线。 - `agents.files.list`、`agents.files.get` 和 `agents.files.set` 管理为智能体暴露的引导工作区文件。 - - `artifacts.list`、`artifacts.get` 和 `artifacts.download` 为显式的 `sessionKey`、`runId` 或 `taskId` 范围暴露由转录生成的产物摘要和下载。运行和任务查询会在服务端解析所属会话,并且只返回来源匹配的转录媒体;不安全或本地 URL 来源会返回不支持的下载,而不是在服务端获取。 - - `agent.identity.get` 返回某个智能体或会话的生效助手身份。 + - `artifacts.list`、`artifacts.get` 和 `artifacts.download` 为显式 `sessionKey`、`runId` 或 `taskId` 作用域暴露从转录派生的产物摘要和下载。运行和任务查询会在服务端解析所属会话,并且只返回来源匹配的转录媒体;不安全或本地 URL 来源会返回不支持的下载,而不是在服务端获取。 + - `agent.identity.get` 返回智能体或会话的生效助手身份。 - `agent.wait` 等待一次运行完成,并在可用时返回终止快照。 - - `sessions.list` 返回当前会话索引;当配置了智能体运行时后端时,包括每行的 `agentRuntime` 元数据。 + - `sessions.list` 返回当前会话索引;当配置了 Agent Runtimes 后端时,包括每行 `agentRuntime` 元数据。 - `sessions.subscribe` 和 `sessions.unsubscribe` 为当前 WS 客户端切换会话变更事件订阅。 - `sessions.messages.subscribe` 和 `sessions.messages.unsubscribe` 为一个会话切换转录/消息事件订阅。 - `sessions.preview` 返回特定会话键的有界转录预览。 - - `sessions.describe` 为精确会话键返回一行 Gateway 网关会话。 + - `sessions.describe` 返回精确会话键对应的一行 Gateway 网关会话。 - `sessions.resolve` 解析或规范化会话目标。 - `sessions.create` 创建新的会话条目。 - `sessions.send` 向现有会话发送消息。 - - `sessions.steer` 是用于活动会话的中断并引导变体。 - - `sessions.abort` 中止某个会话的活动工作。调用方可以传入 `key` 加可选的 `runId`,也可以只为 Gateway 网关可解析到会话的活动运行传入 `runId`。 + - `sessions.steer` 是活动会话的中断并引导变体。 + - `sessions.abort` 中止会话的活动工作。调用方可以传入 `key` 以及可选 `runId`,也可以只传入 `runId`,用于 Gateway 网关可解析到会话的活动运行。 - `sessions.patch` 更新会话元数据/覆盖项,并报告解析后的规范模型以及生效的 `agentRuntime`。 - `sessions.reset`、`sessions.delete` 和 `sessions.compact` 执行会话维护。 - `sessions.get` 返回完整存储的会话行。 - - 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。`chat.history` 会针对 UI 客户端进行显示规范化:可见文本中的内联指令标签会被剥离,纯文本工具调用 XML 载荷(包括 `...`、`...`、`...`、`...`,以及被截断的工具调用块)和泄漏的 ASCII/全角模型控制 token 会被剥离,精确的 `NO_REPLY` / `no_reply` 等纯静默 token 助手行会被省略,过大的行可以被替换为占位符。 + - 聊天执行仍使用 `chat.history`、`chat.send`、`chat.abort` 和 `chat.inject`。`chat.history` 会为 UI 客户端进行显示规范化:从可见文本中移除内联指令标签;移除纯文本工具调用 XML 载荷(包括 `...`、`...`、`...`、`...`,以及截断的工具调用块)和泄漏的 ASCII/全角模型控制令牌;省略精确 `NO_REPLY` / `no_reply` 等纯静默令牌助手行;超大行可以替换为占位符。 - + - `device.pair.list` 返回待处理和已批准的配对设备。 - `device.pair.approve`、`device.pair.reject` 和 `device.pair.remove` 管理设备配对记录。 - - `device.token.rotate` 在已批准角色和调用方范围边界内轮换配对设备 token。 - - `device.token.revoke` 在已批准角色和调用方范围边界内撤销配对设备 token。 + - `device.token.rotate` 在已批准角色和调用方作用域边界内轮换配对设备令牌。 + - `device.token.revoke` 在已批准角色和调用方作用域边界内撤销配对设备令牌。 - `node.pair.request`、`node.pair.list`、`node.pair.approve`、`node.pair.reject`、`node.pair.remove` 和 `node.pair.verify` 覆盖节点配对和引导验证。 - `node.list` 和 `node.describe` 返回已知/已连接节点状态。 - - `node.rename` 更新配对节点标签。 + - `node.rename` 更新已配对节点标签。 - `node.invoke` 将命令转发到已连接节点。 - `node.invoke.result` 返回调用请求的结果。 - `node.event` 将源自节点的事件带回 Gateway 网关。 - - `node.canvas.capability.refresh` 刷新按范围限定的 canvas 能力 token。 + - `node.canvas.capability.refresh` 刷新作用域内的画布能力令牌。 - `node.pending.pull` 和 `node.pending.ack` 是已连接节点队列 API。 - `node.pending.enqueue` 和 `node.pending.drain` 管理离线/断开连接节点的持久待处理工作。 - + - `exec.approval.request`、`exec.approval.get`、`exec.approval.list` 和 `exec.approval.resolve` 覆盖一次性 exec 审批请求以及待处理审批查找/重放。 - - `exec.approval.waitDecision` 等待一个待处理 exec 审批并返回最终决定(超时时返回 `null`)。 + - `exec.approval.waitDecision` 等待一个待处理 exec 审批,并返回最终决策(超时时返回 `null`)。 - `exec.approvals.get` 和 `exec.approvals.set` 管理 Gateway 网关 exec 审批策略快照。 - `exec.approvals.node.get` 和 `exec.approvals.node.set` 通过节点中继命令管理节点本地 exec 审批策略。 - `plugin.approval.request`、`plugin.approval.list`、`plugin.approval.waitDecision` 和 `plugin.approval.resolve` 覆盖插件定义的审批流程。 @@ -409,93 +411,89 @@ Gateway 网关会将这些视为**声明**,并强制执行服务器端允许 -### 常见事件族 +### 常见事件系列 -- `chat`:UI 聊天更新,例如 `chat.inject` 和其他仅转录的聊天 - 事件。 +- `chat`:UI 聊天更新,例如 `chat.inject` 和其他仅转录聊天事件。 - `session.message` 和 `session.tool`:已订阅会话的转录/事件流更新。 - `sessions.changed`:会话索引或元数据已更改。 - `presence`:系统在线状态快照更新。 -- `tick`:周期性 keepalive / 存活事件。 +- `tick`:周期性 keepalive / 活性事件。 - `health`:Gateway 网关健康快照更新。 -- `heartbeat`:heartbeat 事件流更新。 +- `heartbeat`:Heartbeat 事件流更新。 - `cron`:cron 运行/作业变更事件。 - `shutdown`:Gateway 网关关闭通知。 - `node.pair.requested` / `node.pair.resolved`:节点配对生命周期。 - `node.invoke.request`:节点调用请求广播。 - `device.pair.requested` / `device.pair.resolved`:配对设备生命周期。 - `voicewake.changed`:唤醒词触发器配置已更改。 -- `exec.approval.requested` / `exec.approval.resolved`:exec 审批 - 生命周期。 -- `plugin.approval.requested` / `plugin.approval.resolved`:插件审批 - 生命周期。 +- `exec.approval.requested` / `exec.approval.resolved`:exec 审批生命周期。 +- `plugin.approval.requested` / `plugin.approval.resolved`:插件审批生命周期。 ### 节点辅助方法 -- 节点可以调用 `skills.bins` 来获取当前技能可执行文件列表, - 用于自动允许检查。 +- 节点可以调用 `skills.bins` 来获取当前技能可执行文件列表,用于自动允许检查。 -### 操作员辅助方法 +### 操作者辅助方法 -- 操作者可以调用 `commands.list`(`operator.read`)来获取智能体的运行时命令清单。 - - `agentId` 是可选的;省略它可读取默认 Agent 工作区。 - - `scope` 控制主要 `name` 面向的界面: +- 操作员可以调用 `commands.list`(`operator.read`)来获取智能体的运行时命令清单。 + - `agentId` 是可选的;省略它可读取默认智能体工作区。 + - `scope` 控制主 `name` 目标所在的表面: - `text` 返回不带前导 `/` 的主文本命令令牌 - - `native` 和默认的 `both` 路径会在可用时返回感知提供商的原生命令名称 + - `native` 和默认的 `both` 路径在可用时返回感知提供商的原生命令名称 - `textAliases` 携带精确的斜杠别名,例如 `/model` 和 `/m`。 - `nativeName` 在存在时携带感知提供商的原生命令名称。 - - `provider` 是可选的,只影响原生命名以及原生插件命令的可用性。 + - `provider` 是可选的,并且只影响原生命名以及原生插件命令可用性。 - `includeArgs=false` 会从响应中省略序列化的参数元数据。 -- 操作者可以调用 `tools.catalog`(`operator.read`)来获取智能体的运行时工具目录。响应包含分组工具和来源元数据: +- 操作员可以调用 `tools.catalog`(`operator.read`)来获取智能体的运行时工具目录。响应包含分组工具和来源元数据: - `source`:`core` 或 `plugin` - - `pluginId`:当 `source="plugin"` 时为插件所有者 + - `pluginId`:当 `source="plugin"` 时的插件所有者 - `optional`:插件工具是否为可选 -- 操作者可以调用 `tools.effective`(`operator.read`)来获取会话的运行时生效工具清单。 +- 操作员可以调用 `tools.effective`(`operator.read`)来获取某个会话的运行时生效工具清单。 - `sessionKey` 是必需的。 - - Gateway 网关会从服务端的会话中派生可信运行时上下文,而不是接受调用方提供的认证或投递上下文。 - - 响应限定在会话范围内,并反映当前活动对话现在可以使用的内容,包括核心、插件和渠道工具。 -- 操作者可以调用 `tools.invoke`(`operator.write`),通过与 `/tools/invoke` 相同的 Gateway 网关策略路径调用一个可用工具。 + - Gateway 网关会从服务器端会话推导受信任的运行时上下文,而不是接受调用方提供的身份验证或递送上下文。 + - 响应以会话为范围,并反映当前活动对话现在可以使用的内容,包括核心、插件和渠道工具。 +- 操作员可以调用 `tools.invoke`(`operator.write`),通过与 `/tools/invoke` 相同的 Gateway 网关策略路径调用一个可用工具。 - `name` 是必需的。`args`、`sessionKey`、`agentId`、`confirm` 和 `idempotencyKey` 是可选的。 - - 如果同时存在 `sessionKey` 和 `agentId`,解析出的会话智能体必须与 `agentId` 匹配。 - - 响应是面向 SDK 的信封,包含 `ok`、`toolName`、可选的 `output`,以及带类型的 `error` 字段。审批或策略拒绝会在载荷中返回 `ok:false`,而不是绕过 Gateway 网关工具策略流水线。 -- 操作者可以调用 `skills.status`(`operator.read`)来获取智能体的可见 skill 清单。 - - `agentId` 是可选的;省略它可读取默认 Agent 工作区。 - - 响应包含资格状态、缺失要求、配置检查,以及经过净化的安装选项,且不会暴露原始密钥值。 -- 操作者可以调用 `skills.search` 和 `skills.detail`(`operator.read`)获取 ClawHub 设备发现元数据。 -- 操作者可以用两种模式调用 `skills.install`(`operator.admin`): - - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 会将一个 skill 文件夹安装到默认 Agent 工作区的 `skills/` 目录。 - - Gateway 网关安装器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` 会在 Gateway 网关主机上运行已声明的 `metadata.openclaw.install` 操作。 -- 操作者可以用两种模式调用 `skills.update`(`operator.admin`): - - ClawHub 模式会更新一个已跟踪的 slug,或更新默认 Agent 工作区中所有已跟踪的 ClawHub 安装项。 + - 如果同时存在 `sessionKey` 和 `agentId`,解析出的会话智能体必须匹配 `agentId`。 + - 响应是面向 SDK 的封套,包含 `ok`、`toolName`、可选的 `output`,以及带类型的 `error` 字段。审批或策略拒绝会在载荷中返回 `ok:false`,而不是绕过 Gateway 网关工具策略管线。 +- 操作员可以调用 `skills.status`(`operator.read`)来获取智能体的可见 Skills 清单。 + - `agentId` 是可选的;省略它可读取默认智能体工作区。 + - 响应包含资格、缺失的要求、配置检查,以及经过净化的安装选项,且不会暴露原始密钥值。 +- 操作员可以调用 `skills.search` 和 `skills.detail`(`operator.read`)获取 ClawHub 发现元数据。 +- 操作员可以通过两种模式调用 `skills.install`(`operator.admin`): + - ClawHub 模式:`{ source: "clawhub", slug, version?, force? }` 会将一个 Skill 文件夹安装到默认智能体工作区的 `skills/` 目录。 + - Gateway 网关安装器模式:`{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` 会在 Gateway 网关主机上运行声明的 `metadata.openclaw.install` 动作。 +- 操作员可以通过两种模式调用 `skills.update`(`operator.admin`): + - ClawHub 模式会更新一个已跟踪的 slug,或默认智能体工作区中所有已跟踪的 ClawHub 安装。 - 配置模式会修补 `skills.entries.` 的值,例如 `enabled`、`apiKey` 和 `env`。 ### `models.list` 视图 `models.list` 接受可选的 `view` 参数: -- 省略或 `"default"`:当前运行时行为。如果已配置 `agents.defaults.models`,响应为允许的目录;否则响应为完整 Gateway 网关目录。 -- `"configured"`:适合选择器规模的行为。如果已配置 `agents.defaults.models`,它仍然优先。否则响应会使用显式的 `models.providers.*.models` 条目,只有在不存在已配置的模型行时才回退到完整目录。 -- `"all"`:完整 Gateway 网关目录,绕过 `agents.defaults.models`。用于诊断和发现 UI,而不是普通模型选择器。 +- 省略或 `"default"`:当前运行时行为。如果已配置 `agents.defaults.models`,响应就是允许的目录;否则响应就是完整的 Gateway 网关目录。 +- `"configured"`:适合选择器大小的行为。如果已配置 `agents.defaults.models`,它仍然优先生效。否则响应使用显式的 `models.providers.*.models` 条目,仅在不存在已配置模型行时回退到完整目录。 +- `"all"`:完整的 Gateway 网关目录,绕过 `agents.defaults.models`。将此用于诊断和发现 UI,而不是普通模型选择器。 -## Exec 审批 +## 执行审批 -- 当 exec 请求需要审批时,Gateway 网关会广播 `exec.approval.requested`。 -- 操作者客户端通过调用 `exec.approval.resolve` 进行处理(需要 `operator.approvals` scope)。 +- 当执行请求需要审批时,Gateway 网关会广播 `exec.approval.requested`。 +- 操作员客户端通过调用 `exec.approval.resolve` 来解决(需要 `operator.approvals` 范围)。 - 对于 `host=node`,`exec.approval.request` 必须包含 `systemRunPlan`(规范的 `argv`/`cwd`/`rawCommand`/会话元数据)。缺少 `systemRunPlan` 的请求会被拒绝。 -- 审批后,转发的 `node.invoke system.run` 调用会复用该规范的 `systemRunPlan`,将其作为权威的命令/cwd/会话上下文。 -- 如果调用方在 prepare 和最终获批的 `system.run` 转发之间修改 `command`、`rawCommand`、`cwd`、`agentId` 或 `sessionKey`,Gateway 网关会拒绝本次运行,而不是信任被修改的载荷。 +- 审批之后,转发的 `node.invoke system.run` 调用会复用该规范的 `systemRunPlan`,作为权威的命令/cwd/会话上下文。 +- 如果调用方在准备阶段和最终已审批的 `system.run` 转发之间更改了 `command`、`rawCommand`、`cwd`、`agentId` 或 `sessionKey`,Gateway 网关会拒绝运行,而不是信任被更改的载荷。 -## 智能体投递回退 +## 智能体递送回退 -- `agent` 请求可以包含 `deliver=true` 来请求出站投递。 -- `bestEffortDeliver=false` 保持严格行为:无法解析或仅限内部的投递目标会返回 `INVALID_REQUEST`。 -- `bestEffortDeliver=true` 允许在无法解析外部可投递路由时回退到仅会话执行(例如内部/webchat 会话或多渠道配置不明确)。 +- `agent` 请求可以包含 `deliver=true` 来请求出站递送。 +- `bestEffortDeliver=false` 保持严格行为:无法解析或仅限内部的递送目标会返回 `INVALID_REQUEST`。 +- `bestEffortDeliver=true` 允许在无法解析外部可递送路由时回退到仅会话执行(例如内部/webchat 会话或模糊的多渠道配置)。 ## 版本控制 - `PROTOCOL_VERSION` 位于 `src/gateway/protocol/schema/protocol-schemas.ts`。 -- 客户端发送 `minProtocol` + `maxProtocol`;服务器会拒绝不匹配项。 -- schema + 模型由 TypeBox 定义生成: +- 客户端发送 `minProtocol` + `maxProtocol`;服务器会拒绝不匹配的情况。 +- Schema 和模型由 TypeBox 定义生成: - `pnpm protocol:gen` - `pnpm protocol:gen:swift` - `pnpm protocol:check` @@ -508,83 +506,81 @@ Gateway 网关会将这些视为**声明**,并强制执行服务器端允许 | ----------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | | `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | | 请求超时(每个 RPC) | `30_000` ms | `src/gateway/client.ts`(`requestTimeoutMs`) | -| 预认证 / 连接挑战超时 | `15_000` ms | `src/gateway/handshake-timeouts.ts`(配置/环境变量可以提高成对的服务端/客户端预算) | +| 预身份验证 / 连接质询超时 | `15_000` ms | `src/gateway/handshake-timeouts.ts`(配置/环境变量可以提高配对的服务器/客户端预算) | | 初始重连退避 | `1_000` ms | `src/gateway/client.ts`(`backoffMs`) | | 最大重连退避 | `30_000` ms | `src/gateway/client.ts`(`scheduleReconnect`) | -| 设备令牌关闭后的快速重试限制 | `250` ms | `src/gateway/client.ts` | -| `terminate()` 前的强制停止宽限期 | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` | +| 设备令牌关闭后的快速重试钳制 | `250` ms | `src/gateway/client.ts` | +| `terminate()` 前的强制停止宽限时间 | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` | | `stopAndWait()` 默认超时 | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` | -| 默认 tick 间隔(`hello-ok` 前) | `30_000` ms | `src/gateway/client.ts` | -| tick 超时关闭 | 静默超过 `tickIntervalMs * 2` 时使用 code `4000` | `src/gateway/client.ts` | +| 默认 tick 间隔(`hello-ok` 前) | `30_000` ms | `src/gateway/client.ts` | +| tick 超时关闭 | 静默超过 `tickIntervalMs * 2` 时使用代码 `4000` | `src/gateway/client.ts` | | `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024`(25 MB) | `src/gateway/server-constants.ts` | -服务器会在 `hello-ok` 中公布生效的 `policy.tickIntervalMs`、`policy.maxPayload` 和 `policy.maxBufferedBytes`;客户端应遵循这些值,而不是握手前的默认值。 +服务器会在 `hello-ok` 中通告有效的 `policy.tickIntervalMs`、`policy.maxPayload` 和 `policy.maxBufferedBytes`;客户端应遵循这些值,而不是握手前的默认值。 -## 认证 +## 身份验证 - 共享密钥 Gateway 网关认证使用 `connect.params.auth.token` 或 - `connect.params.auth.password`,具体取决于配置的认证模式。 -- 带身份的模式,例如 Tailscale Serve - (`gateway.auth.allowTailscale: true`) 或非 loopback - `gateway.auth.mode: "trusted-proxy"`,会通过请求标头满足连接认证检查, - 而不是通过 `connect.params.auth.*`。 + `connect.params.auth.password`,具体取决于已配置的认证模式。 +- Tailscale Serve(`gateway.auth.allowTailscale: true`)或非 loopback + `gateway.auth.mode: "trusted-proxy"` 等带有身份信息的模式,会从请求标头满足连接认证检查, + 而不是使用 `connect.params.auth.*`。 - 私有入口 `gateway.auth.mode: "none"` 会完全跳过共享密钥连接认证; - 不要在公开/不受信任的入口上暴露该模式。 -- 配对后,Gateway 网关会签发一个限定为连接角色 + 作用域的**设备令牌**。 - 它会在 `hello-ok.auth.deviceToken` 中返回,客户端应将其持久化以供未来连接使用。 -- 客户端应在任何成功连接后持久化主 `hello-ok.auth.deviceToken`。 -- 使用该**已存储**设备令牌重新连接时,也应复用为该令牌存储的已批准作用域集。 - 这会保留已授予的读取/探测/status 访问权限,并避免将重新连接静默收窄为 - 仅管理员的隐式作用域。 + 不要在公共/不受信任的入口上暴露该模式。 +- 配对后,Gateway 网关会签发一个限定到连接角色 + 作用域的**设备令牌**。 + 它会在 `hello-ok.auth.deviceToken` 中返回,客户端应将其持久化用于后续连接。 +- 客户端应在任何成功连接后持久化主要的 `hello-ok.auth.deviceToken`。 +- 使用该**已存储**的设备令牌重新连接时,也应复用为该令牌存储的已批准作用域集合。 + 这会保留已经授予的读取/探测/status 访问权限,并避免将重连静默收窄为隐式的仅管理员作用域。 - 客户端连接认证组装(`src/gateway/client.ts` 中的 `selectConnectAuth`): - - `auth.password` 是正交的,设置后始终会被转发。 - - `auth.token` 按优先级填充:显式共享令牌优先, - 然后是显式 `deviceToken`,再然后是已存储的每设备令牌(按 - `deviceId` + `role` 作为键)。 - - 仅当上述任一项都未解析出 `auth.token` 时,才会发送 + - `auth.password` 是正交的,设置后始终会转发。 + - `auth.token` 按优先级填充:先使用显式共享令牌, + 然后是显式 `deviceToken`,最后是已存储的按设备令牌(按 + `deviceId` + `role` 键控)。 + - 只有当上述任何一项都没有解析出 `auth.token` 时,才会发送 `auth.bootstrapToken`。共享令牌或任何已解析的设备令牌都会抑制它。 - - 在一次性 `AUTH_TOKEN_MISMATCH` 重试中,自动提升已存储设备令牌仅限于**受信任端点** — - loopback,或带有固定 `tlsFingerprint` 的 `wss://`。未固定的公开 - `wss://` 不符合条件。 -- 额外的 `hello-ok.auth.deviceTokens` 条目是引导交接令牌。 - 仅当连接在受信任传输上使用引导认证时才持久化它们,例如 `wss://` 或 - loopback/本地配对。 -- 如果客户端提供**显式** `deviceToken` 或显式 `scopes`,则该调用方请求的作用域集仍为权威来源; - 缓存作用域仅在客户端复用已存储的每设备令牌时才会被复用。 + - 在一次性 `AUTH_TOKEN_MISMATCH` 重试中自动提升已存储设备令牌,仅限于**受信任端点**: + loopback,或带有已固定 `tlsFingerprint` 的 `wss://`。没有固定的公共 `wss://` + 不符合条件。 +- 额外的 `hello-ok.auth.deviceTokens` 条目是 bootstrap 交接令牌。 + 只有当连接在受信任传输上使用 bootstrap 认证时才持久化它们, + 例如 `wss://` 或 loopback/local 配对。 +- 如果客户端提供**显式** `deviceToken` 或显式 `scopes`, + 则该调用方请求的作用域集合仍然具有权威性;只有当客户端复用已存储的按设备令牌时, + 才会复用缓存的作用域。 - 设备令牌可通过 `device.token.rotate` 和 - `device.token.revoke` 轮换/撤销(需要 `operator.pairing` 作用域)。 -- `device.token.rotate` 返回轮换元数据。只有在同设备调用且已使用 - 该设备令牌完成认证时,它才会回显替换用 bearer 令牌,这样仅令牌客户端可在 - 重新连接前持久化替换令牌。共享/管理员轮换不会回显 bearer 令牌。 -- 令牌签发、轮换和撤销都会受限于该设备配对条目中记录的已批准角色集; - 令牌变更不能扩展或指向配对批准从未授予的设备角色。 -- 对于已配对设备令牌会话,除非调用方还拥有 `operator.admin`,否则设备管理是自限定作用域的: - 非管理员调用方只能移除/撤销/轮换其**自己的**设备条目。 -- `device.token.rotate` 和 `device.token.revoke` 还会将目标 operator - 令牌作用域集与调用方当前会话作用域进行检查。非管理员调用方不能轮换或撤销比自己已持有作用域更宽的 - operator 令牌。 + `device.token.revoke` 轮换/吊销(需要 `operator.pairing` 作用域)。 +- `device.token.rotate` 返回轮换元数据。只有在同一设备调用且已使用该设备令牌完成认证时, + 它才会回显替换用的 bearer 令牌,因此仅令牌客户端可以在重新连接前持久化替换令牌。 + 共享/管理员轮换不会回显 bearer 令牌。 +- 令牌签发、轮换和吊销始终受限于该设备配对条目中记录的已批准角色集合; + 令牌变更不能扩展到或指向配对批准从未授予的设备角色。 +- 对于已配对设备令牌会话,设备管理默认限定到自身范围,除非调用方还拥有 + `operator.admin`:非管理员调用方只能移除/吊销/轮换其**自己的**设备条目。 +- `device.token.rotate` 和 `device.token.revoke` 还会根据调用方当前会话作用域检查目标操作员令牌作用域集合。 + 非管理员调用方不能轮换或吊销比自己已持有范围更宽的操作员令牌。 - 认证失败包含 `error.details.code` 以及恢复提示: - `error.details.canRetryWithDeviceToken`(布尔值) - `error.details.recommendedNextStep`(`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`) -- 客户端针对 `AUTH_TOKEN_MISMATCH` 的行为: - - 受信任客户端可以尝试一次有界重试,使用缓存的每设备令牌。 - - 如果该重试失败,客户端应停止自动重新连接循环,并显示 operator 操作指导。 +- `AUTH_TOKEN_MISMATCH` 的客户端行为: + - 受信任客户端可以尝试一次有界重试,并使用缓存的按设备令牌。 + - 如果该重试失败,客户端应停止自动重连循环,并显示操作员操作指引。 ## 设备身份 + 配对 - 节点应包含从密钥对指纹派生的稳定设备身份(`device.id`)。 - Gateway 网关会按设备 + 角色签发令牌。 -- 除非启用了本地自动批准,否则新的设备 ID 需要配对批准。 +- 新设备 ID 需要配对批准,除非启用了本地自动批准。 - 配对自动批准以直接 local loopback 连接为中心。 -- OpenClaw 还提供一个狭窄的后端/容器本地自连接路径,用于受信任的共享密钥辅助流程。 -- 同主机 tailnet 或 LAN 连接仍会被视为远程配对,并需要批准。 -- WS 客户端通常会在 `connect` 期间包含 `device` 身份(operator + - 节点)。仅以下显式信任路径属于无设备 operator 例外: - - `gateway.controlUi.allowInsecureAuth=true`,用于仅限 localhost 的不安全 HTTP 兼容。 - - 成功的 `gateway.auth.mode: "trusted-proxy"` operator Control UI 认证。 - - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(应急破窗,严重降低安全性)。 +- OpenClaw 还为受信任的共享密钥辅助流程提供一条狭窄的后端/容器本地自连接路径。 +- 同主机 tailnet 或 LAN 连接在配对时仍视为远程连接,并需要批准。 +- WS 客户端通常会在 `connect` 期间包含 `device` 身份(操作员 + 节点)。 + 唯一无设备的操作员例外是显式信任路径: + - `gateway.controlUi.allowInsecureAuth=true`,用于仅限 localhost 的不安全 HTTP 兼容性。 + - 成功的 `gateway.auth.mode: "trusted-proxy"` 操作员 Control UI 认证。 + - `gateway.controlUi.dangerouslyDisableDeviceAuth=true`(应急开关,严重降低安全性)。 - 使用共享 Gateway 网关令牌/密码认证的 direct-loopback `gateway-client` 后端 RPC。 -- 所有连接都必须签署服务器提供的 `connect.challenge` nonce。 +- 所有连接都必须签名服务器提供的 `connect.challenge` nonce。 ### 设备认证迁移诊断 @@ -605,26 +601,25 @@ Gateway 网关会将这些视为**声明**,并强制执行服务器端允许 迁移目标: - 始终等待 `connect.challenge`。 -- 签署包含服务器 nonce 的 v2 载荷。 +- 签名包含服务器 nonce 的 v2 载荷。 - 在 `connect.params.device.nonce` 中发送相同的 nonce。 -- 首选签名载荷是 `v3`,它除了绑定设备/客户端/角色/作用域/令牌/nonce 字段外, +- 首选签名载荷是 `v3`,它除了设备/客户端/角色/作用域/令牌/nonce 字段外, 还会绑定 `platform` 和 `deviceFamily`。 -- 为保持兼容性,旧版 `v2` 签名仍会被接受,但已配对设备的 - 元数据固定仍会控制重新连接时的命令策略。 +- 为了兼容性,旧版 `v2` 签名仍会被接受,但已配对设备的元数据固定仍会控制重连时的命令策略。 ## TLS + 固定 - WS 连接支持 TLS。 -- 客户端可以选择固定 Gateway 网关证书指纹(见 `gateway.tls` +- 客户端可以选择固定 Gateway 网关证书指纹(请参阅 `gateway.tls` 配置以及 `gateway.remote.tlsFingerprint` 或 CLI `--tls-fingerprint`)。 -## 作用域 +## 范围 -该协议暴露**完整的 Gateway 网关 API**(status、渠道、模型、聊天、 +此协议暴露**完整 Gateway 网关 API**(status、渠道、模型、聊天、 智能体、会话、节点、批准等)。确切接口由 `src/gateway/protocol/schema.ts` 中的 TypeBox schema 定义。 ## 相关 - [Bridge protocol](/zh-CN/gateway/bridge-protocol) -- [Gateway runbook](/zh-CN/gateway) +- [Gateway 网关运行手册](/zh-CN/gateway) diff --git a/docs/zh-CN/gateway/security/index.md b/docs/zh-CN/gateway/security/index.md index 30a3fa7fe..faa56e40f 100644 --- a/docs/zh-CN/gateway/security/index.md +++ b/docs/zh-CN/gateway/security/index.md @@ -1,42 +1,41 @@ --- read_when: - 添加会扩大访问范围或自动化能力的功能 -summary: 运行具备 shell 访问权限的人工智能网关时的安全注意事项和威胁模型 +summary: 运行具有 shell 访问权限的 AI Gateway 网关的安全注意事项和威胁模型 title: 安全 x-i18n: - generated_at: "2026-05-02T09:44:55Z" + generated_at: "2026-05-03T00:42:54Z" model: gpt-5.5 provider: openai - source_hash: fe44c1ab2b0487afc60b6220aa7665be3803906da187fe38ce33daf8b86c3a1a + source_hash: cee36b337c79199e037d6087f9db0500925ed869d67dca302dedfe0d236b818f source_path: gateway/security/index.md workflow: 16 --- - **个人助理信任模型。** 本指南假设每个 Gateway 网关有一个受信任的 + **个人助理信任模型。** 本指南假设每个 Gateway 网关只有一个可信 操作者边界(单用户、个人助理模型)。 - OpenClaw **不是** 一个用于多个 - 对抗性用户共享同一智能体或 Gateway 网关的敌对多租户安全边界。如果你需要混合信任或 - 对抗性用户操作,请拆分信任边界(独立的 Gateway 网关 + - 凭证,最好还使用独立的操作系统用户或主机)。 + OpenClaw **不是**一个面向多个对抗性用户共享同一个智能体或 Gateway 网关的敌对多租户安全边界。如果你需要混合信任或 + 对抗性用户操作,请拆分信任边界(单独的 Gateway 网关 + + 凭据,最好还使用单独的 OS 用户或主机)。 -## 先界定范围:个人助理安全模型 +## 先明确范围:个人助理安全模型 -OpenClaw 安全指南假设采用**个人助理**部署:一个受信任的操作者边界,可以有多个智能体。 +OpenClaw 安全指南假设使用**个人助理**部署:一个可信操作者边界,可能包含多个智能体。 -- 支持的安全姿态:每个 Gateway 网关对应一个用户/信任边界(最好每个边界对应一个操作系统用户/主机/VPS)。 -- 不支持的安全边界:互不信任或对抗性的用户共用一个 Gateway 网关/智能体。 -- 如果需要对抗性用户隔离,请按信任边界拆分(独立的 Gateway 网关 + 凭证,最好还使用独立的操作系统用户/主机)。 -- 如果多个不受信任的用户都可以向同一个已启用工具的智能体发送消息,请将他们视为共享该智能体的同一委托工具权限。 +- 支持的安全姿态:每个 Gateway 网关一个用户/信任边界(优先每个边界使用一个 OS 用户/主机/VPS)。 +- 不支持作为安全边界的形态:由互不信任或对抗性用户共用的一个 Gateway 网关/智能体。 +- 如果需要对抗性用户隔离,请按信任边界拆分(单独的 Gateway 网关 + 凭据,最好还使用单独的 OS 用户/主机)。 +- 如果多个不受信任的用户可以向同一个启用了工具的智能体发消息,请把他们视为共享该智能体的同一组委托工具权限。 -本页说明的是**在该模型内**的加固方式。它不声称在一个共享 Gateway 网关上提供敌对多租户隔离。 +本页说明如何在**该模型内**加固。它不声称在一个共享 Gateway 网关上提供敌对多租户隔离。 ## 快速检查:`openclaw security audit` -另见:[形式化验证(安全模型)](/zh-CN/security/formal-verification) +另请参阅:[形式化验证(安全模型)](/zh-CN/security/formal-verification) -定期运行以下命令(尤其是在更改配置或暴露网络表面之后): +定期运行此命令(尤其是在更改配置或暴露网络表面之后): ```bash openclaw security audit @@ -45,109 +44,110 @@ openclaw security audit --fix openclaw security audit --json ``` -`security audit --fix` 会刻意保持范围很窄:它会将常见的开放 group -策略切换为 allowlist,恢复 `logging.redactSensitive: "tools"`,收紧 -state/config/include-file 权限,并且在 Windows 上运行时使用 Windows ACL 重置,而不是 +`security audit --fix` 会刻意保持较窄范围:它会将常见的开放组 +策略切换为允许列表,恢复 `logging.redactSensitive: "tools"`,收紧 +状态/配置/包含文件权限,并且在 Windows 上运行时使用 Windows ACL 重置而不是 POSIX `chmod`。 -它会标记常见风险点(Gateway 网关认证暴露、浏览器控制暴露、提升权限 allowlist、文件系统权限、宽松的 exec 审批,以及开放渠道工具暴露)。 +它会标记常见的风险点(Gateway 网关认证暴露、浏览器控制暴露、提升权限允许列表、文件系统权限、宽松的执行批准,以及开放渠道工具暴露)。 -OpenClaw 既是产品,也是实验:你正在把前沿模型行为接入真实消息表面和真实工具。**不存在“完全安全”的设置。** 目标是有意识地明确: +OpenClaw 既是一个产品,也是一个实验:你正在把前沿模型行为接入真实的消息表面和真实工具。**不存在“完全安全”的设置。**目标是有意识地明确: - 谁可以和你的机器人对话 -- 机器人被允许在哪里行动 +- 机器人可以在哪里执行操作 - 机器人可以接触什么 -从仍能工作的最小访问权限开始,然后随着信心提升再逐步放宽。 +先从仍能正常工作的最小访问权限开始,然后随着信心增加再扩大范围。 -### 部署与主机信任 +### 部署和主机信任 -OpenClaw 假设主机和配置边界是受信任的: +OpenClaw 假设主机和配置边界是可信的: -- 如果某人可以修改 Gateway 网关主机状态/配置(`~/.openclaw`,包括 `openclaw.json`),请将其视为受信任的操作者。 -- 不建议为多个互不信任/对抗性的操作者运行同一个 Gateway 网关。 -- 对于混合信任团队,请用独立 Gateway 网关拆分信任边界(或至少使用独立的操作系统用户/主机)。 -- 推荐默认方式:每台机器/主机(或 VPS)一个用户,该用户一个 Gateway 网关,并在该 Gateway 网关中运行一个或多个智能体。 -- 在同一个 Gateway 网关实例内,经过认证的操作者访问是受信任的控制平面角色,而不是按用户划分的租户角色。 +- 如果某人可以修改 Gateway 网关主机状态/配置(`~/.openclaw`,包括 `openclaw.json`),请将其视为可信操作者。 +- 不建议让多个互不信任/对抗性的操作者共用一个 Gateway 网关。 +- 对于混合信任团队,请使用单独的 Gateway 网关拆分信任边界(或至少使用单独的 OS 用户/主机)。 +- 推荐默认设置:每台机器/主机(或 VPS)一个用户,该用户一个 Gateway 网关,并在该 Gateway 网关中运行一个或多个智能体。 +- 在一个 Gateway 网关实例内,经过认证的操作者访问是可信控制平面角色,而不是按用户划分的租户角色。 - 会话标识符(`sessionKey`、会话 ID、标签)是路由选择器,不是授权令牌。 -- 如果多个人都可以向同一个已启用工具的智能体发送消息,他们每个人都可以引导同一组权限。按用户隔离会话/记忆有助于隐私,但不会把共享智能体变成按用户授权主机的机制。 +- 如果几个人可以向同一个启用了工具的智能体发消息,他们每个人都可以操控同一组权限。按用户划分的会话/记忆隔离有助于隐私,但不会把共享智能体转换成按用户划分的主机授权。 ### 共享 Slack 工作区:真实风险 -如果“Slack 中的每个人都可以向机器人发送消息”,核心风险是委托工具权限: +如果“Slack 中的所有人都可以给机器人发消息”,核心风险是委托工具权限: -- 任何被允许的发送者都可以在智能体策略范围内诱导工具调用(`exec`、浏览器、网络/文件工具); +- 任何获准的发送者都可以在智能体策略范围内诱导工具调用(`exec`、浏览器、网络/文件工具); - 来自某个发送者的提示/内容注入可能导致影响共享状态、设备或输出的操作; -- 如果一个共享智能体拥有敏感凭证/文件,任何被允许的发送者都可能通过工具使用驱动数据外泄。 +- 如果一个共享智能体拥有敏感凭据/文件,任何获准的发送者都可能通过工具使用来驱动外泄。 -团队工作流应使用工具最少的独立智能体/Gateway 网关;包含个人数据的智能体应保持私有。 +团队工作流应使用带有最少工具的单独智能体/Gateway 网关;将个人数据智能体保持私有。 ### 公司共享智能体:可接受模式 -当使用该智能体的所有人都处于同一信任边界内(例如同一个公司团队),且智能体严格限定为业务范围时,这种方式是可接受的。 +当使用该智能体的所有人都处于同一信任边界内(例如一个公司团队),并且该智能体严格限定在业务范围内时,这是可接受的。 -- 在专用机器/虚拟机/容器上运行; -- 为该运行时使用专用操作系统用户 + 专用浏览器/配置文件/账号; +- 在专用机器/VM/容器上运行它; +- 为该运行时使用专用 OS 用户 + 专用浏览器/配置文件/账号; - 不要让该运行时登录个人 Apple/Google 账号或个人密码管理器/浏览器配置文件。 -如果你在同一个运行时混用个人身份和公司身份,就会破坏隔离并增加个人数据暴露风险。 +如果你在同一个运行时混用个人和公司身份,就会破坏隔离并增加个人数据暴露风险。 ## Gateway 网关和节点信任概念 -将 Gateway 网关和节点视为一个操作者信任域,但二者角色不同: +将 Gateway 网关和节点视为同一个操作者信任域,但角色不同: - **Gateway 网关**是控制平面和策略表面(`gateway.auth`、工具策略、路由)。 -- **节点**是配对到该 Gateway 网关的远程执行表面(命令、设备操作、主机本地能力)。 -- 对 Gateway 网关完成认证的调用方在 Gateway 网关范围内受信任。配对之后,节点操作就是该节点上的受信任操作者操作。 -- 使用共享 Gateway 网关 - 令牌/密码完成认证的直接 loopback 后端客户端,可以在不出示用户 +- **节点**是与该 Gateway 网关配对的远程执行表面(命令、设备操作、主机本地能力)。 +- 经过 Gateway 网关认证的调用方在 Gateway 网关范围内被信任。配对后,节点操作会被视为该节点上的可信操作者操作。 +- 操作者范围级别和批准时检查汇总在 + [操作者范围](/zh-CN/gateway/operator-scopes)中。 +- 使用共享 Gateway 网关令牌/密码认证的直接 loopback 后端客户端可以在不提供用户 设备身份的情况下发起内部控制平面 RPC。这不是远程或浏览器配对绕过:网络 客户端、节点客户端、设备令牌客户端和显式设备身份 - 仍然需要经过配对和范围升级强制检查。 -- `sessionKey` 是路由/上下文选择,不是按用户认证。 -- Exec 审批(allowlist + ask)是操作者意图的防护栏,不是敌对多租户隔离。 -- 对受信任单操作者设置,OpenClaw 的产品默认值是允许在 `gateway`/`node` 上执行主机 exec,且不弹出审批提示(`security="full"`,`ask="off"`,除非你收紧它)。这个默认值是有意的用户体验设计,本身不是漏洞。 -- Exec 审批会绑定精确的请求上下文和尽力识别的直接本地文件操作数;它们不会在语义上建模每一种运行时/解释器加载路径。要获得强边界,请使用沙箱隔离和主机隔离。 + 仍会经过配对和范围升级强制执行。 +- `sessionKey` 是路由/上下文选择,不是按用户划分的认证。 +- 执行批准(允许列表 + 询问)是操作者意图的护栏,不是敌对多租户隔离。 +- OpenClaw 面向可信单操作者设置的产品默认行为是,`gateway`/`node` 上的主机执行允许无需批准提示(`security="full"`,`ask="off"`,除非你收紧它)。该默认值是有意的 UX 选择,本身不是漏洞。 +- 执行批准会绑定精确的请求上下文和尽力而为的直接本地文件操作数;它们不会对每个运行时/解释器加载器路径进行语义建模。要获得强边界,请使用沙箱隔离和主机隔离。 -如果你需要敌对用户隔离,请按操作系统用户/主机拆分信任边界,并运行独立 Gateway 网关。 +如果你需要敌对用户隔离,请按 OS 用户/主机拆分信任边界并运行单独的 Gateway 网关。 ## 信任边界矩阵 -排查风险时,可用此作为快速模型: +在分诊风险时,将其用作快速模型: | 边界或控制 | 含义 | 常见误读 | | --------------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------- | -| `gateway.auth`(令牌/密码/受信任代理/设备认证) | 对 Gateway 网关 API 调用方进行认证 | “为了安全,每一帧都需要逐消息签名” | -| `sessionKey` | 用于上下文/会话选择的路由键 | “会话键是用户认证边界” | -| 提示/内容防护栏 | 降低模型滥用风险 | “仅凭提示注入就证明认证绕过” | -| `canvas.eval` / 浏览器 evaluate | 启用时的有意操作者能力 | “任何 JS eval 原语在这个信任模型中都会自动成为漏洞” | -| 本地 TUI `!` shell | 显式由操作者触发的本地执行 | “本地 shell 便捷命令就是远程注入” | -| 节点配对和节点命令 | 在已配对设备上的操作者级远程执行 | “远程设备控制默认应被视为不受信任的用户访问” | -| `gateway.nodes.pairing.autoApproveCidrs` | 选择启用的受信任网络节点注册策略 | “默认禁用的 allowlist 是自动配对漏洞” | +| `gateway.auth`(令牌/密码/可信代理/设备认证) | 认证 Gateway 网关 API 的调用方 | “每一帧都需要逐消息签名才安全” | +| `sessionKey` | 上下文/会话选择的路由键 | “会话键是用户认证边界” | +| 提示/内容护栏 | 降低模型滥用风险 | “仅提示注入就证明认证绕过” | +| `canvas.eval` / 浏览器 evaluate | 启用时的有意操作者能力 | “任何 JS eval 原语在此信任模型中都会自动成为漏洞” | +| 本地 TUI `!` shell | 显式由操作者触发的本地执行 | “本地 shell 便捷命令是远程注入” | +| 节点配对和节点命令 | 在已配对设备上的操作者级远程执行 | “默认应将远程设备控制视为不受信任的用户访问” | +| `gateway.nodes.pairing.autoApproveCidrs` | 选择加入的可信网络节点注册策略 | “默认禁用的允许列表是自动配对漏洞” | ## 按设计不属于漏洞 - + -这些模式经常被报告;除非证明存在真实边界绕过,否则通常会被关闭且不采取行动: +这些模式经常被报告,并且通常会在没有实际边界绕过证明时关闭为无需操作: -- 仅有提示注入链,但没有策略、认证或沙箱绕过。 -- 假设在一个共享主机或配置上存在敌对多租户操作的主张。 -- 将正常操作者读取路径访问(例如 +- 仅提示注入链,且没有策略、认证或沙箱绕过。 +- 假设在一个共享主机或配置上进行敌对多租户操作的主张。 +- 将正常操作者读路径访问(例如 `sessions.list` / `sessions.preview` / `chat.history`)在共享 Gateway 网关设置中归类为 IDOR 的主张。 -- 仅限 localhost 的部署发现(例如仅限 loopback 的 +- 仅 localhost 部署发现(例如仅 loopback 的 Gateway 网关上的 HSTS)。 -- 针对此仓库中不存在的入站路径提出的 Discord 入站 webhook 签名发现。 +- 针对此仓库中不存在的入站路径的 Discord 入站 webhook 签名发现。 - 将节点配对元数据视为 `system.run` 的隐藏第二层按命令 - 审批机制的报告;真实执行边界仍然是 - Gateway 网关的全局节点命令策略加节点自身的 exec - 审批。 + 批准层的报告,而实际执行边界仍然是 + Gateway 网关的全局节点命令策略加上节点自身的执行 + 批准。 - 将已配置的 `gateway.nodes.pairing.autoApproveCidrs` 本身视为 - 漏洞的报告。该设置默认禁用,需要 + 漏洞的报告。此设置默认禁用,需要 显式 CIDR/IP 条目,只适用于首次 `role: node` 配对且 - 未请求 scopes 的情况,并且不会自动批准操作者/浏览器/Control UI、 - WebChat、角色升级、scope 升级、元数据更改、公钥更改, - 或同主机 loopback 受信任代理 header 路径,除非已显式启用 loopback 受信任代理认证。 + 没有请求范围,并且不会自动批准操作者/浏览器/Control UI、 + WebChat、角色升级、范围升级、元数据变更、公钥变更, + 或同主机 loopback 可信代理标头路径,除非已显式启用 loopback 可信代理认证。 - 将 `sessionKey` 视为 认证令牌的“缺少按用户授权”发现。 @@ -155,7 +155,7 @@ OpenClaw 假设主机和配置边界是受信任的: ## 60 秒加固基线 -先使用这个基线,然后按受信任智能体选择性重新启用工具: +先使用此基线,然后按可信智能体选择性地重新启用工具: ```json5 { @@ -180,56 +180,56 @@ OpenClaw 假设主机和配置边界是受信任的: } ``` -这会让 Gateway 网关保持仅本地访问、隔离私信,并默认禁用控制平面/运行时工具。 +这会让 Gateway 网关保持仅本地可用,隔离私信,并默认禁用控制平面/运行时工具。 ## 共享收件箱快速规则 -如果不止一个人可以给你的机器人发私信: +如果不止一个人可以 DM 你的机器人: - 设置 `session.dmScope: "per-channel-peer"`(多账号渠道使用 `"per-account-channel-peer"`)。 -- 保持 `dmPolicy: "pairing"` 或严格 allowlist。 -- 切勿将共享私信与宽泛工具访问结合使用。 -- 这会加固协作式/共享收件箱,但当用户共享主机/配置写入访问权限时,它并不是为敌对共租户隔离而设计的。 +- 保持 `dmPolicy: "pairing"` 或严格允许列表。 +- 绝不要将共享私信与宽泛工具访问结合使用。 +- 这会加固协作式/共享收件箱,但当用户共享主机/配置写入访问时,它并不是为敌对共租户隔离而设计的。 ## 上下文可见性模型 OpenClaw 区分两个概念: -- **触发授权**:谁可以触发智能体(`dmPolicy`、`groupPolicy`、allowlist、提及门控)。 -- **上下文可见性**:哪些补充上下文会注入模型输入(回复正文、引用文本、线程历史、转发元数据)。 +- **触发授权**:谁可以触发智能体(`dmPolicy`、`groupPolicy`、允许列表、提及门控)。 +- **上下文可见性**:哪些补充上下文会注入到模型输入中(回复正文、引用文本、话题历史、转发元数据)。 -Allowlist 会对触发和命令授权进行门控。`contextVisibility` 设置控制如何过滤补充上下文(引用回复、线程根、抓取的历史): +允许列表会限制触发和命令授权。`contextVisibility` 设置控制如何过滤补充上下文(引用回复、话题根、获取到的历史): -- `contextVisibility: "all"`(默认)会按接收时的样子保留补充上下文。 -- `contextVisibility: "allowlist"` 会将补充上下文过滤为通过当前 allowlist 检查允许的发送者。 -- `contextVisibility: "allowlist_quote"` 的行为类似 `allowlist`,但仍保留一个显式引用回复。 +- `contextVisibility: "all"`(默认)会按接收到的形式保留补充上下文。 +- `contextVisibility: "allowlist"` 会将补充上下文过滤为通过活动允许列表检查的发送者。 +- `contextVisibility: "allowlist_quote"` 的行为类似 `allowlist`,但仍会保留一条显式引用回复。 -按渠道或按房间/对话设置 `contextVisibility`。设置详情请参阅[群聊](/zh-CN/channels/groups#context-visibility-and-allowlists)。 +按渠道或按房间/对话设置 `contextVisibility`。有关设置详情,请参阅[群聊](/zh-CN/channels/groups#context-visibility-and-allowlists)。 -安全公告分诊指南: +安全通告分诊指南: -- 仅表明“模型可以看到来自不在允许列表中的发送者的引用文本或历史文本”的声明,属于可通过 `contextVisibility` 解决的加固发现,本身并不是鉴权或沙箱边界绕过。 -- 要构成安全影响,报告仍需展示信任边界绕过(鉴权、策略、沙箱、审批,或另一个已记录的边界)。 +- 仅显示“模型可以看到来自非允许列表发送者的引用文本或历史文本”的声明是可通过 `contextVisibility` 处理的加固发现,本身并不是身份验证或沙箱边界绕过。 +- 若要产生安全影响,报告仍需展示明确的信任边界绕过(身份验证、策略、沙箱、审批或其他已记录的边界)。 ## 审计检查内容(高层概览) - **入站访问**(私信策略、群组策略、允许列表):陌生人能否触发机器人? -- **工具影响范围**(高权限工具 + 开放房间):提示注入是否可能转化为 shell/文件/网络操作? -- **Exec 审批漂移**(`security=full`、`autoAllowSkills`、没有 `strictInlineEval` 的解释器允许列表):主机执行防护是否仍按你的预期工作? - - `security="full"` 是宽泛的姿态警告,并不是 bug 证明。它是可信个人助理设置所选择的默认值;只有当你的威胁模型需要审批或允许列表防护时才收紧它。 -- **网络暴露**(Gateway 网关绑定/鉴权、Tailscale Serve/Funnel、弱/短鉴权令牌)。 +- **工具影响范围**(提权工具 + 开放房间):提示注入是否可能转化为 shell/文件/网络操作? +- **执行审批漂移**(`security=full`、`autoAllowSkills`、没有 `strictInlineEval` 的解释器允许列表):主机执行防护是否仍按你的预期工作? + - `security="full"` 是宽泛姿态警告,而不是缺陷证明。它是受信任个人助理设置所选择的默认值;只有当你的威胁模型需要审批或允许列表防护时,才收紧它。 +- **网络暴露**(Gateway 网关绑定/身份验证、Tailscale Serve/Funnel、弱/短身份验证令牌)。 - **浏览器控制暴露**(远程节点、中继端口、远程 CDP 端点)。 - **本地磁盘卫生**(权限、符号链接、配置 include、“同步文件夹”路径)。 - **插件**(插件在没有显式允许列表的情况下加载)。 -- **策略漂移/误配置**(已配置沙箱 Docker 设置但沙箱模式关闭;`gateway.nodes.denyCommands` 模式无效,因为匹配仅按精确命令名进行(例如 `system.run`),且不会检查 shell 文本;危险的 `gateway.nodes.allowCommands` 条目;全局 `tools.profile="minimal"` 被每个智能体的配置覆盖;在宽松工具策略下可访问插件自有工具)。 -- **运行时预期漂移**(例如假设隐式 exec 仍表示 `sandbox`,而 `tools.exec.host` 现在默认是 `auto`;或者在沙箱模式关闭时显式设置 `tools.exec.host="sandbox"`)。 -- **模型卫生**(当配置的模型看起来已过时时发出警告;不是硬性阻断)。 +- **策略漂移/错误配置**(配置了沙箱 Docker 设置但沙箱模式关闭;`gateway.nodes.denyCommands` 模式无效,因为匹配仅基于精确命令名(例如 `system.run`),不会检查 shell 文本;危险的 `gateway.nodes.allowCommands` 条目;全局 `tools.profile="minimal"` 被每个智能体的配置覆盖;插件自有工具可在宽松工具策略下访问)。 +- **运行时期望漂移**(例如假设隐式执行仍表示 `sandbox`,但 `tools.exec.host` 现在默认是 `auto`;或在沙箱模式关闭时显式设置 `tools.exec.host="sandbox"`)。 +- **模型卫生**(当配置的模型看起来较旧时发出警告;不是硬性阻断)。 -如果运行 `--deep`,OpenClaw 还会尽力尝试实时 Gateway 网关探测。 +如果运行 `--deep`,OpenClaw 还会尝试尽力执行一次实时 Gateway 网关探测。 ## 凭证存储映射 -审计访问权限或决定备份内容时使用此信息: +在审计访问或决定要备份什么时使用此信息: - **WhatsApp**:`~/.openclaw/credentials/whatsapp//creds.json` - **Telegram 机器人令牌**:配置/环境变量或 `channels.telegram.tokenFile`(仅限普通文件;拒绝符号链接) @@ -238,65 +238,66 @@ Allowlist 会对触发和命令授权进行门控。`contextVisibility` 设置 - **配对允许列表**: - `~/.openclaw/credentials/-allowFrom.json`(默认账户) - `~/.openclaw/credentials/--allowFrom.json`(非默认账户) -- **模型鉴权配置文件**:`~/.openclaw/agents//agent/auth-profiles.json` +- **模型身份验证配置**:`~/.openclaw/agents//agent/auth-profiles.json` - **Codex 运行时状态**:`~/.openclaw/agents//agent/codex-home/` - **文件后端密钥载荷(可选)**:`~/.openclaw/secrets.json` - **旧版 OAuth 导入**:`~/.openclaw/credentials/oauth.json` ## 安全审计检查清单 -当审计打印发现时,按以下优先级处理: +当审计输出发现时,请按以下优先级处理: -1. **任何“开放”+ 启用工具的情况**:先锁定私信/群组(配对/允许列表),再收紧工具策略/沙箱隔离。 -2. **公网暴露**(LAN 绑定、Funnel、缺失鉴权):立即修复。 -3. **浏览器控制远程暴露**:把它视为操作员访问权限(仅限 tailnet、有意配对节点、避免公开暴露)。 -4. **权限**:确保状态/配置/凭证/鉴权信息不是组/全局可读。 +1. **任何“开放”+ 已启用工具的情况**:先锁定私信/群组(配对/允许列表),然后收紧工具策略/沙箱隔离。 +2. **公共网络暴露**(LAN 绑定、Funnel、缺少身份验证):立即修复。 +3. **浏览器控制远程暴露**:将其视为操作员访问(仅限 tailnet、有意配对节点、避免公开暴露)。 +4. **权限**:确保状态/配置/凭证/身份验证信息不能被组/全局读取。 5. **插件**:只加载你明确信任的内容。 -6. **模型选择**:对于任何带工具的机器人,优先使用现代、经过指令加固的模型。 +6. **模型选择**:对于任何带工具的机器人,优先使用现代、指令加固的模型。 -## 安全审计词汇表 +## 安全审计术语表 -每个审计发现都由结构化 `checkId` 标识(例如 +每个审计发现都由结构化的 `checkId` 标识(例如 `gateway.bind_no_auth` 或 `tools.exec.security_full_configured`)。常见 严重级别类别: -- `fs.*` — 状态、配置、凭证、鉴权配置文件的文件系统权限。 -- `gateway.*` — 绑定模式、鉴权、Tailscale、控制 UI、可信代理设置。 +- `fs.*` — 状态、配置、凭证、身份验证配置的文件系统权限。 +- `gateway.*` — 绑定模式、身份验证、Tailscale、控制 UI、可信代理设置。 - `hooks.*`、`browser.*`、`sandbox.*`、`tools.exec.*` — 各表面的加固。 -- `plugins.*`、`skills.*` — 插件/skill 供应链和扫描发现。 -- `security.exposure.*` — 访问策略与工具影响范围交汇处的横切检查。 +- `plugins.*`、`skills.*` — 插件/Skills 供应链和扫描发现。 +- `security.exposure.*` — 访问策略与工具影响范围交汇处的横向检查。 -完整目录(包含严重级别、修复键和自动修复支持)见 +完整目录(含严重级别、修复键和自动修复支持)见 [安全审计检查](/zh-CN/gateway/security/audit-checks)。 -## 通过 HTTP 使用控制 UI +## HTTP 上的控制 UI 控制 UI 需要**安全上下文**(HTTPS 或 localhost)来生成设备 身份。`gateway.controlUi.allowInsecureAuth` 是本地兼容性开关: -- 在 localhost 上,当页面通过非安全 HTTP 加载时,它允许没有设备身份的控制 UI 鉴权。 +- 在 localhost 上,当页面通过非安全 HTTP 加载时,它允许没有设备身份的控制 UI 身份验证。 - 它不会绕过配对检查。 - 它不会放宽远程(非 localhost)设备身份要求。 -优先使用 HTTPS(Tailscale Serve),或在 `127.0.0.1` 打开 UI。 +优先使用 HTTPS(Tailscale Serve),或在 `127.0.0.1` 上打开 UI。 -仅在应急场景中,`gateway.controlUi.dangerouslyDisableDeviceAuth` -会完全禁用设备身份检查。这是严重的安全降级; -除非你正在主动调试且能快速还原,否则请保持关闭。 +仅限应急场景使用,`gateway.controlUi.dangerouslyDisableDeviceAuth` +会完全禁用设备身份检查。这会严重降低安全性; +除非你正在主动调试且能快速恢复,否则请保持关闭。 与这些危险标志分开,成功的 `gateway.auth.mode: "trusted-proxy"` -可以在没有设备身份的情况下准入**操作员**控制 UI 会话。这是 -有意的鉴权模式行为,不是 `allowInsecureAuth` 快捷方式,而且它仍然 +可以在没有设备身份的情况下接纳**操作员**控制 UI 会话。这是 +有意设计的身份验证模式行为,不是 `allowInsecureAuth` 捷径,并且它仍然 不会扩展到节点角色的控制 UI 会话。 启用此设置时,`openclaw security audit` 会发出警告。 ## 不安全或危险标志摘要 -当已知的不安全/危险调试开关被启用时,`openclaw security audit` 会报告 `config.insecure_or_dangerous_flags`。生产环境中请不要设置这些开关。 +当已知不安全/危险的调试开关被启用时,`openclaw security audit` 会产生 +`config.insecure_or_dangerous_flags`。在生产环境中保持这些项未设置。 - + - `gateway.controlUi.allowInsecureAuth=true` - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` @@ -307,15 +308,15 @@ Allowlist 会对触发和命令授权进行门控。`contextVisibility` 设置 - + 控制 UI 和浏览器: - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback` - `gateway.controlUi.dangerouslyDisableDeviceAuth` - `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` - 渠道名称匹配(内置渠道和插件渠道;在适用情况下也可按 - `accounts.` 配置): + 渠道名称匹配(内置和插件渠道;在适用时也可用于每个 + `accounts.`): - `channels.discord.dangerouslyAllowNameMatching` - `channels.slack.dangerouslyAllowNameMatching` @@ -329,7 +330,7 @@ Allowlist 会对触发和命令授权进行门控。`contextVisibility` 设置 网络暴露: - - `channels.telegram.network.dangerouslyAllowPrivateNetwork`(也可按账户配置) + - `channels.telegram.network.dangerouslyAllowPrivateNetwork`(也可按账户设置) 沙箱 Docker(默认值 + 每个智能体): @@ -343,15 +344,15 @@ Allowlist 会对触发和命令授权进行门控。`contextVisibility` 设置 ## 反向代理配置 如果你在反向代理(nginx、Caddy、Traefik 等)后运行 Gateway 网关,请配置 -`gateway.trustedProxies`,以正确处理转发的客户端 IP。 +`gateway.trustedProxies`,以便正确处理转发的客户端 IP。 -当 Gateway 网关从一个**不在** `trustedProxies` 中的地址检测到代理头时,它**不会**把连接视为本地客户端。如果 Gateway 网关鉴权被禁用,这些连接会被拒绝。这可以防止鉴权绕过,否则经代理的连接会看起来来自 localhost 并获得自动信任。 +当 Gateway 网关从**不在** `trustedProxies` 中的地址检测到代理标头时,它**不会**将连接视为本地客户端。如果 Gateway 网关身份验证已禁用,这些连接会被拒绝。这会防止身份验证绕过,否则经过代理的连接可能看起来来自 localhost 并获得自动信任。 -`gateway.trustedProxies` 也会供 `gateway.auth.mode: "trusted-proxy"` 使用,但该鉴权模式更严格: +`gateway.trustedProxies` 也会供 `gateway.auth.mode: "trusted-proxy"` 使用,但该身份验证模式更严格: -- 可信代理鉴权默认会对 loopback 来源代理**失败关闭** +- 可信代理身份验证默认会**对 loopback 源代理失败关闭** - 同主机 loopback 反向代理可以使用 `gateway.trustedProxies` 进行本地客户端检测和转发 IP 处理 -- 同主机 loopback 反向代理只有在 `gateway.auth.trustedProxy.allowLoopback = true` 时才能满足 `gateway.auth.mode: "trusted-proxy"`;否则请使用令牌/密码鉴权 +- 同主机 loopback 反向代理只有在 `gateway.auth.trustedProxy.allowLoopback = true` 时才能满足 `gateway.auth.mode: "trusted-proxy"`;否则请使用令牌/密码身份验证 ```yaml gateway: @@ -365,77 +366,75 @@ gateway: password: ${OPENCLAW_GATEWAY_PASSWORD} ``` -配置 `trustedProxies` 后,Gateway 网关会使用 `X-Forwarded-For` 来确定客户端 IP。默认情况下会忽略 `X-Real-IP`,除非显式设置 `gateway.allowRealIpFallback: true`。 +配置 `trustedProxies` 后,Gateway 网关会使用 `X-Forwarded-For` 确定客户端 IP。默认会忽略 `X-Real-IP`,除非显式设置 `gateway.allowRealIpFallback: true`。 -可信代理头不会让节点设备配对自动受信任。 -`gateway.nodes.pairing.autoApproveCidrs` 是独立的、默认禁用的 -操作员策略。即使启用,loopback 来源的可信代理头路径 -也会被排除在节点自动审批之外,因为本地调用方可以伪造这些 -头,包括在显式启用 loopback 可信代理鉴权时也是如此。 +可信代理标头不会让节点设备配对自动受信任。 +`gateway.nodes.pairing.autoApproveCidrs` 是一个独立且默认禁用的 +操作员策略。即使启用,loopback 源可信代理标头路径 +也会被排除在节点自动批准之外,因为本地调用方可以伪造这些 +标头,包括显式启用 loopback 可信代理身份验证时也是如此。 -良好的反向代理行为(覆盖传入的转发头): +良好的反向代理行为(覆盖传入的转发标头): ```nginx proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr; ``` -不良的反向代理行为(追加/保留不可信的转发头): +不良的反向代理行为(追加/保留不受信任的转发标头): ```nginx proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ``` -## HSTS 和 origin 说明 +## HSTS 和来源说明 -- OpenClaw gateway 优先面向本地/loopback。如果你在反向代理处终止 TLS,请在那里为代理面向的 HTTPS 域名设置 HSTS。 -- 如果 gateway 本身终止 HTTPS,你可以设置 `gateway.http.securityHeaders.strictTransportSecurity`,让 OpenClaw 响应发出 HSTS 头。 -- 详细部署指导见 [可信代理鉴权](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)。 +- OpenClaw Gateway 网关优先面向本地/loopback。如果你在反向代理处终止 TLS,请在那里为面向代理的 HTTPS 域设置 HSTS。 +- 如果 Gateway 网关自身终止 HTTPS,你可以设置 `gateway.http.securityHeaders.strictTransportSecurity`,让 OpenClaw 响应发出 HSTS 标头。 +- 详细部署指南见[可信代理身份验证](/zh-CN/gateway/trusted-proxy-auth#tls-termination-and-hsts)。 - 对于非 loopback 控制 UI 部署,默认需要 `gateway.controlUi.allowedOrigins`。 -- `gateway.controlUi.allowedOrigins: ["*"]` 是显式允许所有浏览器 origin 的策略,不是加固默认值。请避免在严格受控的本地测试之外使用。 -- loopback 上的浏览器 origin 鉴权失败仍会被限速,即使 - 常规 loopback 豁免已启用,但锁定键会按 - 规范化后的 `Origin` 值限定范围,而不是使用一个共享的 localhost 桶。 -- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` 会启用 Host-header origin 回退模式;请将其视为操作员选择的危险策略。 -- 将 DNS rebinding 和代理 Host 头行为视为部署加固问题;保持 `trustedProxies` 严格,并避免将 gateway 直接暴露到公网。 +- `gateway.controlUi.allowedOrigins: ["*"]` 是显式允许所有浏览器来源的策略,不是加固默认值。避免在严格受控的本地测试之外使用它。 +- 即使启用了通用 loopback 豁免,loopback 上的浏览器来源身份验证失败仍会受到速率限制,但锁定键会按规范化的 `Origin` 值分别限定范围,而不是使用一个共享的 localhost 桶。 +- `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` 会启用 Host 标头来源回退模式;将其视为危险的操作员选择策略。 +- 将 DNS 重新绑定和代理 Host 标头行为视为部署加固问题;保持 `trustedProxies` 严格,并避免将 Gateway 网关直接暴露到公共互联网。 -## 本地会话日志存储在磁盘上 +## 本地会话日志存放在磁盘上 OpenClaw 将会话转录存储在 `~/.openclaw/agents//sessions/*.jsonl` 下的磁盘上。 这是会话连续性和(可选)会话记忆索引所必需的,但也意味着 -**任何拥有文件系统访问权限的进程/用户都可以读取这些日志**。请把磁盘访问视为信任 +**任何拥有文件系统访问权限的进程/用户都可以读取这些日志**。请将磁盘访问视为信任 边界,并锁定 `~/.openclaw` 的权限(见下方审计部分)。如果你需要 -在智能体之间实现更强隔离,请让它们在不同的 OS 用户或不同主机下运行。 +在智能体之间实现更强隔离,请在不同 OS 用户或不同主机下运行它们。 ## 节点执行(system.run) 如果已配对 macOS 节点,Gateway 网关可以在该节点上调用 `system.run`。这是 Mac 上的**远程代码执行**: - 需要节点配对(审批 + 令牌)。 -- Gateway 网关节点配对不是按命令审批的表面。它建立节点身份/信任并签发令牌。 +- Gateway 网关节点配对不是按命令审批的入口。它建立节点身份/信任并签发令牌。 - Gateway 网关通过 `gateway.nodes.allowCommands` / `denyCommands` 应用粗粒度的全局节点命令策略。 -- 在 Mac 上通过 **设置 → 执行审批**(security + ask + allowlist)控制。 -- 按节点的 `system.run` 策略是节点自己的执行审批文件(`exec.approvals.node.*`),它可以比 gateway 的全局命令 ID 策略更严格或更宽松。 -- 以 `security="full"` 且 `ask="off"` 运行的节点遵循默认的受信任操作员模型。除非你的部署明确要求更严格的审批或 allowlist 立场,否则应将其视为预期行为。 -- 审批模式会绑定精确的请求上下文,并在可能时绑定一个具体的本地脚本/文件操作数。如果 OpenClaw 无法为解释器/运行时命令精确识别出唯一一个直接本地文件,则会拒绝基于审批的执行,而不是承诺完整的语义覆盖。 -- 对于 `host=node`,基于审批的运行还会存储一个规范化的预备 - `systemRunPlan`;之后已审批的转发会复用该已存储计划,并且 Gateway 网关 - 验证会拒绝调用方在审批请求创建后对 command/cwd/session 上下文的编辑。 -- 如果你不想允许远程执行,请将 security 设为 **deny**,并移除该 Mac 的节点配对。 +- 在 Mac 上通过 **设置 → 执行审批** 控制(安全 + 询问 + 允许列表)。 +- 按节点的 `system.run` 策略是节点自己的执行审批文件(`exec.approvals.node.*`),它可以比 Gateway 网关的全局命令 ID 策略更严格或更宽松。 +- 以 `security="full"` 和 `ask="off"` 运行的节点遵循默认可信操作员模型。除非你的部署明确要求更严格的审批或允许列表立场,否则应将其视为预期行为。 +- 审批模式会绑定精确的请求上下文,并在可能时绑定一个具体的本地脚本/文件操作数。如果 OpenClaw 无法为解释器/运行时命令精确识别出一个直接本地文件,则会拒绝基于审批的执行,而不是承诺完整的语义覆盖。 +- 对于 `host=node`,基于审批的运行还会存储一个规范化、已准备好的 + `systemRunPlan`;后续已审批的转发会复用该已存储计划,并且 Gateway 网关 + 验证会拒绝调用方在审批请求创建后对命令/cwd/会话上下文的编辑。 +- 如果你不想启用远程执行,请将安全设置为 **deny**,并移除该 Mac 的节点配对。 -这个区别对分流很重要: +这一区分对分流很重要: -- 重新连接的已配对节点宣告不同的命令列表,这本身并不是漏洞,只要 Gateway 网关全局策略和节点的本地执行审批仍然强制执行实际的执行边界。 +- 重新连接的已配对节点宣告不同的命令列表,本身并不是漏洞,前提是 Gateway 网关全局策略和节点的本地执行审批仍然强制执行实际的执行边界。 - 将节点配对元数据视为第二层隐藏的按命令审批层的报告,通常是策略/UX 混淆,而不是安全边界绕过。 ## 动态 Skills(监视器 / 远程节点) -OpenClaw 可以在会话中刷新 Skills 列表: +OpenClaw 可以在会话中途刷新 Skills 列表: -- **Skills 监视器**:对 `SKILL.md` 的更改可以在下一轮智能体 turn 更新 Skills 快照。 -- **远程节点**:连接 macOS 节点可以让仅限 macOS 的 Skills 符合条件(基于 bin 探测)。 +- **Skills 监视器**:对 `SKILL.md` 的更改可以在下一次智能体回合更新 Skills 快照。 +- **远程节点**:连接 macOS 节点可以让仅限 macOS 的 Skills 变为可用(基于 bin 探测)。 -将 Skills 文件夹视为**受信任代码**,并限制可修改它们的人员。 +将 Skills 文件夹视为 **可信代码**,并限制可修改它们的人员。 ## 威胁模型 @@ -448,46 +447,45 @@ OpenClaw 可以在会话中刷新 Skills 列表: 给你发消息的人可以: -- 试图诱导你的 AI 做坏事 -- 通过社会工程获取你的数据访问权 +- 试图诱骗你的 AI 做坏事 +- 通过社会工程获取你的数据访问权限 - 探测基础设施细节 -## 核心概念:先访问控制,后智能 +## 核心概念:智能之前先做访问控制 -这里的大多数失败并不是复杂漏洞,而是“有人给机器人发了消息,机器人照做了”。 +这里的大多数失败并不是复杂的漏洞利用,而是“有人给 bot 发了消息,然后 bot 按他们的要求做了”。 OpenClaw 的立场: -- **身份优先:**决定谁可以与机器人交谈(私信配对 / allowlist / 显式“open”)。 -- **范围其次:**决定机器人允许在哪里执行操作(群组 allowlist + mention 门控、工具、沙箱隔离、设备权限)。 -- **模型最后:**假设模型可以被操纵;通过设计限制操纵的影响范围。 +- **身份优先:** 决定谁可以和 bot 对话(私信配对 / 允许列表 / 显式“开放”)。 +- **范围其次:** 决定 bot 被允许在哪里行动(群组允许列表 + 提及门控、工具、沙箱隔离、设备权限)。 +- **模型最后:** 假设模型可能被操纵;设计时让操纵造成的影响范围有限。 ## 命令授权模型 -斜杠命令和指令只会对**已授权发送者**生效。授权来源于 -渠道 allowlist/配对加上 `commands.useAccessGroups`(见[配置](/zh-CN/gateway/configuration) -和[斜杠命令](/zh-CN/tools/slash-commands))。如果某个渠道 allowlist 为空或包含 `"*"`, -则该渠道的命令实际上是开放的。 +斜杠命令和指令只会对 **已授权发送者** 生效。授权来自 +渠道允许列表/配对以及 `commands.useAccessGroups`(参见 [配置](/zh-CN/gateway/configuration) +和 [斜杠命令](/zh-CN/tools/slash-commands))。如果某个渠道允许列表为空或包含 `"*"`, +该渠道的命令实际上是开放的。 -`/exec` 是供已授权操作员使用的仅限会话便利功能。它**不会**写入配置或 +`/exec` 是面向已授权操作员的仅限会话便捷功能。它**不会**写入配置或 更改其他会话。 ## 控制平面工具风险 -两个内置工具可以进行持久性控制平面更改: +两个内置工具可以进行持久化控制平面更改: -- `gateway` 可以通过 `config.schema.lookup` / `config.get` 检查配置,并可以通过 `config.apply`、`config.patch` 和 `update.run` 进行持久性更改。 -- `cron` 可以创建定时任务,这些任务会在原始聊天/任务结束后继续运行。 +- `gateway` 可以通过 `config.schema.lookup` / `config.get` 检查配置,并可以通过 `config.apply`、`config.patch` 和 `update.run` 进行持久化更改。 +- `cron` 可以创建在原始聊天/任务结束后仍继续运行的定时作业。 仅限所有者的 `gateway` 运行时工具仍会拒绝重写 `tools.exec.ask` 或 `tools.exec.security`;旧版 `tools.bash.*` 别名会在写入前 -规范化为相同的受保护 exec 路径。 -智能体驱动的 `gateway config.apply` 和 `gateway config.patch` 编辑默认 -fail-closed:只有一组很窄的 prompt、model 和 mention-gating -路径可由智能体调节。因此,新的敏感配置树会受到保护, -除非它们被有意加入 allowlist。 +规范化到相同的受保护执行路径。 +由智能体驱动的 `gateway config.apply` 和 `gateway config.patch` 编辑默认采用 +失败关闭策略:只有一小组提示词、模型和提及门控路径可由智能体调节。因此,新的敏感配置树会受到保护, +除非它们被有意加入允许列表。 -对于任何处理不受信任内容的智能体/表面,默认拒绝这些工具: +对于任何处理不受信内容的智能体/表面,默认拒绝这些工具: ```json5 { @@ -497,36 +495,36 @@ fail-closed:只有一组很窄的 prompt、model 和 mention-gating } ``` -`commands.restart=false` 只会阻止重启操作。它不会禁用 `gateway` 配置/update 操作。 +`commands.restart=false` 只会阻止重启动作。它不会禁用 `gateway` 配置/更新动作。 ## 插件 -插件在 Gateway 网关中**进程内**运行。将它们视为受信任代码: +插件与 Gateway 网关在**同一进程内**运行。将它们视为可信代码: - 只安装来自你信任来源的插件。 -- 优先使用显式 `plugins.allow` allowlist。 +- 优先使用显式的 `plugins.allow` 允许列表。 - 启用前审查插件配置。 - 插件更改后重启 Gateway 网关。 -- 如果你安装或更新插件(`openclaw plugins install `、`openclaw plugins update `),请像运行不受信任代码一样对待: +- 如果你安装或更新插件(`openclaw plugins install `、`openclaw plugins update `),请将其视为运行不受信代码: - 安装路径是活动插件安装根目录下的按插件目录。 - - OpenClaw 会在安装/update 前运行内置危险代码扫描。默认情况下,`critical` 发现会阻止安装。 - - npm 和 git 插件安装只会在显式 install/update 流程中运行包管理器依赖收敛。本地路径和归档会被视为自包含插件包;OpenClaw 会复制/引用它们,而不会运行 `npm install`。 + - OpenClaw 会在安装/更新前运行内置危险代码扫描。默认情况下,`critical` 发现会阻止操作。 + - npm 和 git 插件安装只在显式安装/更新流程期间运行包管理器依赖收敛。本地路径和归档会被视为自包含插件包;OpenClaw 会复制/引用它们,而不会运行 `npm install`。 - 优先使用固定的精确版本(`@scope/pkg@1.2.3`),并在启用前检查磁盘上解包后的代码。 - - `--dangerously-force-unsafe-install` 只是用于插件 install/update 流程中内置扫描误报的紧急选项。它不会绕过插件 `before_install` 钩子策略阻止,也不会绕过扫描失败。 - - Gateway 网关支持的 Skill 依赖安装遵循相同的危险/可疑分级:内置 `critical` 发现会阻止,除非调用方显式设置 `dangerouslyForceUnsafeInstall`,而可疑发现仍只会发出警告。`openclaw skills install` 仍是单独的 ClawHub Skill 下载/安装流程。 + - `--dangerously-force-unsafe-install` 只是插件安装/更新流程中针对内置扫描误报的破窗选项。它不会绕过插件 `before_install` 钩子策略阻止,也不会绕过扫描失败。 + - 由 Gateway 网关支持的 Skill 依赖安装遵循相同的危险/可疑划分:除非调用方显式设置 `dangerouslyForceUnsafeInstall`,内置 `critical` 发现会阻止操作,而可疑发现仍仅发出警告。`openclaw skills install` 仍是独立的 ClawHub Skill 下载/安装流程。 详情:[插件](/zh-CN/tools/plugin) -## 私信访问模型:配对、allowlist、open、disabled +## 私信访问模型:配对、允许列表、开放、禁用 -所有当前支持私信的渠道都支持私信策略(`dmPolicy` 或 `*.dm.policy`),该策略会在处理消息**之前**门控入站私信: +所有当前支持私信的渠道都支持私信策略(`dmPolicy` 或 `*.dm.policy`),该策略会在消息被处理**之前**对入站私信进行门控: -- `pairing`(默认):未知发送者会收到一段简短配对码,机器人会忽略他们的消息,直到获得批准。代码在 1 小时后过期;重复私信不会重新发送代码,直到创建新请求。默认情况下,待处理请求上限为**每个渠道 3 个**。 -- `allowlist`:未知发送者会被阻止(没有配对握手)。 -- `open`:允许任何人私信(公开)。**要求**渠道 allowlist 包含 `"*"`(显式选择加入)。 +- `pairing`(默认):未知发送者会收到一个简短配对码,bot 会忽略他们的消息,直到配对获批。代码在 1 小时后过期;重复私信不会重新发送代码,直到创建新的请求。默认情况下,待处理请求按渠道上限为 **3 个**。 +- `allowlist`:未知发送者会被阻止(无配对握手)。 +- `open`:允许任何人私信(公开)。**要求**渠道允许列表包含 `"*"`(显式选择加入)。 - `disabled`:完全忽略入站私信。 -通过 CLI 批准: +通过 CLI 审批: ```bash openclaw pairing list @@ -537,7 +535,7 @@ openclaw pairing approve ## 私信会话隔离(多用户模式) -默认情况下,OpenClaw 会将**所有私信路由到主会话**,这样你的助手可以跨设备和渠道保持连续性。如果**多个人**可以私信机器人(开放私信或多人 allowlist),请考虑隔离私信会话: +默认情况下,OpenClaw 会将**所有私信路由到主会话**,让你的助手在不同设备和渠道之间保持连续性。如果**多个人**可以给 bot 发私信(开放私信或多人允许列表),请考虑隔离私信会话: ```json5 { @@ -545,76 +543,76 @@ openclaw pairing approve } ``` -这可以防止跨用户上下文泄露,同时保持群聊隔离。 +这会防止跨用户上下文泄漏,同时保持群聊隔离。 -这是消息上下文边界,不是主机管理员边界。如果用户之间互相对抗,并共享同一个 Gateway 网关主机/配置,请改为按信任边界运行独立 gateway。 +这是消息上下文边界,而不是主机管理员边界。如果用户之间互不信任并共享同一个 Gateway 网关主机/配置,请改为按信任边界运行独立的 Gateway 网关。 ### 安全私信模式(推荐) 将上面的片段视为**安全私信模式**: - 默认:`session.dmScope: "main"`(所有私信共享一个会话以保持连续性)。 -- 本地 CLI 新手引导默认值:未设置时写入 `session.dmScope: "per-channel-peer"`(保留现有显式值)。 -- 安全私信模式:`session.dmScope: "per-channel-peer"`(每个渠道+发送者组合获得一个隔离的私信上下文)。 -- 跨渠道对等方隔离:`session.dmScope: "per-peer"`(每个发送者在同类型的所有渠道中获得一个会话)。 +- 本地 CLI 新手引导默认值:在未设置时写入 `session.dmScope: "per-channel-peer"`(保留现有显式值)。 +- 安全私信模式:`session.dmScope: "per-channel-peer"`(每个渠道+发送者组合获得隔离的私信上下文)。 +- 跨渠道对等方隔离:`session.dmScope: "per-peer"`(每个发送者在同类型所有渠道中获得一个会话)。 -如果你在同一渠道上运行多个账号,请改用 `per-account-channel-peer`。如果同一个人通过多个渠道联系你,请使用 `session.identityLinks` 将这些私信会话合并为一个规范身份。见[会话管理](/zh-CN/concepts/session)和[配置](/zh-CN/gateway/configuration)。 +如果你在同一渠道上运行多个账号,请改用 `per-account-channel-peer`。如果同一个人在多个渠道联系你,请使用 `session.identityLinks` 将这些私信会话折叠为一个规范身份。参见 [会话管理](/zh-CN/concepts/session) 和 [配置](/zh-CN/gateway/configuration)。 -## 私信和群组的 allowlist +## 私信和群组的允许列表 OpenClaw 有两个独立的“谁可以触发我?”层: -- **私信 allowlist**(`allowFrom` / `channels.discord.allowFrom` / `channels.slack.allowFrom`;旧版:`channels.discord.dm.allowFrom`、`channels.slack.dm.allowFrom`):谁可以在直接消息中与机器人交谈。 - - 当 `dmPolicy="pairing"` 时,审批会写入 `~/.openclaw/credentials/` 下账号作用域的配对 allowlist 存储(默认账号为 `-allowFrom.json`,非默认账号为 `--allowFrom.json`),并与配置 allowlist 合并。 -- **群组 allowlist**(渠道特定):机器人到底会接受哪些群组/渠道/guild 的消息。 +- **私信允许列表**(`allowFrom` / `channels.discord.allowFrom` / `channels.slack.allowFrom`;旧版:`channels.discord.dm.allowFrom`、`channels.slack.dm.allowFrom`):谁被允许在直接消息中与 bot 对话。 + - 当 `dmPolicy="pairing"` 时,审批会写入 `~/.openclaw/credentials/` 下按账号划分的配对允许列表存储(默认账号为 `-allowFrom.json`,非默认账号为 `--allowFrom.json`),并与配置允许列表合并。 +- **群组允许列表**(特定于渠道):bot 会从哪些群组/渠道/guild 接受消息。 - 常见模式: - - `channels.whatsapp.groups`、`channels.telegram.groups`、`channels.imessage.groups`:按群组的默认值,例如 `requireMention`;设置后,它也会充当群组 allowlist(包含 `"*"` 以保留 allow-all 行为)。 - - `groupPolicy="allowlist"` + `groupAllowFrom`:限制谁可以在群组会话_内部_触发机器人(WhatsApp/Telegram/Signal/iMessage/Microsoft Teams)。 - - `channels.discord.guilds` / `channels.slack.channels`:按表面的 allowlist + mention 默认值。 - - 群组检查按此顺序运行:先 `groupPolicy`/群组 allowlist,再 mention/reply 激活。 - - 回复机器人消息(隐式 mention)**不会**绕过 `groupAllowFrom` 等发送者 allowlist。 - - **安全注意事项:**将 `dmPolicy="open"` 和 `groupPolicy="open"` 视为最后手段设置。它们应该极少使用;除非你完全信任房间中的每个成员,否则优先使用配对 + allowlist。 + - `channels.whatsapp.groups`、`channels.telegram.groups`、`channels.imessage.groups`:按群组默认值,例如 `requireMention`;设置后,它也会充当群组允许列表(包含 `"*"` 以保留全部允许行为)。 + - `groupPolicy="allowlist"` + `groupAllowFrom`:限制谁可以在群组会话_内部_触发 bot(WhatsApp/Telegram/Signal/iMessage/Microsoft Teams)。 + - `channels.discord.guilds` / `channels.slack.channels`:按表面的允许列表 + 提及默认值。 + - 群组检查按此顺序运行:先执行 `groupPolicy`/群组允许列表,再执行提及/回复激活。 + - 回复 bot 消息(隐式提及)**不会**绕过 `groupAllowFrom` 等发送者允许列表。 + - **安全注意事项:** 将 `dmPolicy="open"` 和 `groupPolicy="open"` 视为最后手段设置。它们应当极少使用;除非你完全信任房间中的每个成员,否则优先使用配对 + 允许列表。 -详情:[配置](/zh-CN/gateway/configuration)和[群组](/zh-CN/channels/groups) +详情:[配置](/zh-CN/gateway/configuration) 和 [群组](/zh-CN/channels/groups) -## Prompt injection(它是什么,为什么重要) +## 提示注入(是什么,为什么重要) -Prompt injection 是指攻击者构造一条消息,操纵模型执行不安全操作(“忽略你的指令”、“转储你的文件系统”、“访问此链接并运行命令”等)。 +提示注入是指攻击者构造一条消息,操纵模型执行不安全操作(“忽略你的指令”、“导出你的文件系统”、“打开这个链接并运行命令”等)。 -即使有强系统提示,**prompt injection 也尚未被解决**。系统提示护栏只是软性指导;硬性强制来自工具策略、exec 审批、沙箱隔离和渠道 allowlist(而且操作员可以按设计禁用这些机制)。实践中有帮助的是: +即使有强系统提示词,**提示注入也尚未被解决**。系统提示词防护栏只是软性指导;硬性强制来自工具策略、执行审批、沙箱隔离和渠道允许列表(而操作员也可以按设计禁用这些)。实践中有帮助的是: -- 将传入私信保持锁定(配对/允许列表)。 -- 在群组中优先使用提及门控;避免在公开房间使用“始终在线”的机器人。 +- 保持入站私信锁定(配对/允许列表)。 +- 在群组中优先使用提及门控;避免在公共房间中使用“始终在线”的机器人。 - 默认将链接、附件和粘贴的指令视为恶意内容。 -- 在沙箱中运行敏感工具执行;不要让密钥出现在智能体可访问的文件系统中。 -- 注意:沙箱隔离是选择启用的。如果沙箱模式关闭,隐式 `host=auto` 会解析到 Gateway 网关主机。显式 `host=sandbox` 仍会失败关闭,因为没有可用的沙箱运行时。如果你希望在配置中明确该行为,请设置 `host=gateway`。 -- 将高风险工具(`exec`、`browser`、`web_fetch`、`web_search`)限制给可信智能体或显式允许列表。 -- 如果你将解释器(`python`、`node`、`ruby`、`perl`、`php`、`lua`、`osascript`)加入允许列表,请启用 `tools.exec.strictInlineEval`,这样内联 eval 形式仍需要显式批准。 -- Shell 审批分析也会拒绝 **未加引号的 heredoc** 中的 POSIX 参数展开形式(`$VAR`、`$?`、`$$`、`$1`、`$@`、`${…}`),因此已加入允许列表的 heredoc 正文无法把 shell 展开伪装成纯文本绕过允许列表审查。为 heredoc 结束符加引号(例如 `<<'EOF'`)以选择字面正文语义;会展开变量的未加引号 heredoc 会被拒绝。 -- **模型选择很重要:** 较旧/较小/遗留模型对提示注入和工具滥用的防护显著更弱。对于启用工具的智能体,请使用可用的最强最新一代、经过指令加固的模型。 +- 在沙箱中运行敏感工具执行;让密钥远离智能体可访问的文件系统。 +- 注意:沙箱隔离是选择启用的。如果沙箱模式关闭,隐式 `host=auto` 会解析为 Gateway 网关主机。显式 `host=sandbox` 仍会失败关闭,因为没有可用的沙箱运行时。如果你希望在配置中明确这种行为,请设置 `host=gateway`。 +- 将高风险工具(`exec`、`browser`、`web_fetch`、`web_search`)限制为可信智能体或显式允许列表。 +- 如果你允许解释器(`python`、`node`、`ruby`、`perl`、`php`、`lua`、`osascript`),请启用 `tools.exec.strictInlineEval`,这样内联求值形式仍需要显式批准。 +- Shell 批准分析还会拒绝 **未加引号的 heredocs** 中的 POSIX 参数展开形式(`$VAR`、`$?`、`$$`、`$1`、`$@`、`${…}`),因此允许列表中的 heredoc 正文不能伪装成纯文本绕过允许列表审查并偷偷执行 Shell 展开。为 heredoc 结束符加引号(例如 `<<'EOF'`)即可选择字面正文语义;会展开变量的未加引号 heredocs 会被拒绝。 +- **模型选择很重要:** 较旧/较小/遗留模型在抵御提示注入和工具误用方面明显不够稳健。对于启用工具的智能体,请使用可用的最强、最新一代、经过指令强化的模型。 需要视为不可信的危险信号: -- “读取这个文件/URL,并完全照它说的做。” -- “忽略你的系统提示或安全规则。” +- “读取这个文件/URL,并严格按其中说明执行。” +- “忽略你的系统提示词或安全规则。” - “泄露你的隐藏指令或工具输出。” - “粘贴 ~/.openclaw 或你的日志的完整内容。” ## 外部内容特殊 token 清理 -OpenClaw 会在常见自托管 LLM 聊天模板特殊 token 字面量到达模型之前,将其从包装后的外部内容和元数据中剥离。覆盖的标记族包括 Qwen/ChatML、Llama、Gemma、Mistral、Phi,以及 GPT-OSS 角色/轮次 token。 +OpenClaw 会先从封装的外部内容和元数据中移除常见的自托管 LLM 聊天模板特殊 token 字面量,再将它们传给模型。覆盖的标记族包括 Qwen/ChatML、Llama、Gemma、Mistral、Phi,以及 GPT-OSS 角色/轮次 token。 原因: -- 作为自托管模型前端的 OpenAI 兼容后端,有时会保留用户文本中出现的特殊 token,而不是屏蔽它们。否则,能够写入传入外部内容(抓取的页面、邮件正文、文件内容工具输出)的攻击者,可能注入合成的 `assistant` 或 `system` 角色边界,并逃逸包装内容的防护规则。 -- 清理发生在外部内容包装层,因此会统一应用于抓取/读取工具和传入渠道内容,而不是按提供商分别处理。 -- 传出的模型响应已经有独立的清理器,会在最终渠道投递边界,从用户可见回复中剥离泄露的 ``、``、``、`` 以及类似的内部运行时脚手架。外部内容清理器是对应的传入侧机制。 +- 面向自托管模型的 OpenAI 兼容后端有时会保留用户文本中出现的特殊 token,而不是将其屏蔽。否则,能够写入入站外部内容(抓取的页面、邮件正文、文件内容工具输出)的攻击者可能注入合成的 `assistant` 或 `system` 角色边界,并逃逸封装内容的防护。 +- 清理发生在外部内容封装层,因此会统一应用于抓取/读取工具和入站渠道内容,而不是按提供商分别处理。 +- 出站模型响应已经有单独的清理器,会在最终渠道投递边界从用户可见回复中移除泄露的 ``、``、``、`` 以及类似的内部运行时脚手架。外部内容清理器是对应的入站防护。 -这不会替代本页的其他加固措施,`dmPolicy`、允许列表、exec 审批、沙箱隔离和 `contextVisibility` 仍承担主要工作。它会封闭一种针对自托管栈的特定 tokenizer 层绕过方式,这类栈会完整转发带有特殊 token 的用户文本。 +这不会取代本页的其他加固措施 — `dmPolicy`、允许列表、exec 批准、沙箱隔离和 `contextVisibility` 仍承担主要工作。它关闭的是一种特定的 tokenizer 层绕过路径,针对会完整转发带特殊 token 用户文本的自托管栈。 ## 不安全外部内容绕过标志 -OpenClaw 包含会禁用外部内容安全包装的显式绕过标志: +OpenClaw 包含会禁用外部内容安全封装的显式绕过标志: - `hooks.mappings[].allowUnsafeExternalContent` - `hooks.gmail.allowUnsafeExternalContent` @@ -622,71 +620,71 @@ OpenClaw 包含会禁用外部内容安全包装的显式绕过标志: 指导: -- 在生产环境中保持这些未设置/false。 -- 仅在严格限定范围的调试中临时启用。 +- 在生产环境中保持这些项未设置/为 false。 +- 仅在范围严格限定的调试中临时启用。 - 如果启用,请隔离该智能体(沙箱 + 最少工具 + 专用会话命名空间)。 -Hooks 风险注意事项: +钩子风险说明: -- Hook 载荷是不可信内容,即使投递来自你控制的系统(邮件/文档/web 内容可能携带提示注入)。 -- 较弱模型层级会提高这种风险。对于 hook 驱动的自动化,优先使用强大的现代模型层级,并保持工具策略严格(`tools.profile: "messaging"` 或更严格),并尽可能使用沙箱隔离。 +- 钩子载荷是不可信内容,即使投递来自你控制的系统(邮件/文档/网页内容也可能携带提示注入)。 +- 弱模型层级会增加这种风险。对于钩子驱动的自动化,优先选择强大的现代模型层级,并保持工具策略严格(`tools.profile: "messaging"` 或更严格),同时尽可能启用沙箱隔离。 -### 提示注入不需要公开私信 +### 提示注入不需要公共私信 -即使**只有你**能给机器人发消息,提示注入仍可能通过机器人读取的任何**不可信内容**发生(web 搜索/抓取结果、浏览器页面、邮件、文档、附件、粘贴的日志/代码)。换句话说:发送者并不是唯一的威胁面;**内容本身**可能携带对抗性指令。 +即使**只有你**能给机器人发消息,提示注入仍可能通过机器人读取的任何**不可信内容**发生(Web 搜索/抓取结果、浏览器页面、邮件、文档、附件、粘贴的日志/代码)。换句话说:发送者不是唯一威胁面;**内容本身**也可能携带对抗性指令。 -启用工具时,典型风险是外泄上下文或触发工具调用。通过以下方式缩小影响范围: +启用工具时,典型风险是外泄上下文或触发工具调用。通过以下方式降低影响范围: -- 使用只读或禁用工具的**阅读器智能体**来总结不可信内容,然后将摘要传递给你的主智能体。 +- 使用只读或禁用工具的**阅读器智能体**来总结不可信内容,然后将摘要传给你的主智能体。 - 除非需要,否则为启用工具的智能体关闭 `web_search` / `web_fetch` / `browser`。 - 对于 OpenResponses URL 输入(`input_file` / `input_image`),设置严格的 `gateway.http.endpoints.responses.files.urlAllowlist` 和 `gateway.http.endpoints.responses.images.urlAllowlist`,并保持 `maxUrlParts` 较低。空允许列表会被视为未设置;如果你想完全禁用 URL 抓取,请使用 `files.allowUrl: false` / `images.allowUrl: false`。 -- 对于 OpenResponses 文件输入,解码后的 `input_file` 文本仍会作为**不可信外部内容**注入。不要仅仅因为 Gateway 网关在本地解码了文件文本,就认为它是可信的。即使此路径省略了更长的 `SECURITY NOTICE:` 横幅,注入的块仍会携带显式 `<<>>` 边界标记以及 `Source: External` 元数据。 -- 当媒体理解在把文本追加到媒体提示之前从附加文档中提取文本时,也会应用同样基于标记的包装。 +- 对于 OpenResponses 文件输入,解码后的 `input_file` 文本仍会作为**不可信外部内容**注入。不要仅因为 Gateway 网关在本地解码了文件文本,就认为它可信。注入块仍带有显式的 `<<>>` 边界标记以及 `Source: External` 元数据,尽管此路径会省略较长的 `SECURITY NOTICE:` 横幅。 +- 当媒体理解在把文本追加到媒体提示词之前从附加文档中提取文本时,也会应用同样的基于标记的封装。 - 为任何接触不可信输入的智能体启用沙箱隔离和严格工具允许列表。 -- 不要把密钥放入提示;改为通过 Gateway 网关主机上的环境变量/配置传递。 +- 不要把密钥放入提示词;而是在 Gateway 网关主机上通过环境变量/配置传递它们。 ### 自托管 LLM 后端 -OpenAI 兼容的自托管后端,例如 vLLM、SGLang、TGI、LM Studio,或自定义 Hugging Face tokenizer 栈,在处理聊天模板特殊 token 的方式上可能与托管提供商不同。如果后端将用户内容中的 `<|im_start|>`、`<|start_header_id|>` 或 `` 等字面字符串 tokenizer 化为结构化聊天模板 token,不可信文本就可能尝试在 tokenizer 层伪造角色边界。 +OpenAI 兼容的自托管后端,例如 vLLM、SGLang、TGI、LM Studio,或自定义 Hugging Face tokenizer 栈,在处理聊天模板特殊 token 的方式上可能不同于托管提供商。如果某个后端会把 `<|im_start|>`、`<|start_header_id|>` 或 `` 这类字面字符串 token 化为用户内容内部的结构化聊天模板 token,那么不可信文本就可能尝试在 tokenizer 层伪造角色边界。 -OpenClaw 会在将包装后的外部内容发送到模型前,剥离常见模型族的特殊 token 字面量。保持启用外部内容包装,并在可用时优先使用会拆分或转义用户提供内容中特殊 token 的后端设置。OpenAI 和 Anthropic 等托管提供商已经应用自己的请求侧清理。 +OpenClaw 会在把封装的外部内容分发给模型之前,移除常见模型族的特殊 token 字面量。保持外部内容封装启用,并在可用时优先使用会拆分或转义用户提供内容中特殊 token 的后端设置。OpenAI 和 Anthropic 等托管提供商已经应用它们自己的请求侧清理。 -### 模型强度(安全注意事项) +### 模型强度(安全说明) -不同模型层级的提示注入抵抗力**并不**一致。较小/较便宜的模型通常更容易受到工具滥用和指令劫持,尤其是在对抗性提示下。 +提示注入抵抗力在不同模型层级之间**并不**一致。较小/较便宜的模型通常更容易受到工具误用和指令劫持影响,尤其是在对抗性提示下。 -对于启用工具的智能体或会读取不可信内容的智能体,较旧/较小模型的提示注入风险通常过高。不要在弱模型层级上运行这些工作负载。 +对于启用工具的智能体或会读取不可信内容的智能体,使用较旧/较小模型时的提示注入风险通常过高。不要在弱模型层级上运行这些工作负载。 建议: - 对任何可以运行工具或接触文件/网络的机器人,**使用最新一代、最佳层级模型**。 -- **不要对启用工具的智能体或不可信收件箱使用较旧/较弱/较小层级**;提示注入风险太高。 -- 如果必须使用较小模型,**缩小影响范围**(只读工具、强沙箱隔离、最少文件系统访问、严格允许列表)。 -- 运行小模型时,**为所有会话启用沙箱隔离**,并**禁用 web_search/web_fetch/browser**,除非输入受到严格控制。 -- 对于输入可信且无工具的纯聊天个人助手,较小模型通常可以接受。 +- **不要为启用工具的智能体或不可信收件箱使用较旧/较弱/较小的层级**;提示注入风险太高。 +- 如果必须使用较小模型,**降低影响范围**(只读工具、强沙箱隔离、最小文件系统访问、严格允许列表)。 +- 运行小模型时,**为所有会话启用沙箱隔离**,并且除非输入受到严格控制,否则**禁用 web_search/web_fetch/browser**。 +- 对于输入可信且没有工具的纯聊天个人助手,较小模型通常没问题。 ## 群组中的推理和详细输出 -`/reasoning`、`/verbose` 和 `/trace` 可能暴露内部推理、工具输出或插件诊断,这些内容并不适合公开渠道。在群组设置中,将它们视为**仅限调试**,除非明确需要,否则保持关闭。 +`/reasoning`、`/verbose` 和 `/trace` 可能暴露内部推理、工具输出或插件诊断信息,而这些内容本不应出现在公共渠道中。在群组设置中,将它们视为**仅用于调试**,除非明确需要,否则保持关闭。 指导: -- 在公开房间中保持禁用 `/reasoning`、`/verbose` 和 `/trace`。 +- 在公共房间中保持 `/reasoning`、`/verbose` 和 `/trace` 禁用。 - 如果启用它们,只在可信私信或严格受控的房间中启用。 -- 请记住:详细和 trace 输出可能包含工具参数、URL、插件诊断以及模型看到的数据。 +- 记住:详细和追踪输出可能包含工具参数、URL、插件诊断信息以及模型看到的数据。 ## 配置加固示例 ### 文件权限 -在 Gateway 网关主机上保持配置 + 状态私密: +在 Gateway 网关主机上保持配置 + 状态私有: -- `~/.openclaw/openclaw.json`: `600`(仅用户读/写) -- `~/.openclaw`: `700`(仅用户) +- `~/.openclaw/openclaw.json`:`600`(仅用户可读/写) +- `~/.openclaw`:`700`(仅用户) -`openclaw doctor` 可以发出警告并提供收紧这些权限的选项。 +`openclaw doctor` 可以警告并建议收紧这些权限。 ### 网络暴露(绑定、端口、防火墙) @@ -695,32 +693,32 @@ Gateway 网关在单个端口上复用 **WebSocket + HTTP**: - 默认值:`18789` - 配置/标志/环境变量:`gateway.port`、`--port`、`OPENCLAW_GATEWAY_PORT` -此 HTTP 表面包括 Control UI 和 canvas host: +此 HTTP 表面包括控制 UI 和画布主机: -- Control UI(SPA 资源)(默认基础路径 `/`) -- Canvas host:`/__openclaw__/canvas/` 和 `/__openclaw__/a2ui/`(任意 HTML/JS;视为不可信内容) +- 控制 UI(SPA 资源)(默认基础路径 `/`) +- 画布主机:`/__openclaw__/canvas/` 和 `/__openclaw__/a2ui/`(任意 HTML/JS;视为不可信内容) -如果你在普通浏览器中加载 canvas 内容,请像对待任何其他不可信网页一样对待它: +如果你在普通浏览器中加载画布内容,请像对待任何其他不可信网页一样处理: -- 不要将 canvas host 暴露给不可信网络/用户。 -- 除非你完全理解其影响,否则不要让 canvas 内容与特权 web 表面共享同一源。 +- 不要将画布主机暴露给不可信网络/用户。 +- 除非你完全理解其影响,否则不要让画布内容与特权 Web 表面共享同一来源。 绑定模式控制 Gateway 网关监听的位置: - `gateway.bind: "loopback"`(默认):只有本地客户端可以连接。 -- 非 loopback 绑定(`"lan"`、`"tailnet"`、`"custom"`)会扩大攻击面。仅在使用 Gateway 网关认证(共享 token/密码或正确配置的可信代理)和真实防火墙时使用它们。 +- 非 loopback 绑定(`"lan"`、`"tailnet"`、`"custom"`)会扩大攻击面。只有在使用 Gateway 网关认证(共享 token/密码或正确配置的可信代理)和真实防火墙时才使用它们。 -经验规则: +经验法则: - 优先使用 Tailscale Serve,而不是 LAN 绑定(Serve 会让 Gateway 网关保持在 loopback 上,由 Tailscale 处理访问)。 -- 如果必须绑定到 LAN,请用防火墙将端口限制到严格的源 IP 允许列表;不要广泛端口转发。 -- 绝不要在 `0.0.0.0` 上无认证地暴露 Gateway 网关。 +- 如果必须绑定到 LAN,请通过防火墙将端口限制到严格的源 IP 允许列表;不要大范围做端口转发。 +- 切勿在 `0.0.0.0` 上未认证地暴露 Gateway 网关。 ### 使用 UFW 发布 Docker 端口 -如果你在 VPS 上用 Docker 运行 OpenClaw,请记住,发布的容器端口(`-p HOST:CONTAINER` 或 Compose `ports:`)会通过 Docker 的转发链路由,而不只是主机 `INPUT` 规则。 +如果你在 VPS 上用 Docker 运行 OpenClaw,请记住,已发布的容器端口(`-p HOST:CONTAINER` 或 Compose `ports:`)会通过 Docker 的转发链路路由,而不只是主机 `INPUT` 规则。 -为了让 Docker 流量与你的防火墙策略保持一致,请在 `DOCKER-USER` 中执行规则(此链会在 Docker 自身的 accept 规则之前求值)。在许多现代发行版上,`iptables`/`ip6tables` 使用 `iptables-nft` 前端,并且仍会把这些规则应用到 nftables 后端。 +为了让 Docker 流量与你的防火墙策略保持一致,请在 `DOCKER-USER` 中强制执行规则(此链会在 Docker 自己的 accept 规则之前求值)。在许多现代发行版上,`iptables`/`ip6tables` 使用 `iptables-nft` 前端,并且仍会把这些规则应用到 nftables 后端。 最小允许列表示例(IPv4): @@ -741,9 +739,9 @@ Gateway 网关在单个端口上复用 **WebSocket + HTTP**: COMMIT ``` -IPv6 有单独的表。如果启用了 Docker IPv6,请在 `/etc/ufw/after6.rules` 中添加匹配策略。 +IPv6 使用单独的表。如果启用了 Docker IPv6,请在 `/etc/ufw/after6.rules` 中添加匹配策略。 -避免在文档片段中硬编码 `eth0` 等接口名称。接口名称会因 VPS 镜像而异(`ens3`、`enp*` 等),不匹配可能会意外跳过你的拒绝规则。 +避免在文档片段中硬编码 `eth0` 这类接口名称。不同 VPS 镜像中的接口名称各不相同(`ens3`、`enp*` 等),不匹配可能导致意外跳过你的拒绝规则。 重新加载后的快速验证: @@ -754,21 +752,21 @@ ip6tables -S DOCKER-USER nmap -sT -p 1-65535 --open ``` -预期的外部端口应仅包含你有意暴露的端口(对于大多数设置:SSH + 你的反向代理端口)。 +预期的外部端口应当只有你有意暴露的端口(对大多数设置而言:SSH + 你的反向代理端口)。 ### mDNS/Bonjour 设备发现 -Gateway 网关会通过 mDNS(端口 5353 上的 `_openclaw-gw._tcp`)广播其存在,用于本地设备发现。在完整模式下,这包括可能暴露运行细节的 TXT 记录: +Gateway 网关通过 mDNS(端口 5353 上的 `_openclaw-gw._tcp`)广播自身存在,用于本地设备发现。在完整模式下,这包括可能暴露操作细节的 TXT 记录: - `cliPath`:CLI 二进制文件的完整文件系统路径(会暴露用户名和安装位置) - `sshPort`:公布主机上的 SSH 可用性 - `displayName`、`lanHost`:主机名信息 -**操作安全考虑:** 广播基础设施细节会让本地网络上的任何人更容易进行侦察。即使是像文件系统路径和 SSH 可用性这样的“无害”信息,也会帮助攻击者描绘你的环境。 +**运维安全注意事项:** 广播基础设施细节会让本地网络上的任何人更容易进行侦察。即使是像文件系统路径和 SSH 可用性这样的“无害”信息,也会帮助攻击者摸清你的环境。 **建议:** -1. **最小模式**(默认,推荐用于暴露的 Gateway 网关):从 mDNS 广播中省略敏感字段: +1. **最小模式**(默认,建议用于暴露的 Gateway 网关):从 mDNS 广播中省略敏感字段: ```json5 { @@ -798,19 +796,19 @@ Gateway 网关会通过 mDNS(端口 5353 上的 `_openclaw-gw._tcp`)广播 } ``` -4. **环境变量**(替代方式):设置 `OPENCLAW_DISABLE_BONJOUR=1`,无需修改配置即可禁用 mDNS。 +4. **环境变量**(替代方式):设置 `OPENCLAW_DISABLE_BONJOUR=1` 可在不改配置的情况下禁用 mDNS。 -在最小模式下,Gateway 网关仍会广播足够用于设备发现的信息(`role`、`gatewayPort`、`transport`),但会省略 `cliPath` 和 `sshPort`。需要 CLI 路径信息的应用可以改为通过已认证的 WebSocket 连接获取它。 +在最小模式下,Gateway 网关仍会广播足够用于设备发现的信息(`role`、`gatewayPort`、`transport`),但会省略 `cliPath` 和 `sshPort`。需要 CLI 路径信息的应用可以改为通过已通过身份验证的 WebSocket 连接获取它。 -### 锁定 Gateway 网关 WebSocket(本地认证) +### 锁定 Gateway 网关 WebSocket(本地身份验证) -Gateway 网关认证**默认必需**。如果没有配置有效的 Gateway 网关认证路径, -Gateway 网关会拒绝 WebSocket 连接(失败关闭)。 +Gateway 网关身份验证**默认必需**。如果没有配置有效的 Gateway 网关身份验证路径, +Gateway 网关会拒绝 WebSocket 连接(失败即关闭)。 -新手引导默认会生成一个令牌(即使是 loopback),因此 -本地客户端必须认证。 +新手引导默认会生成一个令牌(即使用于 loopback),因此 +本地客户端必须进行身份验证。 -设置一个令牌,让**所有** WS 客户端都必须认证: +设置一个令牌,让**所有** WS 客户端都必须进行身份验证: ```json5 { @@ -823,149 +821,150 @@ Gateway 网关会拒绝 WebSocket 连接(失败关闭)。 Doctor 可以为你生成一个:`openclaw doctor --generate-gateway-token`。 -`gateway.remote.token` 和 `gateway.remote.password` 是客户端凭证来源。它们本身**不会**保护本地 WS 访问。本地调用路径只能在未设置 `gateway.auth.*` 时,将 `gateway.remote.*` 用作回退。如果 `gateway.auth.token` 或 `gateway.auth.password` 通过 SecretRef 显式配置但未能解析,解析会失败关闭(不会被远程回退掩盖)。 +`gateway.remote.token` 和 `gateway.remote.password` 是客户端凭证来源。它们本身**不会**保护本地 WS 访问。本地调用路径只有在未设置 `gateway.auth.*` 时才能使用 `gateway.remote.*` 作为回退。如果 `gateway.auth.token` 或 `gateway.auth.password` 通过 SecretRef 显式配置但未解析成功,解析会失败即关闭(不会用远程回退掩盖)。 可选:使用 `wss://` 时,通过 `gateway.remote.tlsFingerprint` 固定远程 TLS。 -明文 `ws://` 默认仅限 loopback。对于受信任的私有网络 -路径,可在客户端进程上设置 `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` 作为 -应急开关。这有意仅作为进程环境变量,而不是 +明文 `ws://` 默认仅限 loopback。对于可信私有网络 +路径,请在客户端进程上设置 `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1` 作为 +应急手段。这有意仅限进程环境,而不是 `openclaw.json` 配置键。 -移动配对以及 Android 手动或扫码的 Gateway 网关路由更严格: -loopback 可接受明文,但私有 LAN、链路本地、`.local` 和 -无点主机名必须使用 TLS,除非你显式选择启用受信任的 +移动端配对以及 Android 手动或扫码 Gateway 网关路由更严格: +loopback 接受明文,但私有 LAN、链路本地、`.local` 和 +无点主机名必须使用 TLS,除非你明确选择启用可信 私有网络明文路径。 本地设备配对: -- 对直接 local loopback 连接会自动批准设备配对,以保持 - 同主机客户端流畅。 -- OpenClaw 还有一个狭窄的后端/容器本地自连接路径,用于 - 受信任的共享密钥辅助流程。 -- Tailnet 和 LAN 连接(包括同主机 tailnet 绑定)会被视为 - 远程连接进行配对,仍然需要批准。 -- loopback 请求上的转发头证据会取消 loopback +- 对直接 local loopback 连接,设备配对会自动批准,以保持 + 同主机客户端顺畅。 +- OpenClaw 还有一个很窄的后端/容器本地自连接路径,用于 + 可信共享密钥辅助流程。 +- Tailnet 和 LAN 连接,包括同主机 tailnet 绑定,都会被视为 + 远程配对,仍然需要批准。 +- loopback 请求上的转发标头证据会取消 loopback 本地性资格。元数据升级自动批准的范围很窄。请参阅 [Gateway 网关配对](/zh-CN/gateway/pairing)了解这两条规则。 -认证模式: +身份验证模式: -- `gateway.auth.mode: "token"`:共享 bearer 令牌(推荐用于大多数设置)。 -- `gateway.auth.mode: "password"`:密码认证(建议通过环境变量设置:`OPENCLAW_GATEWAY_PASSWORD`)。 -- `gateway.auth.mode: "trusted-proxy"`:信任具备身份感知能力的反向代理来认证用户,并通过请求头传递身份(请参阅[受信任代理认证](/zh-CN/gateway/trusted-proxy-auth))。 +- `gateway.auth.mode: "token"`:共享 bearer 令牌(建议用于大多数设置)。 +- `gateway.auth.mode: "password"`:密码身份验证(建议通过环境设置:`OPENCLAW_GATEWAY_PASSWORD`)。 +- `gateway.auth.mode: "trusted-proxy"`:信任具备身份感知能力的反向代理来验证用户,并通过标头传递身份(参阅[可信代理身份验证](/zh-CN/gateway/trusted-proxy-auth))。 轮换清单(令牌/密码): -1. 生成/设置一个新密钥(`gateway.auth.token` 或 `OPENCLAW_GATEWAY_PASSWORD`)。 -2. 重启 Gateway 网关(如果 macOS 应用负责监管 Gateway 网关,则重启该应用)。 +1. 生成/设置新的密钥(`gateway.auth.token` 或 `OPENCLAW_GATEWAY_PASSWORD`)。 +2. 重启 Gateway 网关(如果由 macOS 应用托管 Gateway 网关,则重启 macOS 应用)。 3. 更新所有远程客户端(调用 Gateway 网关的机器上的 `gateway.remote.token` / `.password`)。 -4. 验证旧凭证已无法再连接。 +4. 验证旧凭证已无法连接。 -### Tailscale Serve 身份请求头 +### Tailscale Serve 身份标头 -当 `gateway.auth.allowTailscale` 为 `true`(Serve 默认值)时,OpenClaw -会接受 Tailscale Serve 身份请求头(`tailscale-user-login`),用于控制 -UI/WebSocket 认证。OpenClaw 会通过本地 Tailscale 守护进程(`tailscale whois`)解析 -`x-forwarded-for` 地址,并将其与请求头匹配,从而验证身份。这只会在请求命中 loopback -且包含由 Tailscale 注入的 `x-forwarded-for`、`x-forwarded-proto` 和 `x-forwarded-host` -时触发。 -对于这条异步身份检查路径,在限流器记录失败之前,同一 `{scope, ip}` 的失败尝试会被串行化。因此,来自同一个 Serve 客户端的并发错误重试可能会立即锁定第二次尝试, -而不是作为两个普通不匹配请求竞争通过。 +当 `gateway.auth.allowTailscale` 为 `true`(Serve 的默认值)时,OpenClaw +接受 Tailscale Serve 身份标头(`tailscale-user-login`)用于控制 +UI/WebSocket 身份验证。OpenClaw 会通过本地 Tailscale daemon(`tailscale whois`) +解析 `x-forwarded-for` 地址并将其与标头匹配,以验证该身份。 +这只会对命中 loopback 且包含由 Tailscale 注入的 `x-forwarded-for`、 +`x-forwarded-proto` 和 `x-forwarded-host` 的请求触发。 +对于这个异步身份检查路径,同一 `{scope, ip}` 的失败尝试会在限制器记录失败之前串行化。 +因此,来自一个 Serve 客户端的并发错误重试可能会立即锁定第二次尝试, +而不是像两个普通不匹配一样竞争通过。 HTTP API 端点(例如 `/v1/*`、`/tools/invoke` 和 `/api/channels/*`) -**不会**使用 Tailscale 身份请求头认证。它们仍会遵循 Gateway 网关配置的 -HTTP 认证模式。 +**不会**使用 Tailscale 身份标头身份验证。它们仍然遵循 Gateway 网关 +配置的 HTTP 身份验证模式。 重要边界说明: -- Gateway 网关 HTTP bearer 认证实际上是全有或全无的操作员访问权限。 -- 将能够调用 `/v1/chat/completions`、`/v1/responses` 或 `/api/channels/*` 的凭证视为该 Gateway 网关的全访问操作员密钥。 -- 在 OpenAI 兼容的 HTTP 表面上,共享密钥 bearer 认证会恢复完整的默认操作员作用域(`operator.admin`、`operator.approvals`、`operator.pairing`、`operator.read`、`operator.talk.secrets`、`operator.write`)以及用于 agent 轮次的所有者语义;更窄的 `x-openclaw-scopes` 值不会降低这条共享密钥路径的权限。 -- HTTP 上的逐请求作用域语义只在请求来自携带身份的模式时适用,例如受信任代理认证,或私有入口上的 `gateway.auth.mode="none"`。 -- 在这些携带身份的模式中,省略 `x-openclaw-scopes` 会回退到普通操作员默认作用域集;如果你想要更窄的作用域集,请显式发送该请求头。 -- `/tools/invoke` 遵循相同的共享密钥规则:令牌/密码 bearer 认证在那里也会被视为完整操作员访问权限,而携带身份的模式仍会遵循声明的作用域。 -- 不要与不受信任的调用方共享这些凭证;建议为每个信任边界使用单独的 Gateway 网关。 +- Gateway 网关 HTTP bearer 身份验证实际上是全有或全无的操作员访问权限。 +- 将能够调用 `/v1/chat/completions`、`/v1/responses` 或 `/api/channels/*` 的凭证视为该 Gateway 网关的完全访问操作员密钥。 +- 在 OpenAI 兼容的 HTTP 表面上,共享密钥 bearer 身份验证会恢复完整的默认操作员作用域(`operator.admin`、`operator.approvals`、`operator.pairing`、`operator.read`、`operator.talk.secrets`、`operator.write`)以及智能体轮次的所有者语义;更窄的 `x-openclaw-scopes` 值不会降低该共享密钥路径的权限。 +- HTTP 上的按请求作用域语义只适用于来自携带身份的模式的请求,例如可信代理身份验证,或私有入口上的 `gateway.auth.mode="none"`。 +- 在这些携带身份的模式中,省略 `x-openclaw-scopes` 会回退到普通操作员默认作用域集合;当你需要更窄的作用域集合时,请显式发送该标头。 +- `/tools/invoke` 遵循相同的共享密钥规则:令牌/密码 bearer 身份验证在这里也被视为完整操作员访问权限,而携带身份的模式仍会遵循声明的作用域。 +- 不要与不可信调用方共享这些凭证;建议按信任边界使用独立 Gateway 网关。 -**信任假设:** 无令牌 Serve 认证假设 Gateway 网关主机是受信任的。 -不要把它视为对抗恶意同主机进程的保护。如果不受信任的 +**信任假设:** 无令牌 Serve 身份验证假定 Gateway 网关主机是可信的。 +不要把它当作针对恶意同主机进程的保护。如果不可信 本地代码可能在 Gateway 网关主机上运行,请禁用 `gateway.auth.allowTailscale` -并要求使用 `gateway.auth.mode: "token"` 或 `"password"` 进行显式共享密钥认证。 +并要求使用 `gateway.auth.mode: "token"` 或 `"password"` 进行显式共享密钥身份验证。 -**安全规则:** 不要从你自己的反向代理转发这些请求头。如果 -你在 Gateway 网关前终止 TLS 或设置代理,请禁用 -`gateway.auth.allowTailscale`,并改用共享密钥认证(`gateway.auth.mode: -"token"` 或 `"password"`)或[受信任代理认证](/zh-CN/gateway/trusted-proxy-auth)。 +**安全规则:** 不要从你自己的反向代理转发这些标头。如果 +你在 Gateway 网关前终止 TLS 或做代理,请禁用 +`gateway.auth.allowTailscale`,并改用共享密钥身份验证(`gateway.auth.mode: +"token"` 或 `"password"`)或[可信代理身份验证](/zh-CN/gateway/trusted-proxy-auth)。 -受信任代理: +可信代理: - 如果你在 Gateway 网关前终止 TLS,请将 `gateway.trustedProxies` 设置为你的代理 IP。 -- OpenClaw 会信任来自这些 IP 的 `x-forwarded-for`(或 `x-real-ip`),以确定用于本地配对检查和 HTTP 认证/本地检查的客户端 IP。 +- OpenClaw 会信任来自这些 IP 的 `x-forwarded-for`(或 `x-real-ip`),以确定用于本地配对检查和 HTTP 身份验证/本地检查的客户端 IP。 - 确保你的代理**覆盖** `x-forwarded-for`,并阻止直接访问 Gateway 网关端口。 请参阅 [Tailscale](/zh-CN/gateway/tailscale) 和 [Web 概览](/zh-CN/web)。 -### 通过节点主机进行浏览器控制(推荐) +### 通过 node host 控制浏览器(推荐) -如果你的 Gateway 网关是远程的,但浏览器运行在另一台机器上,请在浏览器机器上运行一个**节点主机**, -并让 Gateway 网关代理浏览器操作(请参阅[浏览器工具](/zh-CN/tools/browser))。 -将节点配对视为管理员访问权限。 +如果你的 Gateway 网关是远程的,但浏览器运行在另一台机器上,请在浏览器机器上运行一个 **node host**, +并让 Gateway 网关代理浏览器操作(参阅[浏览器工具](/zh-CN/tools/browser))。 +将 node 配对视为管理员访问权限。 推荐模式: -- 将 Gateway 网关和节点主机保留在同一个 tailnet(Tailscale)上。 -- 有意配对该节点;如果不需要浏览器代理路由,请禁用它。 +- 将 Gateway 网关和 node host 保持在同一个 tailnet(Tailscale)上。 +- 有意配对该 node;如果不需要浏览器代理路由,请将其禁用。 避免: -- 在 LAN 或公共互联网中暴露中继/控制端口。 -- 将 Tailscale Funnel 用于浏览器控制端点(公共暴露)。 +- 通过 LAN 或公网暴露中继/控制端口。 +- 将 Tailscale Funnel 用于浏览器控制端点(公开暴露)。 ### 磁盘上的密钥 假设 `~/.openclaw/`(或 `$OPENCLAW_STATE_DIR/`)下的任何内容都可能包含密钥或私有数据: - `openclaw.json`:配置可能包含令牌(Gateway 网关、远程 Gateway 网关)、提供商设置和允许列表。 -- `credentials/**`:渠道凭证(例如 WhatsApp 凭证)、配对允许列表、旧版 OAuth 导入。 -- `agents//agent/auth-profiles.json`:API 密钥、令牌配置、OAuth 令牌,以及可选的 `keyRef`/`tokenRef`。 -- `agents//agent/codex-home/**`:每个 agent 的 Codex 应用服务器账号、配置、Skills、插件、原生线程状态和诊断信息。 -- `secrets.json`(可选):由 `file` SecretRef 提供商(`secrets.providers`)使用的文件后端密钥载荷。 +- `credentials/**`:渠道凭证(示例:WhatsApp 凭证)、配对允许列表、旧版 OAuth 导入。 +- `agents//agent/auth-profiles.json`:API key、令牌配置、OAuth 令牌,以及可选的 `keyRef`/`tokenRef`。 +- `agents//agent/codex-home/**`:每个智能体的 Codex app-server 账户、配置、Skills、插件、原生线程状态和诊断信息。 +- `secrets.json`(可选):由 `file` SecretRef 提供商(`secrets.providers`)使用的文件后备密钥载荷。 - `agents//agent/auth.json`:旧版兼容文件。发现静态 `api_key` 条目时会将其清除。 -- `agents//sessions/**`:会话转录(`*.jsonl`)+ 路由元数据(`sessions.json`),其中可能包含私密消息和工具输出。 -- 内置插件包:已安装的插件(以及它们的 `node_modules/`)。 -- `sandboxes/**`:工具沙箱工作区;可能会积累你在沙箱内读写过的文件副本。 +- `agents//sessions/**`:会话转录(`*.jsonl`)+ 路由元数据(`sessions.json`),可能包含私密消息和工具输出。 +- 内置插件包:已安装插件(以及它们的 `node_modules/`)。 +- `sandboxes/**`:工具沙箱工作区;可能积累你在沙箱内读写过的文件副本。 加固建议: -- 严格限制权限(目录使用 `700`,文件使用 `600`)。 +- 保持严格权限(目录 `700`,文件 `600`)。 - 在 Gateway 网关主机上使用全盘加密。 -- 如果主机是共享的,建议为 Gateway 网关使用专用 OS 用户账号。 +- 如果主机是共享的,建议为 Gateway 网关使用专用 OS 用户账户。 ### 工作区 `.env` 文件 -OpenClaw 会为 agents 和工具加载工作区本地 `.env` 文件,但绝不会允许这些文件静默覆盖 Gateway 网关运行时控制。 +OpenClaw 会为智能体和工具加载工作区本地 `.env` 文件,但绝不会让这些文件静默覆盖 Gateway 网关运行时控制项。 -- 任何以 `OPENCLAW_*` 开头的键都会被阻止从不受信任的工作区 `.env` 文件加载。 -- Matrix、Mattermost、IRC 和 Synology Chat 的渠道端点设置也会被阻止通过工作区 `.env` 覆盖,因此克隆的工作区无法通过本地端点配置重定向内置连接器流量。端点环境变量键(例如 `MATRIX_HOMESERVER`、`MATTERMOST_URL`、`IRC_HOST`、`SYNOLOGY_CHAT_INCOMING_URL`)必须来自 Gateway 网关进程环境或 `env.shellEnv`,而不是来自工作区加载的 `.env`。 -- 该阻止机制是失败关闭的:未来版本新增的运行时控制变量无法从已签入或攻击者提供的 `.env` 继承;该键会被忽略,Gateway 网关保留自己的值。 -- 受信任的进程/OS 环境变量(Gateway 网关自己的 shell、launchd/systemd 单元、应用包)仍然适用——这只限制 `.env` 文件加载。 +- 任何以 `OPENCLAW_*` 开头的键都会被不可信工作区 `.env` 文件阻止。 +- Matrix、Mattermost、IRC 和 Synology Chat 的渠道端点设置也会被阻止通过工作区 `.env` 覆盖,因此克隆的工作区不能通过本地端点配置重定向内置连接器流量。端点环境变量键(例如 `MATRIX_HOMESERVER`、`MATTERMOST_URL`、`IRC_HOST`、`SYNOLOGY_CHAT_INCOMING_URL`)必须来自 Gateway 网关进程环境或 `env.shellEnv`,而不是来自工作区加载的 `.env`。 +- 阻止策略是失败即关闭:未来版本中新增的运行时控制变量不能从已签入或攻击者提供的 `.env` 继承;该键会被忽略,Gateway 网关会保留自己的值。 +- 可信进程/OS 环境变量(Gateway 网关自己的 shell、launchd/systemd 单元、应用包)仍然适用 — 这只限制 `.env` 文件加载。 -原因:工作区 `.env` 文件经常与 agent 代码相邻,可能被意外提交,或由工具写入。阻止整个 `OPENCLAW_*` 前缀意味着以后添加新的 `OPENCLAW_*` 标志时,绝不会退化为从工作区状态静默继承。 +原因:工作区 `.env` 文件经常与智能体代码放在一起,可能被意外提交,或由工具写入。阻止整个 `OPENCLAW_*` 前缀意味着以后添加新的 `OPENCLAW_*` 标志时,永远不会退化为从工作区状态静默继承。 ### 日志和转录(脱敏与保留) -即使访问控制正确,日志和转录也可能泄漏敏感信息: +即使访问控制正确,日志和转录也可能泄露敏感信息: - Gateway 网关日志可能包含工具摘要、错误和 URL。 - 会话转录可能包含粘贴的密钥、文件内容、命令输出和链接。 建议: -- 保持日志和转录脱敏开启(`logging.redactSensitive: "tools"`;默认值)。 +- 保持日志和转录脱敏开启(`logging.redactSensitive: "tools"`;默认)。 - 通过 `logging.redactPatterns` 为你的环境添加自定义模式(令牌、主机名、内部 URL)。 - 共享诊断信息时,建议使用 `openclaw status --all`(可粘贴,密钥已脱敏),而不是原始日志。 - 如果不需要长期保留,请清理旧会话转录和日志文件。 -详情:[日志](/zh-CN/gateway/logging) +详情:[日志记录](/zh-CN/gateway/logging) -### 私信:默认配对 +### 私信:默认通过配对 ```json5 { @@ -973,7 +972,7 @@ OpenClaw 会为 agents 和工具加载工作区本地 `.env` 文件,但绝不 } ``` -### 群组:所有位置都要求提及 +### 群组:任何地方都要求提及 ```json { @@ -999,27 +998,27 @@ OpenClaw 会为 agents 和工具加载工作区本地 `.env` 文件,但绝不 ### 单独号码(WhatsApp、Signal、Telegram) -对于基于电话号码的渠道,建议将你的 AI 运行在与你个人号码不同的单独电话号码上: +对于基于电话号码的渠道,考虑让你的 AI 使用一个不同于个人号码的独立电话号码: - 个人号码:你的对话保持私密 -- Bot 号码:由 AI 处理这些对话,并设置适当边界 +- 机器人号码:AI 处理这些对话,并设置适当边界 ### 只读模式(通过沙箱和工具) -你可以通过组合以下配置构建只读配置文件: +你可以通过组合以下内容构建只读配置: - `agents.defaults.sandbox.workspaceAccess: "ro"`(或使用 `"none"` 表示无工作区访问权限) - 阻止 `write`、`edit`、`apply_patch`、`exec`、`process` 等的工具允许/拒绝列表。 其他加固选项: -- `tools.exec.applyPatch.workspaceOnly: true`(默认):确保即使沙箱隔离关闭,`apply_patch` 也不能在工作区目录之外写入/删除。仅当你有意希望 `apply_patch` 触及工作区之外的文件时,才设置为 `false`。 -- `tools.fs.workspaceOnly: true`(可选):将 `read`/`write`/`edit`/`apply_patch` 路径和原生提示图片自动加载路径限制在工作区目录内(如果你当前允许绝对路径,并希望有一条统一防护栏,这很有用)。 +- `tools.exec.applyPatch.workspaceOnly: true`(默认):确保即使沙箱隔离关闭,`apply_patch` 也不能在工作区目录之外写入/删除。仅当你有意让 `apply_patch` 触及工作区之外的文件时,才设置为 `false`。 +- `tools.fs.workspaceOnly: true`(可选):将 `read`/`write`/`edit`/`apply_patch` 路径以及原生提示词图片自动加载路径限制到工作区目录(如果你当前允许绝对路径,并想要一个统一的防护栏,这会很有用)。 - 保持文件系统根目录范围狭窄:避免为智能体工作区/沙箱工作区使用像你的主目录这样的宽泛根目录。宽泛根目录可能会把敏感本地文件(例如 `~/.openclaw` 下的状态/配置)暴露给文件系统工具。 ### 安全基线(复制/粘贴) -一个“安全默认”配置示例,可让 Gateway 网关保持私有、要求私信配对,并避免常驻群组 bot: +一个“安全默认值”配置,会保持 Gateway 网关私有、要求私信配对,并避免常驻群组机器人: ```json5 { @@ -1038,69 +1037,71 @@ OpenClaw 会为 agents 和工具加载工作区本地 `.env` 文件,但绝不 } ``` -如果你也希望工具执行“默认更安全”,请为任何非所有者智能体添加沙箱,并拒绝危险工具(示例见下文“按智能体访问配置文件”)。 +如果你也希望工具执行“默认更安全”,请为任何非所有者智能体添加沙箱,并拒绝危险工具(示例见下文“按智能体划分的访问配置”)。 -聊天驱动智能体轮次的内置基线:非所有者发送者不能使用 `cron` 或 `gateway` 工具。 +聊天驱动的智能体轮次的内置基线:非所有者发送者不能使用 `cron` 或 `gateway` 工具。 ## 沙箱隔离(推荐) 专门文档:[沙箱隔离](/zh-CN/gateway/sandboxing) -两种互补方式: +两种互补方法: - **在 Docker 中运行完整 Gateway 网关**(容器边界):[Docker](/zh-CN/install/docker) - **工具沙箱**(`agents.defaults.sandbox`,主机 Gateway 网关 + 沙箱隔离工具;Docker 是默认后端):[沙箱隔离](/zh-CN/gateway/sandboxing) -为防止跨智能体访问,请将 `agents.defaults.sandbox.scope` 保持为 `"agent"`(默认),或使用 `"session"` 获得更严格的按会话隔离。`scope: "shared"` 使用单个容器或工作区。 +为防止跨智能体访问,请将 `agents.defaults.sandbox.scope` 保持为 `"agent"`(默认)或使用 `"session"` 实现更严格的按会话隔离。`scope: "shared"` 使用单个容器或工作区。 -还应考虑沙箱内的智能体工作区访问: +还要考虑沙箱内的智能体工作区访问权限: -- `agents.defaults.sandbox.workspaceAccess: "none"`(默认)让智能体工作区不可访问;工具会在 `~/.openclaw/sandboxes` 下的沙箱工作区运行 +- `agents.defaults.sandbox.workspaceAccess: "none"`(默认)让智能体工作区不可访问;工具会针对 `~/.openclaw/sandboxes` 下的沙箱工作区运行 - `agents.defaults.sandbox.workspaceAccess: "ro"` 将智能体工作区以只读方式挂载到 `/agent`(禁用 `write`/`edit`/`apply_patch`) -- `agents.defaults.sandbox.workspaceAccess: "rw"` 将智能体工作区以读/写方式挂载到 `/workspace` -- 额外的 `sandbox.docker.binds` 会基于规范化和标准化后的源路径进行校验。父级符号链接技巧和标准主目录别名在解析到受阻根目录(如 `/etc`、`/var/run` 或操作系统主目录下的凭证目录)时,仍会默认失败关闭。 +- `agents.defaults.sandbox.workspaceAccess: "rw"` 将智能体工作区以读写方式挂载到 `/workspace` +- 额外的 `sandbox.docker.binds` 会根据规范化和标准化后的源路径进行验证。如果父级符号链接技巧和标准主目录别名解析到被阻止的根目录(如 `/etc`、`/var/run` 或 OS 主目录下的凭据目录),仍会以失败关闭方式处理。 -`tools.elevated` 是全局基线逃生口,会在沙箱之外运行 exec。有效主机默认是 `gateway`,或在 exec 目标配置为 `node` 时为 `node`。保持 `tools.elevated.allowFrom` 严格,不要为陌生人启用它。你还可以通过 `agents.list[].tools.elevated` 按智能体进一步限制提权。参见[提权模式](/zh-CN/tools/elevated)。 +`tools.elevated` 是在沙箱外运行 exec 的全局基线逃生口。有效主机默认是 `gateway`,当 exec 目标配置为 `node` 时则为 `node`。请严格限制 `tools.elevated.allowFrom`,不要为陌生人启用它。你还可以通过 `agents.list[].tools.elevated` 按智能体进一步限制提升权限。参见[提升权限模式](/zh-CN/tools/elevated)。 ### 子智能体委派防护栏 -如果你允许会话工具,请将委派的子智能体运行视为另一个边界决策: +如果你允许会话工具,请把委派的子智能体运行视为另一个边界决策: -- 拒绝 `sessions_spawn`,除非智能体确实需要委派。 -- 将 `agents.defaults.subagents.allowAgents` 和任何按智能体的 `agents.list[].subagents.allowAgents` 覆盖限制为已知安全的目标智能体。 +- 拒绝 `sessions_spawn`,除非该智能体确实需要委派。 +- 将 `agents.defaults.subagents.allowAgents` 以及任何按智能体设置的 `agents.list[].subagents.allowAgents` 覆盖限制为已知安全的目标智能体。 - 对于任何必须保持沙箱隔离的工作流,调用 `sessions_spawn` 时使用 `sandbox: "require"`(默认是 `inherit`)。 - 当目标子运行时未被沙箱隔离时,`sandbox: "require"` 会快速失败。 ## 浏览器控制风险 -启用浏览器控制会让模型具备驱动真实浏览器的能力。 -如果该浏览器配置文件已经包含已登录会话,模型就能访问这些账户和数据。 -请将浏览器配置文件视为**敏感状态**: +启用浏览器控制会让模型能够驱动真实浏览器。 +如果该浏览器配置文件已经包含已登录会话,模型就能 +访问这些账户和数据。请将浏览器配置文件视为**敏感状态**: -- 优先为智能体使用专用配置文件(默认 `openclaw` 配置文件)。 -- 避免将智能体指向你的个人日常使用配置文件。 -- 除非你信任沙箱隔离智能体,否则保持主机浏览器控制关闭。 -- 独立的 loopback 浏览器控制 API 仅遵循共享密钥认证(Gateway 网关令牌 bearer auth 或 Gateway 网关密码)。它不会使用 trusted-proxy 或 Tailscale Serve 身份标头。 +- 优先为智能体使用专用配置文件(默认的 `openclaw` 配置文件)。 +- 避免让智能体指向你的个人日常使用配置文件。 +- 除非你信任沙箱隔离的智能体,否则保持主机浏览器控制禁用。 +- 独立 local loopback 浏览器控制 API 只支持共享密钥认证 + (Gateway 网关 token bearer 认证或 Gateway 网关密码)。它不会使用 + trusted-proxy 或 Tailscale Serve 身份标头。 - 将浏览器下载内容视为不可信输入;优先使用隔离的下载目录。 - 如果可能,在智能体配置文件中禁用浏览器同步/密码管理器(降低影响范围)。 -- 对远程 Gateway 网关,假设“浏览器控制”等同于对该配置文件可访问内容的“操作者访问权限”。 -- 保持 Gateway 网关和节点主机仅 tailnet 可访问;避免将浏览器控制端口暴露到 LAN 或公共互联网。 -- 不需要时禁用浏览器代理路由(`gateway.nodes.browser.mode="off"`)。 -- Chrome MCP 现有会话模式**并不**“更安全”;它可以在该主机 Chrome 配置文件可访问的任何位置以你的身份操作。 +- 对于远程 Gateway 网关,假设“浏览器控制”等同于对该配置文件可访问内容的“操作者访问权限”。 +- 保持 Gateway 网关和节点主机仅限 tailnet;避免将浏览器控制端口暴露给 LAN 或公网。 +- 不需要浏览器代理路由时将其禁用(`gateway.nodes.browser.mode="off"`)。 +- Chrome MCP 现有会话模式**并不**“更安全”;它可以在该主机 Chrome 配置文件可访问的任何地方以你的身份操作。 ### 浏览器 SSRF 策略(默认严格) -OpenClaw 的浏览器导航策略默认严格:私有/内部目标会保持阻止,除非你明确选择加入。 +OpenClaw 的浏览器导航策略默认严格:除非你显式选择加入,否则私有/内部目标会保持阻止状态。 - 默认:`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 未设置,因此浏览器导航会继续阻止私有/内部/特殊用途目标。 -- 旧版别名:为兼容性仍接受 `browser.ssrfPolicy.allowPrivateNetwork`。 +- 旧别名:`browser.ssrfPolicy.allowPrivateNetwork` 为兼容性仍会被接受。 - 选择加入模式:设置 `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true` 以允许私有/内部/特殊用途目标。 -- 在严格模式下,使用 `hostnameAllowlist`(如 `*.example.com` 这样的模式)和 `allowedHostnames`(精确主机例外,包括像 `localhost` 这样的受阻名称)来设置显式例外。 -- 导航会在请求前检查,并在导航后的最终 `http(s)` URL 上尽力再次检查,以减少基于重定向的跳转。 +- 在严格模式下,使用 `hostnameAllowlist`(例如 `*.example.com` 这样的模式)和 `allowedHostnames`(精确主机例外,包括像 `localhost` 这样的被阻止名称)来设置显式例外。 +- 导航会在请求前检查,并在导航完成后的最终 `http(s)` URL 上尽力重新检查,以减少基于重定向的枢轴攻击。 严格策略示例: @@ -1116,11 +1117,11 @@ OpenClaw 的浏览器导航策略默认严格:私有/内部目标会保持阻 } ``` -## 按智能体访问配置文件(多智能体) +## 按智能体划分的访问配置(多智能体) -使用多智能体路由时,每个智能体都可以拥有自己的沙箱 + 工具策略: -用它为每个智能体提供**完全访问权限**、**只读**或**无访问权限**。 -完整详情和优先级规则见[多智能体沙箱与工具](/zh-CN/tools/multi-agent-sandbox-tools)。 +通过多智能体路由,每个智能体都可以拥有自己的沙箱 + 工具策略: +用它为每个智能体提供**完全访问**、**只读**或**无访问**。 +完整详情和优先级规则请参见[多智能体沙箱与工具](/zh-CN/tools/multi-agent-sandbox-tools)。 常见用例: @@ -1225,33 +1226,33 @@ OpenClaw 的浏览器导航策略默认严格:私有/内部目标会保持阻 ### 遏制 -1. **停止它:**停止 macOS 应用(如果它负责监管 Gateway 网关)或终止你的 `openclaw gateway` 进程。 +1. **停止它:**停止 macOS 应用(如果它负责监管 Gateway 网关),或终止你的 `openclaw gateway` 进程。 2. **关闭暴露面:**设置 `gateway.bind: "loopback"`(或禁用 Tailscale Funnel/Serve),直到你弄清发生了什么。 -3. **冻结访问:**将高风险私信/群组切换为 `dmPolicy: "disabled"` / 要求提及,并移除你此前设置的 `"*"` 全允许条目。 +3. **冻结访问:**将有风险的私信/群组切换为 `dmPolicy: "disabled"` / 要求提及,并移除你曾设置的 `"*"` 全允许条目。 -### 轮换(如果密钥泄露则假设已被攻破) +### 轮换(如果密钥泄露,则假定已被攻破) 1. 轮换 Gateway 网关认证(`gateway.auth.token` / `OPENCLAW_GATEWAY_PASSWORD`)并重启。 -2. 在任何能够调用 Gateway 网关的机器上轮换远程客户端密钥(`gateway.remote.token` / `.password`)。 -3. 轮换提供商/API 凭证(WhatsApp 凭证、Slack/Discord 令牌、`auth-profiles.json` 中的模型/API key,以及使用时的加密密钥载荷值)。 +2. 在任何可以调用 Gateway 网关的机器上轮换远程客户端密钥(`gateway.remote.token` / `.password`)。 +3. 轮换提供商/API 凭据(WhatsApp 凭据、Slack/Discord token、`auth-profiles.json` 中的模型/API key,以及使用时的加密 secrets payload 值)。 ### 审计 1. 检查 Gateway 网关日志:`/tmp/openclaw/openclaw-YYYY-MM-DD.log`(或 `logging.file`)。 2. 审查相关转录记录:`~/.openclaw/agents//sessions/*.jsonl`。 -3. 审查最近的配置变更(任何可能扩大访问范围的内容:`gateway.bind`、`gateway.auth`、私信/群组策略、`tools.elevated`、插件变更)。 +3. 审查最近的配置更改(任何可能扩大访问面的内容:`gateway.bind`、`gateway.auth`、私信/群组策略、`tools.elevated`、插件更改)。 4. 重新运行 `openclaw security audit --deep`,并确认严重发现已解决。 -### 收集报告材料 +### 收集报告资料 -- 时间戳、Gateway 网关主机操作系统 + OpenClaw 版本 +- 时间戳、Gateway 网关主机 OS + OpenClaw 版本 - 会话转录记录 + 简短日志尾部(脱敏后) - 攻击者发送了什么 + 智能体做了什么 - Gateway 网关是否暴露到 loopback 之外(LAN/Tailscale Funnel/Serve) ## 密钥扫描 -CI 会在仓库上运行 pre-commit `detect-private-key` 钩子。如果它 +CI 会在仓库上运行 pre-commit 的 `detect-private-key` 钩子。如果它 失败,请移除或轮换已提交的密钥材料,然后在本地复现: ```bash @@ -1260,8 +1261,8 @@ pre-commit run --all-files detect-private-key ## 报告安全问题 -在 OpenClaw 中发现漏洞?请负责任地报告: +发现 OpenClaw 中的漏洞?请负责任地报告: -1. 邮箱:[security@openclaw.ai](mailto:security@openclaw.ai) +1. 电子邮件:[security@openclaw.ai](mailto:security@openclaw.ai) 2. 修复前不要公开发布 3. 我们会致谢你(除非你希望匿名)