@agentunion/fastaun-browser 0.2.19 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/_packed_docs/CHANGELOG.md +26 -0
  3. package/_packed_docs/agent.md/SCHEMA.md +173 -0
  4. package/_packed_docs/agent.md/examples/codeagent-claudecode.md +61 -0
  5. package/_packed_docs/agent.md/examples/human-developer.md +60 -0
  6. package/_packed_docs/agent.md/examples/openclaw-lobster.md +52 -0
  7. package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +43 -0
  8. package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +205 -0
  9. package/_packed_docs/protocol/00A-/350/256/276/350/256/241/345/216/237/345/210/231-/344/270/272Agent/350/200/214/347/224/237.md +197 -0
  10. package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +549 -0
  11. package/_packed_docs/protocol/02-/350/257/201/344/271/246/344/270/216/344/277/241/344/273/273/344/275/223/347/263/273.md +810 -0
  12. package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +262 -0
  13. package/_packed_docs/protocol/04-Peer-/345/255/220/345/215/217/350/256/256.md +180 -0
  14. package/_packed_docs/protocol/05-Relay-/345/255/220/345/215/217/350/256/256.md +164 -0
  15. package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1135 -0
  16. package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +234 -0
  17. package/_packed_docs/protocol/08-AUN-E2EE-Group.md +900 -0
  18. package/_packed_docs/protocol/08-AUN-E2EE.md +413 -0
  19. package/_packed_docs/protocol/09-/345/256/211/345/205/250/350/200/203/350/231/221.md +316 -0
  20. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +804 -0
  21. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +271 -0
  22. package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +329 -0
  23. package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +141 -0
  24. package/_packed_docs/protocol/14-/344/272/244/344/272/222/346/234/272/345/210/266-/345/223/215/345/272/224/346/250/241/345/274/217/344/270/216/350/207/252/344/270/273/346/250/241/345/274/217.md +170 -0
  25. package/_packed_docs/protocol/README.md +71 -0
  26. package/_packed_docs/protocol/agent.md/SCHEMA.md +118 -0
  27. package/_packed_docs/protocol/agent.md/examples/codeagent-claudecode.md +61 -0
  28. package/_packed_docs/protocol/agent.md/examples/human-developer.md +60 -0
  29. package/_packed_docs/protocol/agent.md/examples/openclaw-lobster.md +52 -0
  30. package/_packed_docs/protocol/aun-docs-guide.md +49 -0
  31. package/_packed_docs/protocol/index.md +114 -0
  32. package/_packed_docs/protocol//350/215/211/346/241/210-agent.md/347/255/276/345/220/215/345/215/217/350/256/256.md +205 -0
  33. package/_packed_docs/protocol//350/215/211/346/241/210-/346/213/222/347/273/235/344/277/241/345/217/267/345/215/217/350/256/256.md +249 -0
  34. package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +337 -0
  35. package/_packed_docs/protocol//351/231/204/345/275/225B-/346/211/251/345/261/225/346/200/247/346/214/207/345/215/227.md +80 -0
  36. package/_packed_docs/protocol//351/231/204/345/275/225C-/347/247/201/351/222/245/347/256/241/347/220/206/344/270/216/350/272/253/344/273/275/346/201/242/345/244/215.md +704 -0
  37. package/_packed_docs/protocol//351/231/204/345/275/225D-Root_CA_/346/262/273/347/220/206/346/234/272/345/210/266.md +620 -0
  38. package/_packed_docs/protocol//351/231/204/345/275/225E-Root_CA_/345/207/206/345/205/245/346/265/201/347/250/213.md +605 -0
  39. package/_packed_docs/protocol//351/231/204/345/275/225F-Issuer_CA_/347/224/263/350/257/267/346/265/201/347/250/213.md +548 -0
  40. package/_packed_docs/protocol//351/231/204/345/275/225G-AID_/345/255/244/345/204/277/351/242/204/351/230/262/344/270/216/346/225/221/346/217/264/346/234/272/345/210/266.md +513 -0
  41. package/_packed_docs/protocol//351/231/204/345/275/225H-Identity/346/234/215/345/212/241/345/256/236/347/216/260/346/214/207/345/215/227.md +619 -0
  42. package/_packed_docs/protocol//351/231/204/345/275/225I-/350/267/250/345/237/237/346/266/210/346/201/257/350/267/257/347/224/261/345/256/236/347/216/260/346/214/207/345/215/227.md +492 -0
  43. package/_packed_docs/protocol//351/231/204/345/275/225J-/345/256/242/346/210/267/347/253/257/346/216/245/345/205/245/347/244/272/344/276/213.md +402 -0
  44. package/_packed_docs/protocol//351/231/204/345/275/225K-Agent_Web/345/217/221/347/216/260/345/215/217/350/256/256.md +130 -0
  45. package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +267 -0
  46. package/_packed_docs/protocol//351/231/204/345/275/225M-JWT/350/256/244/350/257/201/345/256/236/347/216/260/346/214/207/345/215/227.md +367 -0
  47. package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +223 -0
  48. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +354 -0
  49. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +172 -0
  50. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +373 -0
  51. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +611 -0
  52. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +1152 -0
  53. package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +150 -0
  54. package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +89 -0
  55. package/_packed_docs/sdk/09-custody-api-manual.md +445 -0
  56. package/_packed_docs/sdk/09-group-rpc-manual.md +1895 -0
  57. package/_packed_docs/sdk/09-message-rpc-manual.md +597 -0
  58. package/_packed_docs/sdk/09-meta-rpc-manual.md +142 -0
  59. package/_packed_docs/sdk/09-payload-reference.md +702 -0
  60. package/_packed_docs/sdk/09-storage-rpc-manual.md +408 -0
  61. package/_packed_docs/sdk/09-stream-rpc-manual.md +275 -0
  62. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +72 -0
  63. package/_packed_docs/sdk/INDEX.md +131 -0
  64. package/_packed_docs/sdk/README.md +307 -0
  65. package/dist/auth.d.ts +2 -1
  66. package/dist/auth.d.ts.map +1 -1
  67. package/dist/auth.js +13 -11
  68. package/dist/auth.js.map +1 -1
  69. package/dist/client.d.ts +38 -8
  70. package/dist/client.d.ts.map +1 -1
  71. package/dist/client.js +179 -97
  72. package/dist/client.js.map +1 -1
  73. package/dist/namespaces/auth.d.ts +1 -0
  74. package/dist/namespaces/auth.d.ts.map +1 -1
  75. package/dist/namespaces/auth.js +20 -6
  76. package/dist/namespaces/auth.js.map +1 -1
  77. package/dist/transport.d.ts +9 -1
  78. package/dist/transport.d.ts.map +1 -1
  79. package/dist/transport.js +24 -0
  80. package/dist/transport.js.map +1 -1
  81. package/package.json +40 -37
