跳转至

Auth 与设备身份

客户端如何证明自身身份:握手认证路径、设备身份与配对签名,以及 TLS 钉扎。

身份验证

所有者页面:网关身份验证 — 认证模式、令牌/密码设置,以及本线协议所执行的面向运维人员的策略。

  • 共享密钥网关认证接受在 connect.params.auth.token 或 connect.params.auth.password 中提供的已配置密钥。 gateway.auth.mode: "token" 选择 gateway.auth.token;"password" 选择 gateway.auth.password。该模式选择的是已配置的密钥, 而非必需的线字段。
  • 携带身份的认证模式,例如 Tailscale Serve(gateway.auth.allowTailscale: true) 或非回环 gateway.auth.mode: "trusted-proxy",通过请求头而非 connect.params.auth.* 满足连接认证检查。
  • 私有入口 gateway.auth.mode: "none" 完全跳过共享密钥连接认证; 请勿在公共/不可信入口上暴露该模式。
  • 配对完成后,网关会签发一个设备令牌,其范围限定为连接 角色 + 已批准的授权,并通过 hello-ok.auth.deviceToken 返回。客户端应在成功连接后、 当令牌是新的或与已存储令牌不同时,将其与 hello-ok.auth.scopes 一起持久化。
  • hello-ok.auth.scopes 是当前套接字的实时权限,并且与 RPC 分派所执行的权限范围一致。
  • 当 hello-ok.auth.deviceToken 与已为同一网关、设备、客户端和角色存储的令牌完全匹配时, 保留该记录中已存储的权限范围,而不是用更窄的实时权限集替换它们。 新签发或轮换的令牌使用 hello-ok.auth.scopes;其批准的授权在该令牌签发时 与该连接匹配。
  • 使用已存储的设备令牌重连时,也应复用该令牌已存储的已批准权限范围。 这样可以保留已授予的读取/探测/状态访问权限,并避免静默地将重连收窄到 隐式的仅管理员范围。
  • 客户端侧连接认证组装(selectConnectAuth,位于 packages/gateway-client/src/client.ts):
  • 当设置时,auth.password 始终被转发。任一共享密钥字段 都可以携带已配置的密钥;当两者都提供时,网关 使用与其认证模式匹配的字段。
  • auth.token 按优先级顺序填充:先显式共享令牌, 然后显式 deviceToken,然后是已存储的按设备令牌(以 deviceId + role 为键)。
  • 仅当以上各项都未能解析出 auth.token 时,才会发送 auth.bootstrapToken。共享令牌或任何已解析的设备令牌都会抑制它。
  • 在一次性 AUTH_TOKEN_MISMATCH 重试中自动提升已存储的设备令牌, 仅限受信任端点:回环,或带有钉扎 tlsFingerprint 的 wss://。 未钉扎的公共 wss:// 不符合条件。
  • 内置设置码引导会返回主节点 hello-ok.auth.deviceToken,并在 hello-ok.auth.deviceTokens 中返回一个有界的操作员令牌,用于受信任的移动端交接。该操作员令牌 包含 operator.talk.secrets 以进行原生 Talk 配置读取,但 排除配对变更权限范围和 operator.admin。
  • hello-ok.auth.deviceTokens 仅包含额外的引导交接令牌。 不要将其用作主 deviceToken 重连记录的元数据。
  • 当非基线设置码引导等待批准时, PAIRING_REQUIRED 的详细信息包含 recommendedNextStep: "wait_then_retry"、 retryable: true 和 pauseReconnect: false。继续使用相同的 引导令牌重连,直到请求被批准或令牌失效。
  • 仅当连接在受信任传输(例如 wss:// 或回环/本地配对)上使用引导 认证时,才持久化 hello-ok.auth.deviceTokens。
  • 如果客户端提供了显式的 deviceToken 或显式的 scopes, 该调用方请求的权限范围对实时连接仍然具有权威性,并会在 hello-ok.auth.scopes 中报告;缓存的令牌授权范围仅在客户端复用 已存储的按设备令牌时被重用。
  • 设备令牌可以通过 device.token.rotate 和 device.token.revoke 轮换/撤销(需要 operator.pairing)。轮换或撤销 节点或其他非操作员角色还需要 operator.admin。
  • device.token.rotate 返回轮换元数据。仅对已使用该设备令牌认证的 同设备调用回显替换承载令牌,因此仅凭令牌的客户端可以在重连 之前持久化其替换令牌。共享/管理员轮换不回显承载令牌。
  • 令牌签发、轮换和撤销始终限定在该设备配对条目中记录的已批准角色 集合内;令牌变更不能扩展或针对配对批准从未授予的设备角色。
  • 对于已配对设备的令牌会话,除非调用方同时拥有 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 (packages/gateway-protocol/src/connect-error-details.ts)。
  • 针对 AUTH_TOKEN_MISMATCH 的客户端行为:
  • 受信任客户端可以尝试一次有界的重试,使用缓存的按设备 令牌。
  • 如果该重试失败,停止自动重连循环,并呈现操作员 操作指南。
  • AUTH_SCOPE_MISMATCH 表示设备令牌已被识别,但 未覆盖所请求的角色/权限范围。不要将其呈现为错误令牌;提示 操作员重新配对或批准更窄/更宽的权限范围契约。
  • OPERATOR_ACCESS_DENIED 表示人员已认证,但网关的 操作员访问策略(例如绑定到 accessPolicyPlugin 的角色) 当前未授予任何访问权限。这不是凭据问题。继续带退避地 重连,以便新授予的访问权限无需用户操作即可生效,并显示 管理员指南以分配角色或授予访问权限。

设备身份与配对

所属页面:网关配对 — 这些字段背后的审批流程、设备记录和 CLI 界面。

  • 节点应包含从密钥对指纹派生的稳定设备身份(device.id)。
  • 网关会为每个设备 + 角色颁发 Token。
  • 除非启用了本地自动批准,否则新的设备 ID 需要配对批准。
  • 如果批准与重连重叠,网关会在完成握手前检查当前已配对的设备。已批准的密钥、角色、scopes 和固定的客户端元数据必须授权该连接;仅凭一个已消费的请求并不授予访问权限。
  • 配对自动批准主要针对直接本地回环连接。
  • OpenClaw 还有一个狭窄的后端/容器本地自连接路径,用于受信任的共享密钥辅助流程。
  • 同一主机上的 tailnet 或 LAN 连接在配对时仍被视为远程,并且需要批准。
  • WS 客户端通常在 connect 期间包含 device 身份(operator + node)。唯一无设备的 operator 例外是显式信任路径:
  • 成功的 gateway.auth.mode: "trusted-proxy" operator Control UI 认证。
  • 保留的内部辅助路径上直接回环的 gateway-client 后端 RPC。
  • 省略设备身份会产生 scope 影响。当无设备的 operator 连接通过显式信任路径被允许时,除非该路径具有命名的 scope 保留例外,否则 OpenClaw 仍会将自声明的 scopes 清空为空集。随后,受 scope 限制的方法会以 missing scope 失败。
  • 保留的直接回环 gateway-client 后端辅助路径仅为内部本地控制平面 RPC 保留 scopes;自定义后端 ID 不会获得此例外。
  • 所有连接都必须对服务器提供的 connect.challenge nonce 进行签名。

设备认证迁移诊断

对于仍使用挑战前签名行为的旧版客户端,connect 会在 error.details.code 下返回 DEVICE_AUTH_* 详情代码,并带有稳定的 error.details.reason。

常见迁移失败:

消息 details.code details.reason 含义
device nonce required DEVICE_AUTH_NONCE_REQUIRED device-nonce-missing 客户端省略了 device.nonce(或发送了空值)。
device nonce mismatch DEVICE_AUTH_NONCE_MISMATCH device-nonce-mismatch 客户端使用了过期/错误的 nonce 进行签名。
device signature invalid DEVICE_AUTH_SIGNATURE_INVALID device-signature 签名载荷与 v2 载荷不匹配。
device signature expired DEVICE_AUTH_SIGNATURE_EXPIRED device-signature-stale 签名时间戳超出了允许的偏差范围。
device identity mismatch DEVICE_AUTH_DEVICE_ID_MISMATCH device-id-mismatch device.id 与公钥指纹不匹配。
device public key invalid DEVICE_AUTH_PUBLIC_KEY_INVALID device-public-key 公钥格式/规范化失败。

迁移目标:

  • 始终等待 connect.challenge。
  • 将 connect.challenge.payload.ts 用作 connect.params.device.signedAt。
  • 对包含服务器 nonce 的 v2 载荷进行签名。
  • 在 connect.params.device.nonce 中发送相同的 nonce。
  • 首选签名载荷是 v3 (位于 packages/gateway-client/src/device-auth.ts 中的 buildDeviceAuthPayloadV3), 除 device/client/role/scopes/token/nonce 字段外,它还绑定 platform 和 deviceFamily。
  • 旧版 v2 签名出于兼容性仍被接受,但已配对设备的元数据固定仍会在重连时控制命令策略。

TLS 与证书固定

所属页面:远程访问 — 配置 gateway.tls 并获取客户端固定的指纹。

  • WS 连接支持 TLS(gateway.tls 配置)。
  • 客户端可选择通过 gateway.remote.tlsFingerprint 或 CLI --tls-fingerprint 固定网关证书指纹。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw