生成模型 :Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗 :输入 ~200,000 tokens,输出 ~15,000 tokens(本章合计)
Gateway 是 OpenClaw 系统的入口大门。任何客户端——无论是本地的 CLI、远程的 macOS 应用、还是浏览器中的 Web 控制台——都需要通过 Gateway 的认证才能访问系统。本节将深入分析 OpenClaw 的多层认证机制。
4.4.1 Gateway Token 认证
Token 认证是最基础的认证方式。它的原理很简单:Gateway 启动时配置一个密钥(Token),客户端连接时提供同样的密钥,匹配则通过。
src/gateway/auth.ts 中的 resolveGatewayAuth() 函数负责解析认证配置:
Copy // src/gateway/auth.ts
export type ResolvedGatewayAuth = {
mode : " token " | " password " ; // 认证模式
token ?: string ; // Token 值
password ?: string ; // 密码值
allowTailscale : boolean ; // 是否允许 Tailscale 认证
};
export function resolveGatewayAuth ( params : {
authConfig ?: GatewayAuthConfig | null ;
env ?: NodeJS . ProcessEnv ;
tailscaleMode ?: GatewayTailscaleMode ;
}) : ResolvedGatewayAuth {
const authConfig = params . authConfig ?? {};
const env = params . env ?? process . env ;
// Token 的来源优先级:配置文件 > OPENCLAW 环境变量 > CLAWDBOT 环境变量
const token =
authConfig . token ??
env . OPENCLAW_GATEWAY_TOKEN ??
env . CLAWDBOT_GATEWAY_TOKEN ??
undefined ;
// 密码的来源优先级:同上
const password =
authConfig . password ??
env . OPENCLAW_GATEWAY_PASSWORD ??
env . CLAWDBOT_GATEWAY_PASSWORD ??
undefined ;
// 模式推断:如果配置了 password 但没指定 mode,默认用 password 模式
const mode = authConfig . mode ?? ( password ? " password " : " token " ) ;
return { mode , token , password , allowTailscale };
} 注意 CLAWDBOT_GATEWAY_TOKEN 等环境变量——这是对旧版本(项目曾用名 ClawdBot)的向后兼容。在大型项目中,这种对旧配置名的兼容是非常常见的实践。
启动时,assertGatewayAuthConfigured() 确保认证已正确配置:
如果 Token 没有配置且不允许 Tailscale 认证,Gateway 会拒绝启动并给出清晰的错误提示。这是一种 Fail-Fast (快速失败)设计——宁可在启动时就发现问题,也不要在运行时出现安全漏洞。
当客户端发起 WebSocket 连接并发送 connect 消息后,Gateway 调用 authorizeGatewayConnect() 进行认证:
认证结果 GatewayAuthResult 包含认证方法信息:
注意 Token 比较使用了 safeEqual() 函数而非简单的 ===:
衍生解释 :timingSafeEqual(时间安全比较)是一种防止时序攻击 (Timing Attack)的技术。普通的字符串比较 === 在发现第一个不匹配的字符时就会返回 false,这意味着比较时间与"匹配了多少字符"成正比。攻击者可以通过精确测量比较时间来逐字符猜测密钥。
timingSafeEqual 无论字符串内容如何,都会花费恒定的时间 完成比较,从而消除了时序侧信道。这是 Node.js crypto 模块提供的标准安全原语。
isLocalDirectRequest() 函数用于判断请求是否来自本机:
这个函数的逻辑比看起来复杂,因为它需要防范伪造本地请求 的攻击:
IP 检查 :客户端 IP 必须是回环地址(127.0.0.1、::1 等)
Host 头检查 :请求的 Host 头必须指向本地(localhost、127.0.0.1)或 Tailscale 地址
代理检测 :如果存在 X-Forwarded-For 等代理头,只有当来源 IP 是受信代理时才认为是本地请求
为什么这么复杂?考虑以下攻击场景:恶意网页通过 JavaScript 向 http://localhost:18789 发起请求(跨站请求),如果 Gateway 只检查 IP 而不检查 Host 头和代理头,就可能被欺骗认为是"本地请求"并跳过认证。
4.4.2 设备配对(Device Pairing)机制
Token 认证适合受信环境(CLI、服务器端),但对于移动设备(iOS/Android),直接在设备上配置 Token 既不安全也不方便。OpenClaw 引入了设备配对 (Device Pairing)机制来解决这个问题。
衍生解释 :设备配对是一种在两个设备之间建立信任关系的过程,类似于蓝牙配对。核心思想是通过一个带外信道 (Out-of-Band Channel)——如显示在屏幕上的配对码——来验证双方身份,然后交换密钥建立持久的信任关系。
设备配对基于非对称密钥加密 (Public Key Cryptography):
设备在后续连接时需要对一段标准化的载荷进行签名。buildDeviceAuthPayload() 函数定义了载荷格式:
载荷使用管道符 | 分隔各字段,类似于 JWT 的载荷格式但更简单。注意几个安全设计:
签名时间戳 (signedAtMs):防止签名被无限期重用。服务器可以拒绝时间戳过旧的签名。
版本演进 :v2 版本增加了 nonce(随机数),用于防止重放攻击 ——即使攻击者截获了一个有效的签名,也无法重新使用它,因为每次连接的 nonce 不同。
衍生解释 :重放攻击(Replay Attack)是指攻击者截获一个合法的认证消息后,重新发送它来获得未授权的访问。这在网络安全中是一类经典攻击。对策包括时间戳(签名过期)、随机数(每次不同)、以及序列号(检测重复)。
回顾 ConnectParams 中的 device 字段:
Gateway 收到这些信息后:
使用存储的公钥验证 signature 是否与载荷匹配
4.4.3 本地连接自动批准 vs 远程连接挑战签名
OpenClaw 的认证策略根据连接来源有不同的宽严度:
当 isLocalDirectRequest() 返回 true 时(如 CLI 连接到本机的 Gateway),认证要求相对宽松:
本地 CLI 可以直接使用配置文件中的 Token
本地 Web 控制台可以通过 Origin 检查后免密访问
这是因为本地连接意味着攻击者需要已经获得了主机的访问权限,此时 Gateway 的认证已不是安全的主要防线。
对于来自网络的远程连接,认证更加严格:
设备必须已配对 :不能直接使用 Token(Token 可能在网络传输中泄露)
使用挑战-响应签名 :Gateway 可以发送一个随机挑战(nonce),设备必须用私钥签名后返回
Tailscale 验证 :如果通过 Tailscale VPN 连接,需要验证 Tailscale 用户身份
衍生解释 :挑战-响应认证(Challenge-Response Authentication)是一种经典的认证模式。服务器发送一个随机数(挑战),客户端用密钥对随机数进行加密或签名后返回(响应)。服务器验证响应是否正确。这种方式的好处是密钥本身永远不会在网络上传输。NTLM、CRAM-MD5、以及 SSH 的公钥认证都使用了类似的机制。
OpenClaw 对 Tailscale VPN 有特殊的集成支持。当 Gateway 以 Tailscale Serve 模式部署时,可以利用 Tailscale 的身份验证:
衍生解释 :Tailscale 是一个基于 WireGuard 的零配置 VPN 服务。它的 Serve 功能允许将本地服务暴露到 Tailscale 网络中,并自动为每个请求注入用户身份信息(通过 HTTP 头)。OpenClaw 利用这个特性实现了"通过 VPN 身份认证 Gateway"——如果你在 Tailscale 网络中,你就不需要单独配置 Token。
验证流程的多重校验(检查 HTTP 头 → 验证代理身份 → Whois API 交叉验证)是为了防止HTTP 头伪造 攻击——如果攻击者能够直接向 Gateway 发送请求并伪造 Tailscale-User-Login 头,没有 Whois 交叉验证的话就会绕过认证。
4.4.4 Origin 检查防止跨站 WebSocket 劫持
浏览器中的 WebSocket 连接面临一个特殊的安全威胁——跨站 WebSocket 劫持 (Cross-Site WebSocket Hijacking, CSWSH)。
衍生解释 :跨站 WebSocket 劫持是 CSRF(跨站请求伪造)在 WebSocket 场景下的变种。当用户在浏览器中同时打开了恶意网页和 OpenClaw 控制台时,恶意网页可以尝试建立到 ws://localhost:18789 的 WebSocket 连接。由于浏览器会自动携带 cookies,如果 Gateway 不检查请求来源,恶意网页就可能成功建立连接并控制用户的 AI 助手。
src/gateway/origin-check.ts 实现了 Origin 检查:
检查逻辑遵循最小特权原则 ,按以下顺序判断:
Origin 头必须存在 :浏览器在发起跨站请求时总是会附带 Origin 头。如果没有 Origin 头,可能是非浏览器客户端(不需要 Origin 检查)或者 Origin 被代理剥离了。
白名单优先 :如果请求来源在配置的白名单中,直接通过。这允许管理员显式授权特定的外部来源。
同源策略 :如果 Origin 的主机部分与请求的 Host 头匹配(即同一个域名),则允许。这是标准的同源策略。
本地环回例外 :如果 Origin 和请求目标都是本地地址(localhost、127.0.0.1 等),则允许。这使得本地开发时 Web 控制台能正常工作,即使端口不同。
Origin 检查中用到的几个辅助函数处理了各种边界情况:
注意 parseOrigin 中对 "null" 字符串的处理——浏览器在某些情况下(如 file:// 协议页面)会发送 Origin: null(字面量字符串),这不应该被当作有效的 Origin。
让我们用一张表格总结 OpenClaw 的多层认证机制:
这些机制并不是互斥的,而是分层叠加 的:
OpenClaw 的认证系统设计体现了深度防御 (Defense in Depth)的安全原则:
多种认证方式 :Token、密码、设备配对、Tailscale——不同场景使用最合适的方式
时间安全比较 :使用 timingSafeEqual 防止时序攻击
设备配对的非对称密钥设计 :私钥永远不离开设备,通过签名验证身份
重放攻击防护 :v2 协议引入 nonce,时间戳限制签名有效期
Origin 检查 :针对浏览器环境的 CSWSH 防护
本章我们从协议设计哲学出发,逐层深入了 OpenClaw Gateway 的协议与类型系统:
4.1 协议设计哲学 :WebSocket 的选择理由、请求-响应-事件的混合帧模式、幂等键机制
4.2 TypeBox 类型模式 :单一定义多端复用的类型系统、JSON Schema 和 Swift 代码生成流水线
4.3 核心方法与事件 :80+ 个方法的功能分族、agent/send/sessions.* 等核心操作、18 种事件类型
4.4 认证与授权 :Token 认证、设备配对、Tailscale 集成、Origin 检查的多层安全机制
这套协议和类型系统是 OpenClaw 所有上层功能(会话、Agent、工具、通道等)的基础通信层。在接下来的章节中,我们将基于这些协议方法,深入分析 Gateway 之上的各个子系统的实现。