Skip to content

04 · 连接、租户与认证

WebSocket 连接进入 Buzz 时,第一件事不是解析用户声称的社区,而是由 Relay 从请求 authority/host 解析 TenantContext。随后连接才进入 NIP-42 challenge/response、成员与封禁校验,并被登记到带社区标签的连接管理器中。

1. 连接生命周期

text
HTTP Upgrade

   ├─ resolve host → TenantContext
   ├─ origin / limits / connection rate checks

WebSocket split
   ├─ receive loop ──► protocol dispatcher
   ├─ send loop ◄──── bounded outbound queue
   ├─ heartbeat / idle timeout
   └─ cancellation / cleanup
          ├─ remove subscriptions
          ├─ release Redis topics
          └─ unregister connection

连接的接收、发送、心跳和 handler 并发都有界。这样慢消费者不会直接让全局 fan-out 无界积压;代价是队列满时必须定义丢弃、关闭或背压策略。

2. TenantContext 是类型围栏

TenantContext 的注释明确要求它只能由服务器侧 resolver 构造,并刻意不实现可让客户端 JSON 直接注入的反序列化/默认路径。其内部同时保存:

  • 规范化后的 host。
  • 对应 community UUID。
  • Relay URL authority 等派生信息。

规范化会处理大小写、端口与 authority 语义,避免 Example.comexample.com:443 等表示在缓存键或认证标签中变成不同租户。

关键边界

社区不能从 event tag、query 参数或客户端 body 中决定。那些值都可以由攻击者签名后提交;真正的 tenant 必须来自服务器控制的域名映射。

3. NIP-42 认证链

Relay 发送 challenge,客户端发布 kind 22242 认证事件。处理顺序可概括为:

text
challenge match + relay tag match

       event ID/signature verify

       community ban check

  optional pubkey allowlist check

 relay membership / NIP-OA owner path

 set AuthState + record connection pubkey

顺序很重要:先证明事件真实性,再访问主体信息;但“签名有效”不等于“有权进入社区”。

4. 封禁和 owning human 级联

认证 handler 在密码学通过后执行 fail-closed 封禁检查。对 Agent 不只检查 Agent 公钥,还解析 owning human:如果 owner 被封,关联 Agent 也不能绕过封禁继续连接。

这是 Buzz 把“可验证主体”与“可追责操作者”区分开的一个典型例子。

5. Relay 成员门

社区可配置成员制。认证主体需满足:

  • 已在 relay member 表中;或
  • 通过 NIP-OA owner/delegation 证明,触发允许的 owner materialization 路径;
  • 并且不在 allowlist/ban 等更严格策略的拒绝侧。

这些检查失败时倾向 fail closed:数据库/解析错误不会被降级成“临时允许”。对安全边界而言,可用性让位于隔离。

6. AuthContext 与 scopes

buzz-auth::AuthContext 统一表达:

字段用途
pubkey当前签名主体
scopesmessages/channels/users/files/repos/admin 等能力
channel_ids可选的能力约束范围
methodNIP-42、NIP-98、bearer 等认证方式
agent_owner_pubkeyAgent 与 owning human 的责任链

NIP-42 WebSocket 认证在完成社区门控后可获得已知 WS scopes;HTTP 接口更多使用 NIP-98 或 token,并按 endpoint 映射最小 scope。

7. NIP-98 与 HTTP

HTTP 请求签署 kind 27235 类 NIP-98 认证事件,绑定 URL、method,并可绑定 payload hash。Buzz 还在 Redis 中维护 replay guard,防同一认证事件在有效窗口内被重复使用。

典型用途包括:

  • CLI 的消息/频道/搜索 REST bridge。
  • Blossom 媒体上传。
  • Git smart HTTP credential helper。
  • Push lease/gateway 管理端点。

URL 规范化、代理头信任和 payload 绑定必须与部署拓扑一致;否则合法请求会误拒,或签名覆盖的 URL 与服务器实际授权资源不一致。

8. ConnectionManager 与社区注册表

进程内连接项带有 receiver、community 和可选已认证 pubkey。CommunityConnectionRegistry 让后台任务可以按社区运行并统一取消。它服务两类控制:

  • fan-out 时先用连接 tenant label 做第一道隔离。
  • 跨 pod 的封禁/成员变更可通过 Redis connection-control 消息要求相关连接重验或断开。

9. 限流边界

当前实现包含 Redis fixed-window limiter:Lua/INCR + EXPIRE 原子维护窗口计数。Relay 在多 pod 下共享限额,而不是每个 pod 各算一份。

它解决的是基础配额与滥用控制,不是精确公平调度:固定窗口在边界时可能出现双倍突发;Redis 不可用时的策略要按 endpoint 风险决定是否 fail closed。

10. 源码入口

独立源码研究笔记 · 非 Buzz 官方文档