Clawnet 重构(协议 + 认证统一)

Clawnet 重构(协议 + 认证统一)

适用范围

在以下情况使用此页面:

  • 为节点 + 操作员客户端规划统一的网络协议
  • 跨设备重新设计审批、配对、TLS 和在线状态

背景

本文档概述了一个拟议的重构,用于跨设备统一协议、认证、审批和身份。

目的

单一、严谨的文档,用于:

  • 当前状态:协议、流程、信任边界。
  • 痛点:审批、多跳路由、UI 重复。
  • 拟议的新状态:一个协议、范围限定角色、统一认证/配对、TLS 绑定。
  • 身份模型:稳定 ID + 可爱的别名。
  • 迁移计划、风险、未解决的问题。

目标

  • 所有客户端(mac 应用、CLI、iOS、Android、无头节点)使用一个协议。
  • 每个网络参与者都已认证 + 已配对。
  • 角色清晰:节点 vs 操作员。
  • 中心审批路由到用户所在位置。
  • 所有远程流量使用 TLS 加密 + 可选绑定。
  • 最小代码重复。
  • 单台机器应只出现一次(无 UI/节点重复条目)。

非目标(明确)

  • 移除能力分离(仍需要最小权限)。
  • 在没有范围检查的情况下暴露完整的网关控制平面。
  • 使认证依赖于人工标签(别名仍然非安全)。

当前状态(现状)

两个协议

1) 网关 WebSocket(控制平面)

  • 完整的 API 表面:配置、频道、模型、会话、智能体运行、日志、节点等。
  • 默认绑定:回环。通过 SSH/Tailscale 远程访问。
  • 认证:通过 connect 的令牌/密码。
  • 无 TLS 绑定(依赖回环/隧道)。
  • 代码:
    • src/gateway/server/ws-connection/message-handler.ts
    • src/gateway/client.ts
    • docs/gateway/protocol.md

2) 桥接(节点传输)

  • 窄允许列表表面,节点身份 + 配对。
  • TCP 上的 JSONL;可选 TLS + 证书指纹绑定。
  • TLS 在发现 TXT 中通告指纹。
  • 代码:
    • src/infra/bridge/server/connection.ts
    • src/gateway/server-bridge.ts
    • src/node-host/bridge-client.ts
    • docs/gateway/bridge-protocol.md

今天的控制平面客户端

  • CLI → 网关 WS 通过 callGatewaysrc/gateway/call.ts)。
  • macOS 应用 UI → 网关 WS(GatewayConnection)。
  • Web 控制 UI → 网关 WS。
  • ACP → 网关 WS。
  • 浏览器控制使用自己的 HTTP 控制服务器。

今天的节点

  • 节点模式下的 macOS 应用连接到网关桥接(MacNodeBridgeSession)。
  • iOS/Android 应用连接到网关桥接。
  • 配对 + 每节点令牌存储在网关上。

当前审批流程(exec)

  • 智能体通过网关使用 system.run
  • 网关通过桥接调用节点。
  • 节点运行时决定审批。
  • mac 应用显示 UI 提示(当 node == mac 应用时)。
  • 节点向网关返回 invoke-res
  • 多跳,UI 绑定到节点主机。

今天的在线状态 + 身份

  • 来自 WS 客户端的网关在线状态条目。
  • 来自桥接的节点在线状态条目。
  • mac 应用可以为同一台机器显示两个条目(UI + 节点)。
  • 节点身份存储在配对存储中;UI 身份分离。

问题 / 痛点

  • 需要维护两个协议栈(WS + Bridge)。
  • 远程节点上的审批:提示出现在节点主机上,而不是用户所在位置。
  • TLS 绑定仅存在于桥接;WS 依赖 SSH/Tailscale。
  • 身份重复:同一台机器显示为多个实例。
  • 角色模糊:UI + 节点 + CLI 功能没有清晰分离。

拟议的新状态(Clawnet)

一个协议,两个角色

带有角色 + 范围的单一 WS 协议。

  • 角色:node(能力主机)
  • 角色:operator(控制平面)
  • 操作员的可选范围
    • operator.read(状态 + 查看)
    • operator.write(智能体运行、发送)
    • operator.admin(配置、频道、模型)

角色行为