@@ -0,0 +1,262 @@
1
+ # 3. Gateway 连接模式
2
+
3
+ ## 3.1 Gateway 模式定位
4
+
5
+ Gateway 是 AUN 三种平级连接模式之一(Gateway / [Peer](04-Peer-子协议.md) / [Relay](05-Relay-子协议.md)),**不是协议唯一入口**。
6
+
7
+ **适用场景**:浏览器、移动端、需要设备管理和在线状态的标准接入。
8
+
9
+ **Gateway 职责**:
10
+
11
+ - 本域消息路由(按 AID 转发到本地服务)
12
+ - 跨域消息路由(Gateway-to-Gateway 转发)
13
+ - JWT token 验证
14
+ - 请求转发到 AUN 服务(Auth、Message 等)
15
+ - **不持有**用户 AID 私钥
16
+ - **不处理**业务逻辑
17
+
18
+ ## 3.2 前置条件
19
+
20
+ - 已创建 AID(通过 `auth.create_aid`)
21
+ - 已获取可用于 `auth.connect` 的访问凭证(常见为 `auth.aid_login1` + `auth.aid_login2` 返回的 JWT access_token)
22
+ - 或已有未过期的 token(重连场景)
23
+
24
+ ## 3.3 Gateway 发现
25
+
26
+ 客户端通过 Well-Known 端点自动发现可用的 Gateway 地址。
27
+
28
+ **请求**:
29
+
30
+ ```
31
+ GET https://{aid}/.well-known/aun-gateway
32
+ ```
33
+
34
+ 其中 `{aid}` 为目标 Agent 的完整 AID(如 `my-agent.agentid.pub`)。
35
+
36
+ **响应**(`Content-Type: application/json`):
37
+
38
+ ```json
39
+ {
40
+ "gateways": [
41
+ {"url": "wss://gw1.agentid.pub/ws", "priority": 1},
42
+ {"url": "wss://gw2.agentid.pub/ws", "priority": 2}
43
+ ]
44
+ }
45
+ ```
46
+
47
+ | 字段 | 类型 | 必需 | 说明 |
48
+ |------|------|:----:|------|
49
+ | `gateways` | array | ✅ | 可用 Gateway 列表,不可为空 |
50
+ | `gateways[].url` | string | ✅ | Gateway WebSocket 地址(`ws://` 或 `wss://`) |
51
+ | `gateways[].priority` | integer | ❌ | 优先级,数值越小优先级越高,默认 999 |
52
+
53
+ **客户端行为**:
54
+
55
+ 1. 按 `priority` 升序排序
56
+ 2. 选择优先级最高(数值最小)的 Gateway 尝试连接
57
+ 3. 连接失败时可降级到下一优先级
58
+ 4. 发现结果应缓存,避免每次连接重复查询
59
+
60
+ ## 3.4 连接时序
61
+
62
+ ```
63
+ WebSocket 连接建立
64
+ ← challenge(服务端推送 nonce)
65
+ → auth.aid_login1 (可选,已有 token 时跳过)
66
+ → auth.aid_login2 (可选)
67
+ → auth.connect(nonce, auth, protocol, device, client, delivery_mode, capabilities)
68
+ ← {status: "ok", protocol, identity, ...}
69
+ → READY,进入 Gateway 业务态
70
+ ```
71
+
72
+ > `auth.aid_login1/2` 为可选:如果客户端已持有有效 token,可直接调用 `auth.connect`。
73
+
74
+ ## 3.5 auth.connect
75
+
76
+ 客户端通过 `auth.connect` 完成会话初始化,Gateway 验证认证凭证后建立到 Kernel 的代理连接,返回 `status: "ok"` 即进入 READY 状态。
77
+
78
+ ### 请求参数
79
+
80
+ | 参数 | 类型 | 必填 | 说明 |
81
+ |------|------|------|------|
82
+ | nonce | string | 是 | 服务端 challenge 中下发的 nonce |
83
+ | auth.method | string | 是 | 认证方式(`"kite_token"` / `"aid"` / `"pairing_code"`) |
84
+ | auth.token | string | 条件必填 | 当 `auth.method="kite_token"` 时必填。当前实现兼容 JWT access_token 与 kite_token |
85
+ | auth.code | string | 条件必填 | 当 `auth.method="pairing_code"` 时必填 |
86
+ | auth.aid | string | 条件必填 | 当 `auth.method="aid"` 时必填,必须是完整 AID |
87
+ | auth.request_id | string | 条件必填 | 当 `auth.method="aid"` 时必填,对应 `auth.aid_login1` 返回的 `request_id` |
88
+ | auth.nonce | string | 条件必填 | 当 `auth.method="aid"` 时必填,对应 `auth.aid_login1` 返回的一次性 nonce |
89
+ | auth.client_time | integer | 条件必填 | 当 `auth.method="aid"` 时必填,客户端毫秒时间戳 |
90
+ | auth.signature | string | 条件必填 | 当 `auth.method="aid"` 时必填,对 `auth.nonce` 的签名 |
91
+ | protocol.min | string | 是 | 客户端支持的最低协议版本 |
92
+ | protocol.max | string | 是 | 客户端支持的最高协议版本 |
93
+ | device.id | string | 推荐 | 设备唯一标识。SDK 默认从 `~/.aun/.device_id` 稳定读取 |
94
+ | device.type | string | 推荐 | 设备类型(desktop/mobile/browser) |
95
+ | client.slot_id | string | 否 | 同一 `device.id` 下的实例槽位。仅在 `device.id` 存在时可用 |
96
+ | delivery_mode.mode | string | 否 | 连接级投递模式:`fanout` 或 `queue` |
97
+ | delivery_mode.routing | string | 否 | 仅 `queue` 时有效:`round_robin` 或 `sender_affinity` |
98
+ | delivery_mode.affinity_ttl_ms | integer | 否 | 仅 `queue + sender_affinity` 时有效,表示发送者粘性保持时长 |
99
+ | capabilities | object | 否 | 客户端能力声明 |
100
+ | client | object | 否 | 客户端信息(名称、版本等) |
101
+
102
+ **当前实现补充**:
103
+
104
+ - 顶层 `nonce` 与 `auth.nonce` 语义不同:前者是 Gateway challenge nonce,后者仅 `aid` 模式使用,来自 `auth.aid_login1`
105
+ - `aid` 模式的 `auth.signature` 由客户端对 `auth.nonce` 进行签名;裸 WebSocket 客户端若先获取了 JWT access_token,也可直接改用 `kite_token` 模式连接
106
+
107
+ **协议版本与能力语义**:
108
+
109
+ - `protocol.min/max` 在 `auth.connect` 阶段参与 Gateway 会话的协议版本协商。Gateway 将客户端版本范围与服务端支持范围取交集,并选择交集中的最高版本作为响应字段 `protocol`。
110
+ - 若双方版本范围没有交集,Gateway 返回 JSON-RPC 错误 `-32000`,错误数据包含 `server_range` 和 `client_range`,随后关闭 WebSocket 连接。
111
+ - 当前 Gateway 为兼容旧客户端,会把缺失的 `protocol.min/max` 按 `"1.0"` 处理;新客户端仍应显式发送 `protocol: {"min": "1.0", "max": "1.0"}`。
112
+ - `auth.connect.params.capabilities` 是**客户端能力声明**,绑定到当前连接。Gateway 会把它记录到会话,并通过 `client.online` 事件转发给业务服务。
113
+ - `hello-ok.result.capabilities` 是**服务端能力公告**,表示 Gateway/服务端当前暴露的命名空间和功能,不是对客户端能力取交集后的结果。
114
+ - 因此当前机制应描述为“协议版本协商 + 客户端能力声明 + 服务端能力公告”。除非某个扩展明确规定交集规则,否则不要把 `capabilities` 理解为完整的双向能力协商。
115
+
116
+ **连接约束**:
117
+
118
+ - 未传 `device.id` 的客户端按 legacy 语义处理,不支持多实例槽位。
119
+ - `client.slot_id` 只能和 `device.id` 一起使用;否则返回 `slot_requires_device_id`。
120
+ - `device.id` 非空但 `client.slot_id` 为空时,同一 `(aid, device.id)` 只允许一个在线实例;冲突时返回 `device_singleton_conflict`。
121
+ - `device.id` 与 `client.slot_id` 同时存在时,同一 `(aid, device.id, client.slot_id)` 只允许一个在线实例;冲突时返回 `slot_conflict`。
122
+ - 同一 `aid` 的所有在线连接必须声明一致的 `delivery_mode`;冲突时返回 `delivery_mode_conflict`。
123
+ - `queue + sender_affinity` 为 best-effort 粘性路由:同一发送者会尽量命中同一实例,实例下线后自动切换。
124
+
125
+ **capabilities 字段说明**:
126
+
127
+ | 字段 | 类型 | 说明 |
128
+ |------|------|------|
129
+ | `e2ee` | boolean | 是否支持 P2P E2EE(接收和发送) |
130
+ | `group_e2ee` | boolean | 是否支持群组 E2EE(接收、解密、密钥协议处理)。所有现代客户端必须声明为 `true` |
131
+
132
+ 当前 Group 服务会读取 `client.online` 中的 `group_e2ee`,用于本域客户端入群、加人等流程的准入检查。跨域客户端的能力声明不会随 `client.online` 跨域传播,服务端按跨域信任策略处理。
133
+
134
+ 请求示例:
135
+
136
+ ```json
137
+ {
138
+ "jsonrpc": "2.0",
139
+ "id": 1,
140
+ "method": "auth.connect",
141
+ "params": {
142
+ "nonce": "challenge-nonce-from-server",
143
+ "auth": {"method": "kite_token", "token": "eyJhbGciOi..."},
144
+ "protocol": {"min": "1.0", "max": "1.0"},
145
+ "device": {"id": "dev-001", "type": "browser"},
146
+ "client": {"slot_id": "slot-a"},
147
+ "delivery_mode": {
148
+ "mode": "queue",
149
+ "routing": "sender_affinity",
150
+ "affinity_ttl_ms": 300000
151
+ },
152
+ "capabilities": {
153
+ "e2ee": true,
154
+ "group_e2ee": true
155
+ }
156
+ }
157
+ }
158
+ ```
159
+
160
+ ### 响应字段
161
+
162
+ | 字段 | 类型 | 说明 |
163
+ |------|------|------|
164
+ | status | string | `"ok"` 表示成功 |
165
+ | protocol | string | 协商后的协议版本 |
166
+ | server_time | number | 服务器时间(Unix 时间戳) |
167
+ | authenticated | boolean | 认证状态 |
168
+ | identity | object | 认证身份信息(含 module_id、role、aid) |
169
+ | connection | object | 连接信息(id、device_id) |
170
+ | bridgeInfo | object | Bridge 信息(name、version) |
171
+ | capabilities | object | 服务端能力声明 |
172
+ | trust_level | string | 信任等级 |
173
+ | token | string | 可选,首次登录时返回 kite_token 供后续重连 |
174
+
175
+ 响应示例:
176
+
177
+ ```json
178
+ {
179
+ "jsonrpc": "2.0",
180
+ "id": 1,
181
+ "result": {
182
+ "status": "ok",
183
+ "protocol": "1.0",
184
+ "server_time": 1711234567.890,
185
+ "authenticated": true,
186
+ "identity": {
187
+ "module_id": "gateway-client-abc123",
188
+ "role": "admin",
189
+ "aid": "alice.agentid.pub"
190
+ },
191
+ "trust_level": "low",
192
+ "connection": {"id": "conn_gateway-client-abc123", "device_id": "dev-001"},
193
+ "bridgeInfo": {"name": "Kite Gateway", "version": "0.1"},
194
+ "capabilities": {
195
+ "namespaces": ["auth", "message", "meta", "group", "storage", "stream"],
196
+ "features": {
197
+ "e2ee": false,
198
+ "binary_message": false,
199
+ "max_message_size": 1048576
200
+ }
201
+ }
202
+ }
203
+ }
204
+ ```
205
+
206
+ ### 错误码
207
+
208
+ | 错误码 | 说明 |
209
+ |--------|------|
210
+ | -32000 | 协议版本不匹配 |
211
+ | 4000 | 缺少必要参数(auth.method、nonce 等) |
212
+ | 4001 | 认证失败(token 无效或过期) |
213
+ | 4010 | Nonce 无效或已过期 |
214
+ | 4500 | 服务端内部错误(Auth 服务或 Kernel 不可达) |
215
+
216
+ **典型错误消息**:
217
+
218
+ - `slot_requires_device_id`
219
+ - `device_singleton_conflict`
220
+ - `slot_conflict`
221
+ - `delivery_mode_conflict`
222
+
223
+ ### 连接超时
224
+
225
+ WebSocket 连接建立后 **30 秒**内未完成 `auth.connect`,服务端关闭连接。
226
+
227
+ ## 3.6 心跳与重连
228
+
229
+ - **心跳**:应用层 `meta.ping`,推荐间隔 30 秒
230
+ - **Token 过期**:连接期间 token 过期时,调用 `auth.refresh_token` 刷新
231
+ - **重连**:新建 WebSocket 连接 → `auth.connect(token)` 重新初始化
232
+
233
+ > 重连不保留前一次连接的会话状态,需重新 `auth.connect`。
234
+
235
+ ## 3.7 与 auth.* 的关系
236
+
237
+ | 职责 | 负责方 |
238
+ |------|--------|
239
+ | AID 创建 / 登录 / token 签发与刷新 | `auth.*`(Auth 服务) |
240
+ | Gateway 会话初始化与连接管理 | `auth.connect` |
241
+ | token 转发验证 | Gateway |
242
+
243
+ - `auth.aid_login1/2` 用于获取 token(身份凭证)
244
+ - Gateway 不处理 `auth.*` 登录逻辑,仅转发到 Auth 服务
245
+ - `auth.connect` 完成 Gateway 模式的会话初始化
246
+
247
+ ## 3.8 跨域消息路由(Gateway-to-Gateway)
248
+
249
+ 当本域客户端需要向其他 Issuer 域的 AID 发送消息时,Gateway 负责跨域中继。
250
+
251
+ ### 路由流程
252
+
253
+ ```
254
+ 本域客户端 → 本域 Gateway → 远端 Gateway → 远端服务 → 目标 AID
255
+ ```
256
+
257
+ **关键特性**:
258
+ - 本域服务(Message/Group/Mail)无需感知远端域,只需将跨域请求发给本地 Gateway
259
+ - Gateway 根据目标 AID 的 Issuer 部分(如 `bob.example.com` 中的 `example.com`)发现远端 Gateway
260
+ - Gateway 间通过 WebSocket 长连接通信,复用 JSON-RPC 2.0 协议
261
+ - 远端 Gateway 验证请求后转发到本域服务
262
+ - **auth 管凭证,auth.connect 管连接**——两者职责不同
@@ -0,0 +1,180 @@
1
+ # 4. Peer 子协议
2
+
3
+ ## 4.1 目标与适用场景
4
+
5
+ `peer.*` 是 AUN 核心协议的**对等认证子协议**。
6
+
7
+ **适用场景**:
8
+
9
+ - **Peer 直连模式** — 双方有可达网络地址,直接 WebSocket 连接
10
+ - **Relay 模式** — 穿透 [Relay](05-Relay-子协议.md) 完成端到端认证
11
+
12
+ **设计目标**:
13
+
14
+ - 复用 AID + X.509 证书链信任(见 [02-证书与信任体系](02-证书与信任体系.md))
15
+ - 不依赖 JWT
16
+ - 对称 challenge-response 双向认证
17
+ - 认证后用 `message.*` 通信
18
+
19
+ ## 4.2 角色与前置条件
20
+
21
+ - **发起方(Initiator)**:主动发起 `peer.hello` 的一方
22
+ - **响应方(Responder)**:接收并回复的一方
23
+
24
+ **前置条件**:
25
+
26
+ - 双方各持有有效 AID 证书和对应私钥
27
+ - 双方各持有受信根证书列表(用于验证对端证书链)
28
+
29
+ ## 4.3 状态机
30
+
31
+ ```
32
+ CONNECTED
33
+ → initialize(mode=peer)
34
+ → INITIALIZED
35
+ → peer.hello
36
+ → PEER_CHALLENGED
37
+ → peer.hello_reply
38
+ → PEER_VERIFIED
39
+ → peer.confirm
40
+ → AUTHENTICATED
41
+ → notification/initialized
42
+ → READY
43
+ ```
44
+
45
+ ## 4.4 peer.hello
46
+
47
+ 发起对等认证。
48
+
49
+ **请求参数**:
50
+
51
+ | 参数 | 类型 | 必填 | 说明 |
52
+ |------|------|------|------|
53
+ | aid | string | 是 | 发起方 AID |
54
+ | cert | string | 是 | 发起方 Agent 证书(PEM) |
55
+ | nonce | string | 是 | 发起方随机挑战(UUID) |
56
+ | protocol | object | 是 | `{min, max}` 协议版本范围 |
57
+
58
+ ```json
59
+ {
60
+ "jsonrpc": "2.0",
61
+ "id": 1,
62
+ "method": "peer.hello",
63
+ "params": {
64
+ "aid": "alice.aid.pub",
65
+ "cert": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
66
+ "nonce": "550e8400-e29b-41d4-a716-446655440000",
67
+ "protocol": { "min": "0.1", "max": "0.1" }
68
+ }
69
+ }
70
+ ```
71
+
72
+ ## 4.5 peer.hello_reply
73
+
74
+ 响应对等认证并签名对端 nonce。
75
+
76
+ **响应字段**:
77
+
78
+ | 字段 | 类型 | 说明 |
79
+ |------|------|------|
80
+ | aid | string | 响应方 AID |
81
+ | cert | string | 响应方 Agent 证书(PEM) |
82
+ | nonce | string | 响应方随机挑战(UUID) |
83
+ | nonce_signature | string | 响应方用私钥对**发起方 nonce** 的签名(Base64) |
84
+ | protocol | string | 协商后的协议版本 |
85
+
86
+ ```json
87
+ {
88
+ "jsonrpc": "2.0",
89
+ "id": 1,
90
+ "result": {
91
+ "aid": "bob.aid.pub",
92
+ "cert": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
93
+ "nonce": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
94
+ "nonce_signature": "MEUCIQD...",
95
+ "protocol": "0.1"
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## 4.6 peer.confirm
101
+
102
+ 发起方验证响应方签名后,签名响应方 nonce。
103
+
104
+ **请求参数**:
105
+
106
+ | 参数 | 类型 | 必填 | 说明 |
107
+ |------|------|------|------|
108
+ | nonce_signature | string | 是 | 发起方用私钥对**响应方 nonce** 的签名(Base64) |
109
+
110
+ ```json
111
+ {
112
+ "jsonrpc": "2.0",
113
+ "id": 2,
114
+ "method": "peer.confirm",
115
+ "params": {
116
+ "nonce_signature": "MEYCIQCx..."
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## 4.7 peer.confirmed
122
+
123
+ 认证完成确认。响应方验证签名后返回。
124
+
125
+ **响应字段**:
126
+
127
+ | 字段 | 类型 | 说明 |
128
+ |------|------|------|
129
+ | status | string | `"ok"` |
130
+ | authenticated | boolean | `true` |
131
+ | identity | object | `{aid: "alice.aid.pub"}` |
132
+
133
+ ## 4.8 证书链验证规则
134
+
135
+ 1. 验证对端证书链到受信 Root CA(Root CA → Registry CA → Issuer CA → Agent cert)
136
+ 2. 校验证书 CN/SAN 与声称的 `aid` 一致
137
+ 3. 检查证书有效期
138
+ 4. 检查证书吊销状态(CRL 或 OCSP,如可用)
139
+
140
+ ## 4.9 Nonce 与签名规则
141
+
142
+ - Nonce **一次性使用**,推荐有效期 30-60 秒
143
+ - 签名算法根据证书曲线:
144
+ - P-256 → ECDSA-SHA256
145
+ - P-384 → ECDSA-SHA384
146
+ - 验证方使用证书中的公钥验证签名
147
+ - 签名输入为 nonce 原始字节(UTF-8 编码)
148
+
149
+ ## 4.10 版本协商
150
+
151
+ 发起方在 `peer.hello` 中提供 `{min, max}` 版本范围,响应方在 `peer.hello_reply` 中返回双方都支持的**最高版本**。如无交集,返回错误码 -32000。
152
+
153
+ ## 4.11 Peer 地址发现
154
+
155
+ 四种方式:
156
+
157
+ 1. **手动配置** — 直接指定对端地址
158
+ 2. **DNS SRV** — `_aun-peer._tcp.{domain}`
159
+ 3. **Gateway 信令交换** — 通过 Gateway 传递 `peer.offer` → `peer.accept`(NAT 穿透辅助)
160
+ 4. **Agent 目录服务** — 查询 Agent 目录获取端点信息
161
+
162
+ ## 4.12 错误码
163
+
164
+ | 错误码 | 说明 |
165
+ |--------|------|
166
+ | -32100 | 证书链验证失败 |
167
+ | -32101 | Nonce 已过期 |
168
+ | -32102 | Nonce 重用检测 |
169
+ | -32103 | 签名验证失败 |
170
+ | -32104 | AID 与证书不匹配 |
171
+ | -32105 | 握手状态非法 |
172
+
173
+ ## 4.13 认证完成后的会话语义
174
+
175
+ 认证完成后:
176
+
177
+ - 双方进入 AUTHENTICATED → READY 状态
178
+ - 可调用所有业务方法(`message.*` 等)
179
+ - 身份由**证书链验证结果**确定,非 JWT
180
+ - 会话生命周期与 WebSocket 连接绑定
@@ -0,0 +1,164 @@
1
+ # 5. Relay 子协议
2
+
3
+ ## 5.1 目标与适用场景
4
+
5
+ `relay.*` 是 AUN 核心协议的**中继传输子协议**。
6
+
7
+ **适用场景**:双方都在 NAT 后无公网 IP,需要轻量中继转发。
8
+
9
+ Relay 实现极简,核心逻辑约 200 行代码即可完成。
10
+
11
+ ## 5.2 Relay 职责边界
12
+
13
+ **职责**:
14
+
15
+ - 维护 AID → WebSocket 连接映射
16
+ - 按目标 AID 转发消息
17
+ - 维持连接与基础流控
18
+
19
+ **非职责**:
20
+
21
+ - 不验证证书链
22
+ - 不签发 JWT
23
+ - 不解析内层 `peer.*` 或 `message.*`
24
+ - 不存储历史消息
25
+
26
+ > Relay 是**零信任笨管道**,所有安全保障由端到端的 [peer.*](04-Peer-子协议.md) 完成。
27
+
28
+ ## 5.3 状态机
29
+
30
+ ```
31
+ CONNECTED
32
+ → initialize(mode=relay)
33
+ → INITIALIZED
34
+ → relay.register
35
+ → RELAY_REGISTERED
36
+ → relay.forward(peer.hello)
37
+ → ...peer.* 穿透认证...
38
+ → AUTHENTICATED
39
+ → notification/initialized
40
+ → READY
41
+ ```
42
+
43
+ ## 5.4 relay.register
44
+
45
+ 注册 AID 到 Relay,建立 AID → 连接映射。
46
+
47
+ **请求**:
48
+
49
+ ```json
50
+ {
51
+ "jsonrpc": "2.0",
52
+ "id": 1,
53
+ "method": "relay.register",
54
+ "params": { "aid": "alice.aid.pub" }
55
+ }
56
+ ```
57
+
58
+ **响应**:
59
+
60
+ ```json
61
+ { "jsonrpc": "2.0", "id": 1, "result": { "status": "ok" } }
62
+ ```
63
+
64
+ ## 5.5 relay.forward
65
+
66
+ 向指定 AID 转发任意 JSON-RPC 消息。
67
+
68
+ **请求参数**:
69
+
70
+ | 参数 | 类型 | 必填 | 说明 |
71
+ |------|------|------|------|
72
+ | to | string | 是 | 目标 AID |
73
+ | message | object | 是 | 要转发的完整 JSON-RPC 消息 |
74
+
75
+ ```json
76
+ {
77
+ "jsonrpc": "2.0",
78
+ "id": 2,
79
+ "method": "relay.forward",
80
+ "params": {
81
+ "to": "bob.aid.pub",
82
+ "message": {
83
+ "jsonrpc": "2.0",
84
+ "id": 1,
85
+ "method": "peer.hello",
86
+ "params": {
87
+ "aid": "alice.aid.pub",
88
+ "cert": "-----BEGIN CERTIFICATE-----\n...",
89
+ "nonce": "550e8400-e29b-41d4-a716-446655440000",
90
+ "protocol": { "min": "0.1", "max": "0.1" }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ **响应**:
98
+
99
+ ```json
100
+ { "jsonrpc": "2.0", "id": 2, "result": { "status": "forwarded" } }
101
+ ```
102
+
103
+ ## 5.6 event/relay.message
104
+
105
+ Relay 向目标 Agent 投递消息(JSON-RPC Notification)。
106
+
107
+ ```json
108
+ {
109
+ "jsonrpc": "2.0",
110
+ "method": "event/relay.message",
111
+ "params": {
112
+ "from": "alice.aid.pub",
113
+ "message": {
114
+ "jsonrpc": "2.0",
115
+ "id": 1,
116
+ "method": "peer.hello",
117
+ "params": { "..." : "..." }
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ ## 5.7 内层消息透明封装规则
124
+
125
+ - Relay **不解析** `message` 内容
126
+ - Relay 将 `from` 绑定到当前连接已注册的 AID(**不信任**内层 message 中的 from)
127
+ - 可限制最大转发消息尺寸(推荐 64KB)和速率
128
+
129
+ ## 5.8 与 peer.* 的关系
130
+
131
+ Relay 模式下的身份认证流程:
132
+
133
+ 1. 双方连接 Relay → `initialize(mode=relay)` → `relay.register`
134
+ 2. 发起方:`relay.forward({to: "bob", message: peer.hello})`
135
+ 3. 对端收到 `event/relay.message`,提取内层 `peer.hello` 处理
136
+ 4. 响应方:`relay.forward({to: "alice", message: peer.hello_reply})`
137
+ 5. 继续 `peer.confirm` / `peer.confirmed` 流程(均通过 relay.forward 传输)
138
+ 6. 认证完成后,业务消息同样通过 `relay.forward` / `event/relay.message` 交换
139
+
140
+ **Relay 只是传输管道,认证由 [peer.*](04-Peer-子协议.md) 完成。**
141
+
142
+ ## 5.9 Relay 发现
143
+
144
+ 1. **手动配置** — 直接指定 Relay 地址
145
+ 2. **公共 Relay 列表** — 自动选择延迟最低的节点
146
+ 3. **Gateway 兼任 Relay** — Gateway 实现可同时提供 Relay 功能
147
+
148
+ ## 5.10 错误码
149
+
150
+ | 错误码 | 说明 |
151
+ |--------|------|
152
+ | -32150 | 未注册,需先 relay.register |
153
+ | -32151 | 目标 AID 未找到 |
154
+ | -32152 | 发送方 AID 不匹配 |
155
+ | -32153 | 转发消息体过大 |
156
+ | -32154 | 速率限制 |
157
+
158
+ ## 5.11 安全说明
159
+
160
+ - Relay 是**零信任笨管道**,不参与任何认证
161
+ - 不持有 JWT,不验证身份
162
+ - 消息内容对 Relay 完全透明(尤其适合 E2EE 场景)
163
+ - 所有身份验证由端到端 `peer.*` 完成
164
+ - Relay 唯一的安全保障是 `from` 字段绑定(防止 AID 伪装)