☰
VisionClaw 安全实践:访问码体系、HMAC 签名 State 与 OAuth 凭据保险库设计
2026/10/2 17:28:15 网站建设 项目流程

VisionClaw 安全实践:访问码体系、HMAC 签名 State 与 OAuth 凭据保险库设计

【免费下载链接】VisionClawReal-time AI assistant for Meta Ray-Ban smart glasses -- voice + vision + agentic actions via Gemini Live and OpenClaw项目地址: https://gitcode.com/gh_mirrors/vi/VisionClaw

VisionClaw 是一款运行在 Meta Ray-Ban 智能眼镜上的实时 AI 助手,靠语音 + 视觉 + 代理动作完成任务。正因为它能读你的日历、代发邮件、操作第三方应用,VisionClaw 安全设计成为整个系统的底座:网关层用访问码把守大门,用 HMAC 签名的 state 参数防伪造回调,把 OAuth 凭据统一锁进按用户隔离的保险库。本文带你从新手视角看懂这三道防线是怎么落地的。

上图给出了整体分层:眼镜端交给 Gemini Live 做实时感知,动作类任务委托给网关(OpenClaw)。所有敏感凭据都留在网关一侧,App 只拿到"够用的钥匙"——这正是下面三层防护的前提。

访问码体系:第一道门禁如何工作 🚪

首次启动 App,你会看到一屏"请输入访问码"。这里的访问码(access code)不是作者手动发放的口令,而是 App 所指向的那个网关签发的令牌:

  • 自托管网关在.env里设置GATEWAY_TOKENS="<你的密钥>:<你的用户名>",这个密钥就是你的访问码,解析逻辑见 gateway/src/config.ts。
  • App 端提交前会先向网关验证,验证通过才解锁,打错码会立刻提示"未被识别",见 AccessCodeScreen.kt。
  • 现在的主入口已升级为 Google 登录:访问码路径降级为"使用自建网关"的备选项,两条路径共用同一套令牌校验。

账号状态机:pending / approved / revoked 三级审批

网关给每个自注册账号维护一个状态字段,访问控制完全由它驱动:

状态行为
pending持有令牌,但除/me外所有接口视同无效令牌
approved正常放行(白名单邮箱域可自动批准)
revoked全部拒绝,凭据不再发放

审批接口仅限"服务令牌"调用,普通用户无法枚举他人账号,见 gateway/src/auth.ts。

令牌只存哈希,最多保留 5 个

每次登录签发的 bearer token 形如vc-+ 16 字节随机数;服务器只保存它的 SHA-256 哈希,原始令牌仅存在于设备端,且每个账号最多保留最近 5 个哈希——泄露存储文件也反推不出可用令牌,实现见 gateway/src/auth.ts。

HMAC 签名 State:如何让 OAuth 回调不可伪造 🔏

任何 OAuth 流程都绕不开state参数,VisionClaw 的做法在 gateway/src/auth.ts 与 gateway/src/connect.ts 中高度一致,核心是四步:

  1. 载荷签名:把{nonce, userId, appId, ts}做 base64url 编码,再用HMAC-SHA256计算 16 字节截断的 MAC,拼成body.mac两段式结构。
  2. 恒定时间比较:验证时用timingSafeEqual对比 MAC,杜绝时序侧信道攻击。
  3. 10 分钟 TTL:state 内嵌时间戳,过期即作废,防止链接被长期截留。
  4. 签名密钥兜底:未配置STATE_SECRET时自动退化为进程内随机密钥——重启会让进行中的登录失效,但保证了无配置环境下也不存在"无签名 state"攻击面(见 auth.ts 第 33-35 行)。

一次性 Nonce 停车机制:令牌绝不经过 URL 🚗

登录完成后,令牌并不走深链接回传(那样会留在浏览器历史里),而是"停"在网关内存中:

  • App 生成一个 16 字节随机 nonce,打开浏览器登录;
  • 回调成功时,网关把新令牌park到该 nonce 下;
  • App 端每 2 秒轮询/auth/exchange取回令牌,取走即删、二次请求返回 410(见 auth.ts 第 308-337 行);
  • 轮询接口还叠加了"每 IP 每分钟 60 次"的速率限制,防暴力枚举 nonce。

连接第三方应用(如 Notion、Slack)时,同样机制与PKCE(S256)结合:verifier 只活到回调那一刻,以签名 state 为键存取,见 connect.ts 第 372-385 行。

OAuth 凭据保险库:每个用户一个独立金库 💰

保险库按用户隔离,凭据按 MCP 地址索引

App 连接日历、Gmail、Notion、Slack 时,网关换取的 refresh token 并不落在本地 JSON 文件里,而是写入 Anthropic Cloud 提供的Vault(凭据保险库):

  • 首次使用即为该用户创建一个专属 vault(visionclaw-vault-<userId>),见 gateway/src/provision.ts;
  • 每条凭据以 MCP 服务器 URL 为键,重连即替换,避免同服务器累积多份过期凭据,见 gateway/src/connect.ts;
  • 后续 token 过期由 Anthropic 侧自动用保险库里的 refresh 配置续期,App 与网关都不持有长期刷新逻辑。

最小权限的 Scope 设计 🎯

申请权限严格遵循"够用就好",例如 gateway/src/apps.ts 中 Gmail 只申请gmail.readonly+gmail.send(汇总与代发邮件),刻意不申请修改标签、删除邮件的权限;日历同样只开放事件读写而非管理权限。

敏感配置永不出现在代码库

  • Google/Slack 的 client_id、client_secret 全部来自环境变量,未配置时对应应用自动隐藏(appAvailable检查);
  • LiveKit 的 API secret 只在网关进程内签名 15 分钟有效期的房间 JWT,App 拿到的只是短票,见 gateway/src/server.ts;
  • 本地 store 文件采用"先写临时文件再原子 rename"的方式落盘,避免半写状态,见 gateway/src/store.ts。

安全实践清单:部署自己的 VisionClaw 网关 📋

如果你想自托管一套网关,以下配置项与防护一一对应(完整说明见 gateway/README.md):

配置项防护目标
GATEWAY_TOKENS访问码体系,未设置时启动即告警
GATEWAY_SERVICE_TOKEN管理员/worker 专用令牌,同时兼任 state 签名密钥
STATE_SECRET登录/连接流程的 state 签名密钥,显式配置可跨重启保活
REGISTRATION_OPEN=false注册总开关(kill switch),随时关闭新账号
AUTO_APPROVE_DOMAINS仅放行白名单邮箱域,其余进入人工审批队列

给新手的 3 条要点:

  1. 访问码是"指向哪个网关、哪个网关说了算",自部署时它就是你的.env里那串密钥;
  2. 任何 OAuth 回调都先验 state 再换码,state 被篡改或过期都会直接 400;
  3. 凭据集中放在按用户隔离的保险库里,代码库与本地文件里找不到可用的 refresh token。

这套"访问码门禁 + 签名 state + 保险库凭据"的组合,让 VisionClaw 在替你动日历、发邮件的同时,把每把钥匙都锁在了对的地方 🔐。

【免费下载链接】VisionClawReal-time AI assistant for Meta Ray-Ban smart glasses -- voice + vision + agentic actions via Gemini Live and OpenClaw项目地址: https://gitcode.com/gh_mirrors/vi/VisionClaw

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询