节点

  • 可以注册能力(capscommands、permissions)。
  • 可以接收 invoke 命令(system.runcamera.*canvas.*screen.record 等)。
  • 可以发送事件:voice.transcriptagent.requestchat.subscribe
  • 不能调用 config/models/channels/sessions/agent 控制平面 API。

操作员

  • 完整的控制平面 API,受范围限制。
  • 接收所有审批。
  • 不直接执行 OS 操作;路由到节点。

关键规则

角色是按连接的,不是按设备的。设备可以分别打开两个角色。


统一认证 + 配对

客户端身份

每个客户端提供:

  • deviceId(稳定,从设备密钥派生)。
  • displayName(人类名称)。
  • role + scope + caps + commands

配对流程(统一)

  • 客户端未认证连接。
  • 网关为该 deviceId 创建配对请求
  • 操作员接收提示;批准/拒绝。
  • 网关颁发绑定到以下内容的凭据:
    • 设备公钥
    • 角色
    • 范围
    • 能力/命令
  • 客户端持久化令牌,重新连接已认证。

设备绑定认证(避免不记名令牌重放)

首选:设备密钥对。

  • 设备生成一次密钥对。
  • deviceId = fingerprint(publicKey)
  • 网关发送随机数;设备签名;网关验证。
  • 令牌颁发给公钥(拥有证明),而不是字符串。

替代方案:

  • mTLS(客户端证书):最强,更多运维复杂性。
  • 短期不记名令牌仅作为临时阶段(轮换 + 早期撤销)。

静默审批(SSH 启发式)

精确定义以避免薄弱环节。首选:

  • 仅本地:当客户端通过回环/Unix 套接字连接时自动配对。
  • 通过 SSH 挑战:网关发布随机数;客户端通过获取来证明 SSH。
  • 物理存在窗口:在网关主机 UI 上本地批准后,允许短时间窗口(例如 10 分钟)内自动配对。

始终记录 + 记录自动审批。


无处不在的 TLS(开发 + 生产)

重用现有的桥接 TLS

使用当前的 TLS 运行时 + 指纹绑定:

  • src/infra/bridge/server/tls.ts
  • src/node-host/bridge-client.ts 中的指纹验证逻辑

应用于 WS

  • WS 服务器支持具有相同证书/密钥 + 指纹的 TLS。
  • WS 客户端可以绑定指纹(可选)。
  • 发现为所有端点通告 TLS + 指纹。
    • 发现仅是定位器提示;绝不是信任锚。

为什么

  • 减少对 SSH/Tailscale 进行保密的依赖。
  • 使远程移动连接默认安全。

审批重新设计(中心化)

当前

审批发生在节点主机(mac 应用节点运行时)。提示出现在节点运行的位置。

拟议

审批是网关托管的,UI 交付给操作员客户端。

新流程

  1. 网关接收 system.run 意图(智能体)。
  2. 网关创建审批记录:approval.requested
  3. 操作员 UI 显示提示。
  4. 审批决策发送到网关:approval.resolve
  5. 如果批准,网关调用节点命令。
  6. 节点执行,返回 invoke-res

审批语义(硬化)

  • 广播到所有操作员;只有活动的 UI 显示模态(其他获得通知)。
  • 第一个解决方案获胜;网关拒绝后续解决方案为已解决。
  • 默认超时:N 秒后拒绝(例如 60s),记录原因。
  • 解决方案需要 operator.approvals 范围。

好处

  • 提示出现在用户所在位置(mac/手机)。
  • 远程节点的一致审批。
  • 节点运行时保持无头;无 UI 依赖。

角色清晰度示例

iPhone 应用

  • 节点角色用于:麦克风、摄像头、语音聊天、位置、按键通话。
  • 可选的 operator.read 用于状态和聊天查看。
  • 仅在明确启用时才使用可选的 operator.write/admin

macOS 应用

  • 默认操作员角色(控制 UI)。
  • 启用"Mac 节点"时的节点角色(system.run、屏幕、摄像头)。
  • 两个连接使用相同的 deviceId → 合并的 UI 条目。

CLI

  • 始终是操作员角色。
  • 范围由子命令派生:
    • statuslogs → read
    • agentmessage → write
    • configchannels → admin
    • 审批 + 配对 → operator.approvals / operator.pairing

