docs/remote/protocol-v2.md,crates/core/src/remote_v2.rs 是 wire 层面的唯一事实源。本页只覆盖实现时必须遵守的边界。
两种配对路径
Vibex 有两条形式不同的配对路径,不要混用:<transport> 取值 direct、tailnet 或 self_hosted_relay。
offer 路径
- 桌面端身份在运行时 home 中生成,Unix 下以
0600权限保存。 - offer 可取消、只能使用一次,其消费与设备授权的创建在同一个 SQLite 事务中完成。
- offer 包含候选路线、桌面公钥、权限摘要、过期时间和一次性 challenge,不包含长期授权、密钥或工作区数据。
- 移动端在本地解析链接,异步处理前先剥离 fragment。
配对码路径
- 九位数字,按
NNN-NNN-NNN分组,由 UUIDv4 派生,只持久化它的 SHA-256 哈希。 - 客户端在
POST /api/v2/pairing/code/claim声明配对码;配对码只出现在请求体里,从不放进 URL,因此不会进入代理和访问日志。 - 该端点与其他未认证路由共享每对端限流和认证失败预算。
- 声明是一次性的:重复使用、格式错误或已过期会返回
remote_pairing_code_invalid/remote_pairing_code_expired,并写入pairing_code_rejected审计记录。 - 成功声明返回恰好一个设备授权,权限级别在创建配对码时确定。
连接串与证书固定
vibex://pair#/code/<payload> 的 payload 是一个 JSON 对象:
tlsCertificateDer 是可选的。证书随连接串带外传递(来自服务器控制台,而不是网络),客户端在发出第一个 TLS 请求之前就固定它,因此局域网自签场景不需要公共 CA。指纹格式为 sha256:<base64url(sha256(DER))>。
固定型链接必须是 https 且指向数值型局域网地址(loopback、RFC1918 或链路本地 / 唯一本地 IPv6),否则返回 remote_pairing_link_invalid。这是有意限制:配对不能变成绕过公网 CA 体系的手段。
服务器身份密钥与 TLS 证书分开固定,前者从 /api/v2/info 的 serverIdentityPublicKey 取得。
握手和密钥
实现使用 X25519、HKDF-SHA256、HMAC-SHA256 和 ChaCha20-Poly1305 等成熟原语。- 连接以
control/hello开始,收到control/server_info结束握手;协议使用范围协商,当前选择2.0。 - WebSocket ticket 有效期 30 秒、单次使用,通过受控 subprotocol 交换,不放在 URL 中。
- hello proof 绑定 ticket challenge、完整 hello transcript、服务器身份、session epoch、设备身份和客户端临时密钥。
server_info返回服务器临时密钥和会话密钥确认。
帧类型
未知的 client、control、JSON message、attachment、binary frame、timeout、close 和 transport 枚举值一律解码为
unknown;未知的活动消息以结构化协议原因关闭,而不是 panic。旧版 0.4 HTTP 与 /ws 路由是兼容端点,新客户端使用 /ws/v2。
RPC、事件和同步
所有业务操作都经过设备认证、权限和工作区授权。变更使用有界幂等键;文件操作额外使用内容修订 / CAS。 客户端发现序号或游标缺口时返回resync_required,并指向一个权威操作重新获取。附件流在开始前重新认证并授权其 domain;终端附件带工作区作用域,终端输入需 generation 检查、授权和审计,不保留原始字节。
设备授权撤销后,该设备的所有活动连接立即收到 device_revoked。运行时关闭时发送 server_shutdown,排空监听并释放 socket。
权限模型
RemoteDevicePermissionLevel 有三个取值,序列化为 read_only / approve_only / full_control:
级别在权威端创建 offer / 配对码时确定,客户端无法自行提权。
网关端点
Relay 约束
Relay 是一个零知识房间路由器:它只转发不透明加密帧,可以暴露/health、/api/info 和 WebSocket bridge 所需的路由元数据,但不执行业务授权、不读写工作区、不保存供应商配置或时间线。
Relay 上的端点是 /health、/api/info、/ws、/api/rooms/{room_id}/pair|command 和两个 /api/push/*。Relay 上没有 /api/v2/info——那是权威运行时的端点。
本地检查:
连接策略
客户端可以在 Direct、Tailnet、Relay 和局域网之间探测和回退。路线恢复后应重新探测并切换,不需要重复配对;如果设备已被撤销,任何路线都必须失败。部署
docs/smoke/relay-nat.md 与 docs/smoke/remote-lan.md。