身份 + 别名

稳定 ID

认证所需;永不更改。 首选:

  • 密钥对指纹(公钥哈希)。

可爱别名(龙虾主题)

仅人类标签。

  • 示例:scarlet-clawsaltwavemantis-pinch
  • 存储在网关注册表中,可编辑。
  • 碰撞处理:-2-3

UI 分组

跨角色的相同 deviceId → 单个"实例"行:

  • 徽章:operatornode
  • 显示能力 + 最后可见时间。

迁移策略

阶段 0:文档 + 对齐

  • 发布此文档。
  • 清单所有协议调用 + 审批流程。

阶段 1:向 WS 添加角色/范围

  • 使用 rolescopedeviceId 扩展 connect 参数。
  • 为节点角色添加允许列表门控。

阶段 2:桥接兼容性

  • 保持桥接运行。
  • 并行添加 WS 节点支持。
  • 在配置标志后门控功能。

阶段 3:中心审批

  • 在 WS 中添加审批请求 + 解决事件。
  • 更新 mac 应用 UI 以提示 + 响应。
  • 节点运行时停止提示 UI。

阶段 4:TLS 统一

  • 使用桥接 TLS 运行时为 WS 添加 TLS 配置。
  • 向客户端添加绑定。

阶段 5:弃用桥接

  • 将 iOS/Android/mac 节点迁移到 WS。
  • 保持桥接作为后备;一旦稳定就移除。

阶段 6:设备绑定认证

  • 要求所有非本地连接使用基于密钥的身份。
  • 添加撤销 + 轮换 UI。

安全说明

  • 角色/允许列表在网关边界强制执行。
  • 没有客户端在没有操作员范围的情况下获得"完整"API。
  • 所有连接都需要配对。
  • TLS + 绑定减少移动设备的 MITM 风险。
  • SSH 静默审批是一种便利;仍然记录 + 可撤销。
  • 发现绝不是信任锚。
  • 能力声明由平台/类型根据服务器允许列表进行验证。

流式传输 + 大负载(节点媒体)

WS 控制平面对于小消息来说很好,但节点也做:

  • 摄像头片段
  • 屏幕录制
  • 音频流

选项:

  1. WS 二进制帧 + 分块 + 反压规则。
  2. 单独的流式端点(仍然是 TLS + 认证)。
  3. 为媒体密集型命令更长时间地保持桥接,最后迁移。

在实现之前选择一个以避免漂移。

能力 + 命令策略

  • 节点报告的 caps/commands 被视为声明
  • 网关强制执行每个平台的允许列表。
  • 任何新命令需要操作员审批或明确的允许列表更改。
  • 使用时间戳审计更改。

审计 + 速率限制

  • 日志:配对请求、审批/拒绝、令牌颁发/轮换/撤销。
  • 速率限制配对垃圾邮件和审批提示。

协议卫生

  • 明确的协议版本 + 错误代码。
  • 重新连接规则 + 心跳策略。
  • 在线状态 TTL 和最后可见性语义。

未解决的问题

  1. 运行两个角色的单个设备:令牌模型

    • 建议每个角色使用单独的令牌(node vs operator)。
    • 相同的 deviceId;不同的范围;更清晰的撤销。
  2. 操作员范围粒度

    • read/write/admin + approvals + pairing(最小可行)。
    • 稍后考虑每个功能的范围。
  3. 令牌轮换 + 撤销 UX

    • 角色更改时自动轮换。
    • 按 deviceId + role 撤销的 UI。
  4. 发现

    • 扩展当前的 Bonjour TXT 以包括 WS TLS 指纹 + 角色提示。
    • 仅视为定位器提示。
  5. 跨网络审批

    • 广播到所有操作员客户端;活动 UI 显示模态。
    • 第一个响应获胜;网关强制执行原子性。

总结(TL;DR)

  • 今天:WS 控制平面 + Bridge 节点传输。
  • 痛点:审批 + 重复 + 两个栈。
  • 提议:一个 WS 协议,具有明确的角色 + 范围、统一的配对 + TLS 绑定、网关托管的审批、稳定的设备 ID + 可爱的别名。
  • 结果:更简单的 UX、更强的安全性、更少的重复、更好的移动路由。