@agentunion/fastaun-browser 0.5.19 → 0.5.21
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.
- package/CHANGELOG.md +176 -78
- package/_packed_docs/CHANGELOG.md +176 -78
- package/_packed_docs/INDEX.md +288 -269
- package/_packed_docs/KITE_DOCS_GUIDE.md +101 -95
- package/_packed_docs/agent.md/SCHEMA.md +7 -7
- package/_packed_docs/agent.md/working/AID/347/261/273/345/236/213-owner/345/205/263/347/263/273/344/270/216/346/215/242owner/347/274/226/346/216/222/346/226/271/346/241/210.md +530 -0
- package/_packed_docs/agent.md/working/AID/347/261/273/345/236/213-owner/345/205/263/347/263/273/345/256/214/346/225/264/350/256/276/350/256/241/344/270/216/345/256/236/346/226/275/350/256/241/345/210/222.md +685 -0
- package/_packed_docs/agent.md/working/agent.md-schema/344/270/216/347/255/276/345/217/221/351/252/214/347/255/276/346/265/201/347/250/213/346/276/204/346/270/205.md +349 -0
- package/_packed_docs/agent.md/working//346/234/254/345/234/260Docker/346/265/213/350/257/225Bug/346/270/205/345/215/225.md +40 -0
- package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +11 -11
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +372 -331
- package/_packed_docs/protocol/08-AUN-E2EE.md +17 -12
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +676 -676
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +8 -12
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/211.md +445 -0
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.0.md +161 -0
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +666 -0
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2113.0.md +233 -0
- package/_packed_docs/protocol/agent.md/SCHEMA.md +1 -1
- package/_packed_docs/sdk/0.5.21-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +368 -0
- package/_packed_docs/sdk/0.5.21-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +350 -0
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +1 -1
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +5 -1
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +64 -64
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +70 -63
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +43 -40
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +179 -19
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +50 -49
- package/_packed_docs/sdk/09-group-rpc-manual.md +261 -254
- package/_packed_docs/sdk/09-message-rpc-manual.md +253 -160
- package/_packed_docs/sdk/09-storage-rpc-manual.md +18 -26
- package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +71 -0
- package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +88 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +105 -92
- package/_packed_docs/sdk/INDEX.md +197 -167
- package/_packed_docs/sdk/Ownership-SDK/345/256/236/347/216/260/346/214/207/345/215/227.md +169 -0
- package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/227.md +349 -0
- package/_packed_docs/sdk/Ownership-SDK/347/274/226/346/216/222/346/214/207/345/215/2272.1.md +930 -0
- package/_packed_docs/sdk/Ownership-SDK/351/233/206/346/210/220/346/214/207/345/215/227.md +270 -0
- package/_packed_docs/sdk/Ownership2.1-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +363 -0
- package/_packed_docs/sdk/Ownership2.1-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +553 -0
- package/_packed_docs/sdk/Ownership2.1-TDD/345/210/206/351/230/266/346/256/265/345/256/236/346/226/275/350/256/241/345/210/222.md +708 -0
- package/_packed_docs/sdk/Ownership2.1/350/257/246/347/273/206/350/256/276/350/256/241.md +480 -0
- package/_packed_docs/sdk/Ownership/347/256/241/347/220/206/344/270/223/351/242/230.md +559 -0
- package/_packed_docs/sdk/ProtectedHeaders/347/224/250/346/263/225/344/270/223/351/242/230.md +299 -0
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +173 -0
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +211 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273SDK/345/256/236/347/216/260/347/247/273/346/244/215/346/214/207/345/215/227.md +331 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273SDK/351/233/206/346/210/220/346/214/207/345/215/227.md +207 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/344/273/243/347/240/201/345/256/241/346/237/245/346/212/245/345/221/212.md +252 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/345/256/236/346/226/275/350/256/241/345/210/222.md +156 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/346/226/271/346/241/210.md +273 -0
- package/_packed_docs//350/267/250/350/256/276/345/244/207/345/267/262/350/257/273/346/234/252/350/257/273/350/257/246/347/273/206/350/256/276/350/256/241.md +211 -0
- package/dist/agent-md-schema.d.ts +16 -4
- package/dist/agent-md-schema.d.ts.map +1 -1
- package/dist/agent-md-schema.js +65 -30
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.d.ts +35 -3
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +384 -150
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +59 -0
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +202 -16
- package/dist/aid-store.js.map +1 -1
- package/dist/aid.d.ts +4 -1
- package/dist/aid.d.ts.map +1 -1
- package/dist/aid.js +24 -42
- package/dist/aid.js.map +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +89 -18
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +6410 -1848
- package/dist/cert-utils.d.ts +50 -1
- package/dist/cert-utils.d.ts.map +1 -1
- package/dist/cert-utils.js +123 -56
- package/dist/cert-utils.js.map +1 -1
- package/dist/client/delivery.d.ts +108 -16
- package/dist/client/delivery.d.ts.map +1 -1
- package/dist/client/delivery.js +1411 -184
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/rpc-pipeline.d.ts +4 -1
- package/dist/client/rpc-pipeline.d.ts.map +1 -1
- package/dist/client/rpc-pipeline.js +203 -117
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +22 -3
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +1312 -684
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +23 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +419 -101
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +8 -6
- package/dist/crypto.js.map +1 -1
- package/dist/events.d.ts +24 -3
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +171 -29
- package/dist/events.js.map +1 -1
- package/dist/facades.d.ts +42 -1
- package/dist/facades.d.ts.map +1 -1
- package/dist/facades.js +368 -12
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +14 -1
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.d.ts +4 -0
- package/dist/keystore/indexeddb-identity-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-identity-store.js +30 -13
- package/dist/keystore/indexeddb-identity-store.js.map +1 -1
- package/dist/keystore/indexeddb-shared.d.ts +19 -2
- package/dist/keystore/indexeddb-shared.d.ts.map +1 -1
- package/dist/keystore/indexeddb-shared.js +193 -6
- package/dist/keystore/indexeddb-shared.js.map +1 -1
- package/dist/keystore/indexeddb-token-store.d.ts +15 -2
- package/dist/keystore/indexeddb-token-store.d.ts.map +1 -1
- package/dist/keystore/indexeddb-token-store.js +308 -27
- package/dist/keystore/indexeddb-token-store.js.map +1 -1
- package/dist/org-protocol.d.ts +45 -0
- package/dist/org-protocol.d.ts.map +1 -1
- package/dist/org-protocol.js +827 -21
- package/dist/org-protocol.js.map +1 -1
- package/dist/ownership-v21.d.ts +43 -9
- package/dist/ownership-v21.d.ts.map +1 -1
- package/dist/ownership-v21.js +183 -81
- package/dist/ownership-v21.js.map +1 -1
- package/dist/ownership-workflow.d.ts +36 -1
- package/dist/ownership-workflow.d.ts.map +1 -1
- package/dist/ownership-workflow.js +610 -89
- package/dist/ownership-workflow.js.map +1 -1
- package/dist/seq-tracker.d.ts +2 -0
- package/dist/seq-tracker.d.ts.map +1 -1
- package/dist/seq-tracker.js +3 -2
- package/dist/seq-tracker.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +61 -3
- package/dist/tools/cross-sdk-agent.d.ts.map +1 -1
- package/dist/tools/cross-sdk-agent.js +524 -45
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +4 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +64 -30
- package/dist/transport.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Ownership SDK实现指南
|
|
2
|
+
|
|
3
|
+
本文是 legacy 实现与移植记录,依据 2026-10-09 工作区中的四 SDK,不代表当前 Ownership 2.1。当前文件、持久任务、P2P 与恢复契约见 [Ownership 2.1 SDK 开发与移植指南](Ownership2.1-SDK开发与移植指南.md);下文旧 proof、自动 escrow、代签和代上传流程不能作为 2.1 实现依据。
|
|
4
|
+
|
|
5
|
+
## 1. 实现边界与参考代码
|
|
6
|
+
|
|
7
|
+
ownership在SDK中编排。复用已有AID签名、证书解析、加密P2P、Storage和agent.md能力,关系记录保存到本端metadata。Message/Gateway承载消息,Storage承载加密identity,Name Service验证并保存名片,Auth/CA承担既有身份认证和rekey。
|
|
8
|
+
|
|
9
|
+
| 责任 | TypeScript | Python | Go | JavaScript浏览器 |
|
|
10
|
+
| --- | --- | --- | --- | --- |
|
|
11
|
+
| 绑定、审批、释放、恢复及消息拦截 | [client.ts](../../ts/src/client.ts) | [client.py](../../python/src/aun_core/client.py) | [ownership_client.go](../../go/ownership_client.go) | [client.ts](../../js/src/client.ts) |
|
|
12
|
+
| 声明、proof与密码学验证 | [ownership-proof.ts](../../ts/src/ownership-proof.ts) | [ownership.py](../../python/src/aun_core/ownership.py) | [ownership_proof.go](../../go/ownership_proof.go) | [ownership-proof.ts](../../js/src/ownership-proof.ts) |
|
|
13
|
+
| P2P消息与escrow封套 | 同上 | [ownership_protocol.py](../../python/src/aun_core/ownership_protocol.py) | [ownership_protocol.go](../../go/ownership_protocol.go),加密在proof文件中 | 同上 |
|
|
14
|
+
| 名片更新、授权、下载验签及待上传恢复 | [agent-md.ts](../../ts/src/agent-md.ts) | [agent_md.py](../../python/src/aun_core/agent_md.py) | [agent_md_manager.go](../../go/agent_md_manager.go) | [agent-md.ts](../../js/src/agent-md.ts) |
|
|
15
|
+
| identity导入、rekey及本地存储 | [aid-store.ts](../../ts/src/aid-store.ts) | [aid_store.py](../../python/src/aun_core/aid_store.py) | [aid_store.go](../../go/aid_store.go) | [aid-store.ts](../../js/src/aid-store.ts) |
|
|
16
|
+
|
|
17
|
+
移植时对齐协议字节和可观察行为。各语言可使用自己的任务、锁与存储实现;服务模块之间仍通过协议协作。
|
|
18
|
+
|
|
19
|
+
## 2. 先对齐SDK公开契约
|
|
20
|
+
|
|
21
|
+
| 能力 | TypeScript / JavaScript | Python | Go |
|
|
22
|
+
| --- | --- | --- | --- |
|
|
23
|
+
| owner发起 | `bindAid(subjectAid, options?)` | `bind_aid(subject_aid, subject_type=..., extensions=..., request_id=...)` | `BindAID(ctx, subjectAID, options...)` |
|
|
24
|
+
| subject发起 | `bindOwner(ownerAid, options?)` | `bind_owner(owner_aid, ...)` | `BindOwner(ctx, ownerAID, options...)` |
|
|
25
|
+
| 接受申请 | `acceptOwnershipRequest(requestId, { extensions }?)` | `accept_ownership_request(request_id, extensions=...)` | `AcceptOwnershipRequest(ctx, requestID, extensions...)` |
|
|
26
|
+
| 拒绝申请 | `rejectOwnershipRequest(requestId)` | `reject_ownership_request(request_id)` | `RejectOwnershipRequest(ctx, requestID)` |
|
|
27
|
+
| 原owner释放 | `releaseOwnership(subjectAid)` | `release_ownership(subject_aid)` | `ReleaseOwnership(ctx, subjectAID)` |
|
|
28
|
+
| 本地查询 | `getType()` / `getOwner()` / `getOwnershipStatus()` | `get_type()` / `get_owner()` / `get_ownership_status()` | `GetType()` / `GetOwner()` / `GetOwnershipStatus()` |
|
|
29
|
+
|
|
30
|
+
TS/JS绑定选项为`subjectType`、`extensions`、`requestId`;Go使用`OwnershipBindOptions{SubjectType, Extensions, RequestID}`。Python已有对应camelCase别名,Go另有`BindAid`别名。语言原生异步形式与错误返回形式沿用各端既有契约;查询方法读取本地状态。
|
|
31
|
+
|
|
32
|
+
发起方签署自己的`extensions`,接受方通过接受API提供自己的扩展。只要求双方声明指向同一关系,不要求扩展相同。`subject_type`保存在关系记录中;名片更新保留已有业务字段,不能把该选项实现成强制重写名片类型。
|
|
33
|
+
|
|
34
|
+
`bindAid`、外部`bindOwner`及`releaseOwnership`返回发送结果。接受申请可能继续发送`escrow.ready`,返回结果不能统一解释为“关系、托管、名片已全部完成”。每次显式绑定调用生成新的UUIDv4 proof;断点恢复复用已经保存的proof。
|
|
35
|
+
|
|
36
|
+
## 3. 实现声明与验证原语
|
|
37
|
+
|
|
38
|
+
按以下顺序完成独立原语,再接入客户端编排:
|
|
39
|
+
|
|
40
|
+
1. 规范化AID、验证小写UUIDv4 `proof_id`,构造带角色和正整数`signed_at`的v2独立声明。
|
|
41
|
+
2. 实现canonical JSON及域分隔签名,输出证书DER指纹、严格Base64的DER ECDSA签名和原始statement。
|
|
42
|
+
3. 校验proof结构,逐份核对关系、角色、签署者、证书指纹及签署时间;只要已出现签名,就要验证。
|
|
43
|
+
4. 分别输出文件验签状态与ownership状态:`unbound`、`incomplete`、`complete`、`released`、`invalid`。
|
|
44
|
+
5. 实现release statement和escrow加解密,使用独立的release域前缀及固定的escrow AAD。
|
|
45
|
+
|
|
46
|
+
关系签名输入为:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
UTF-8("AUN-AID-OWNER-RELATION-V1;") || canonical_json(statement)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
prefix末尾的可见分号属于签名输入;声明版本为2时仍使用此prefix。对键递归排序、UTF-8、数字和转义输出进行字节比对;直接使用语言默认JSON或YAML输出可能得到不同签名字节。空`extensions`由当前生成器省略,应保存实际签署的statement以便重试。
|
|
53
|
+
|
|
54
|
+
证书信任与密码学验签分别落实:按AID及精确指纹查证书,经既有链验证能力建立信任,再验证CN、指纹、签名及相应签署时间。下载历史名片按尾部`timestamp`及各声明`signed_at`解析历史证书;当前登录和服务端上传继续遵循active signing规则。纯签名helper不能替代完整的证书解析与信任验证流程。
|
|
55
|
+
|
|
56
|
+
当前代码保留v1三字段声明的构造与部分解析。现行关系验证要求v2声明及`signed_at`,不要把旧构造向量通过解释为旧关系能通过现行验签。
|
|
57
|
+
|
|
58
|
+
## 4. 将拦截器接到统一接收路径
|
|
59
|
+
|
|
60
|
+
拦截位置是消息完成E2EE解密、即将发布应用`message.received`之间。实时push、离线pull、重连补拉应经过同一个入口。TypeScript参考`_publishAppEvent()`调用`_handleOwnershipMessage()`;Go参考`HandleOwnershipMessage()`。
|
|
61
|
+
|
|
62
|
+
| 接收到的内容 | 处理要求 |
|
|
63
|
+
| --- | --- |
|
|
64
|
+
| 非`aun.ownership.v1` | 沿原消息路径投递应用 |
|
|
65
|
+
| ownership控制消息 | 由SDK消费;验证失败、未知action或处理失败也不转成普通消息 |
|
|
66
|
+
| 有效`bind.request` | 保存申请方签名及待审批标记,再发布本地`ownership.request` |
|
|
67
|
+
| 有效`bind.response` | 合并对端签名;签名齐全时进入active,subject推进名片发布与托管 |
|
|
68
|
+
| `bind.reject` | 核对sender、请求ID和proof后记录rejected |
|
|
69
|
+
| `escrow.ready` | owner核对active关系,下载、导入identity并代上传 |
|
|
70
|
+
| `agent_md.updated` | subject下载、分别验签并同步名片 |
|
|
71
|
+
| `release.request` | subject验证原owner及当前关系证据,持久化释放任务后启动恢复 |
|
|
72
|
+
|
|
73
|
+
普通后续消息必须关联本地同一`request_id`、`proof_id`与双方AID,待审批或rejected记录不能被后续消息推进。release使用独立请求ID,并匹配原关系proof;即使本地关系metadata缺失,也须从本地名片取得同一完整有效proof后才能处理。
|
|
74
|
+
|
|
75
|
+
SDK自产消息总有sender与独立签名封套。当前TS绑定接收实现对缺少sender字段的内部消息对象存在兼容分支;真实消息接收应传入已有消息层确认的`from_aid`/`from`,不能只由payload决定来源。所有控制发送走加密P2P,沿用持久消息默认值,不设置volatile TTL。
|
|
76
|
+
|
|
77
|
+
## 5. 编排双向绑定与self-owner
|
|
78
|
+
|
|
79
|
+
owner发起:保存owner单签pending记录,发送`bind.request`;subject持久化待审批申请;subject应用接受时签署自己的声明,保存完整proof并标记active,再发送`bind.response`。subject立即发布完整proof名片,不等待identity托管;发起方收到有效响应后合并并标记active。
|
|
80
|
+
|
|
81
|
+
subject发起:保存subject单签pending记录,先尝试发布不完整proof名片,再发送`bind.request`;owner应用接受后签署owner声明并回复;subject验证响应后发布完整proof名片并托管identity。
|
|
82
|
+
|
|
83
|
+
完整proof发布和托管分别尝试、分别持久化进度。名片发布失败时保留已签署的pending内容,仍启动托管;托管失败不回退active关系或撤销公开proof。
|
|
84
|
+
|
|
85
|
+
接受/拒绝API只操作待审批申请。拒绝只发送`bind.reject`并记录rejected;当前实现不自动回滚已发布的subject单方名片。名片中不完整声明保持`incomplete`,不授予owner代上传权限。
|
|
86
|
+
|
|
87
|
+
self-owner在本地生成`role: subject`的单签proof,省略`owner_signature`,标记active并自行上传名片。它没有绑定消息、外部审批或escrow。
|
|
88
|
+
|
|
89
|
+
## 6. identity托管与owner代上传
|
|
90
|
+
|
|
91
|
+
subject将当前identity打包为UTF-8 JSON,使用协议固定AES-256-GCM封套加密,写入自己的`default` bucket:`/.aun/ownership/<subject_aid>/<proof_id>.json`。然后向owner写入该路径的`r` ACL,申请含`viewer_aid: owner_aid`的下载票据,通过加密`escrow.ready`发送下载地址、密码和明文摘要。
|
|
92
|
+
|
|
93
|
+
下载地址沿用Storage约定,优先取票据的`logical_url`,其次`download_url`、`url`。`logical_url`使用服务配置的对外数据面入口,可避免公开AID地址重定向后丢失认证头;测试网络也必须能解析该服务域名。
|
|
94
|
+
|
|
95
|
+
owner处理顺序:下载封套 → 解密和校验明文摘要 → 校验包内AID、证书CN和公私钥匹配 → 导入既有身份存储 → 使用subject signer代签名片。当前代码复用名为`importGroupIdentity`/`import_group_identity`的通用导入能力,该名称不意味着托管对象必须是group。
|
|
96
|
+
|
|
97
|
+
| 运行环境 | 已有存储约定 | 恢复方式 |
|
|
98
|
+
| --- | --- | --- |
|
|
99
|
+
| TS / Python / Go文件型SDK | `{aunPath}/AIDs/{subjectAid}/private/key.json`及`public/cert.pem` | 私钥沿用本地seed加密;重启后用同一store加载subject |
|
|
100
|
+
| JS浏览器 | IndexedDB `aun-keystore`中的`key_pairs`、`certs` | 沿用`IndexedDBIdentityStore`及其seed配置 |
|
|
101
|
+
|
|
102
|
+
关系metadata保存proof和进度,运行时`subject_identity`仅作缓存。`subject_identity`、`escrow_password`、`escrow_download_url`排除在公开摘要和顶层持久化关系字段之外。密码/地址丢失后,通过重发绑定响应、重新生成escrow通知恢复;owner已经导入的私钥从身份存储恢复。
|
|
103
|
+
|
|
104
|
+
当前metadata保存完整`pending_message`用于发送重试;不要把整个内部记录视为通用的秘密过滤器。移植时沿用控制消息与托管通知的实际持久化边界,公开日志或状态不得透出identity与密码。
|
|
105
|
+
|
|
106
|
+
agent.md发布同时复用`AgentMdManager`的待上传机制:持久化已经签署的完整内容及ETag;重试前以远端HEAD核对ETag,已经写入则完成本地状态,否则重发保存的签名版本。重试时重新签文件会改变内容与ETag,破坏这项判断。
|
|
107
|
+
|
|
108
|
+
owner代上传保持两种身份:subject私钥签文件,owner私钥签`X-AUN-AgentMD-Owner-Authorization`。授权绑定目标、上传者、完整HTTP正文摘要、时间戳和nonce。跨issuer下载使用资源域票据;同issuer可使用当前token getter,避免将本域JWT发给外域Storage。
|
|
109
|
+
|
|
110
|
+
## 7. metadata与恢复顺序
|
|
111
|
+
|
|
112
|
+
各端使用`ownership_records`,关系键为`<lowercase_subject_aid>|<lowercase_owner_aid>`。状态是本地编排信息,协议不要求服务端建立同样的状态表。
|
|
113
|
+
|
|
114
|
+
| 字段 | 保存内容与用途 |
|
|
115
|
+
| --- | --- |
|
|
116
|
+
| `subject_aid`、`owner_aid`、`type`、`request_id`、`proof_id` | 关系定位与当前请求关联 |
|
|
117
|
+
| `subject_statement/signature`、`owner_statement/signature` | 原始签署内容与完整关系证据 |
|
|
118
|
+
| `status` | `pending`、`active`、`rejected`、`release_pending`、`released`;无记录查询为`legacy_unbound` |
|
|
119
|
+
| `ownership_request_pending` | 等待应用确认;重连后再次发布请求事件 |
|
|
120
|
+
| `pending_message` | 待发送的绑定申请、响应、拒绝或release控制消息 |
|
|
121
|
+
| `subject_proof_published`、`agent_md_uploaded` | subject完整proof发布与本端上传进度 |
|
|
122
|
+
| `agent_md_notified`、`agent_md_synced` | owner更新通知与subject同步进度 |
|
|
123
|
+
| `ownership_release`、`release_request_id`、`release_old_fingerprint` | 已签署释放声明、释放请求及旧身份定位 |
|
|
124
|
+
| `release_status` | owner侧`notified`;subject侧`pending_rekey`、`pending_agent_md`、`pending_upload`、`released` |
|
|
125
|
+
| `release_local_content`、`release_agent_md_payload`、`last_error` | 解绑名片基底、待构造/上传内容和最近恢复错误 |
|
|
126
|
+
|
|
127
|
+
具体文件布局和内部字段可按语言存储适配;对外的P2P字段必须保持协议名称。
|
|
128
|
+
|
|
129
|
+
```mermaid
|
|
130
|
+
flowchart TD
|
|
131
|
+
A[加载AID与ownership metadata] --> B{存在待释放阶段}
|
|
132
|
+
B -->|是| C[连接前恢复pending rekey并载入新身份]
|
|
133
|
+
C --> D[连接后优先推进解绑名片与上传]
|
|
134
|
+
B -->|否| E[连接及既有身份准入检查]
|
|
135
|
+
E --> F[恢复registration intent]
|
|
136
|
+
F --> G[重发pending_message]
|
|
137
|
+
G --> H[重发待审批事件,或推进active关系]
|
|
138
|
+
H --> I[subject重试名片与escrow]
|
|
139
|
+
H --> J[owner加载已导入identity,或重发绑定响应]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
TypeScript参考`_recoverOwnershipRekeyBeforeConnect()`、`_resumeOwnershipAfterConnect()`、`_resumeOwnership()`及`_sendOwnershipControl()`。发送前保存pending消息,发送成功后清除;恢复时继续原请求,不重新调用绑定API生成新proof。异步恢复失败保留记录,供之后的连接恢复继续。
|
|
143
|
+
|
|
144
|
+
## 8. 解绑实现顺序
|
|
145
|
+
|
|
146
|
+
1. 原owner从active记录读取原`proof_id`,签署release,持久化并发送`release.request`。self-owner没有外部owner释放入口。
|
|
147
|
+
2. subject核对sender、release与原关系证据,先持久化`pending_rekey`、旧证书指纹和本地名片快照,再调度任务。
|
|
148
|
+
3. rekey前保存新密钥的pending identity。恢复时先查远端证书是否已经对应pending公钥,再决定继续轮转,复用`AIDStore.rekey()`的现有恢复能力。
|
|
149
|
+
4. rekey完成后载入新AID,必要时断开旧连接并重新认证,进入`pending_agent_md`。
|
|
150
|
+
5. 下载远端名片;已经存在同一有效release则收敛完成;否则要求远端仍是待释放的完整关系。
|
|
151
|
+
6. 比较本地与远端尾部签名时间,较新者作为基底,同时间优先远端。移除owner/proof,保留其它frontmatter及正文,加入release并保存`pending_upload`。
|
|
152
|
+
7. 用新subject证书签名并走既有pending上传机制。上传成功后subject的`status`及`release_status`均为`released`。
|
|
153
|
+
|
|
154
|
+
针对同一关系避免并发启动多个rekey任务。owner仅记录`notified`,现行协议没有release完成响应;不要推导owner一定会自动变为released。Name Service依据已保存名片匹配原关系,普通上传不能直接清空或替换owner。
|
|
155
|
+
|
|
156
|
+
## 9. 移植验证入口与验收点
|
|
157
|
+
|
|
158
|
+
| 验证层次 | 现有入口 | 需要核对的行为 |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| 原语与Schema | [TS proof单元测试](../../ts/tests/unit/ownership-proof.test.ts)、[Python proof测试](../../python/tests/test_ownership_proof.py)、[Go proof测试](../../go/ownership_proof_test.go)、[JS proof测试](../../js/tests/unit/ownership-proof.test.ts) | canonical字节、独立扩展、signed_at、self-owner、非法/不完整proof和已移除摘要字段 |
|
|
161
|
+
| 编排与持久化 | [TS客户端测试](../../ts/tests/unit/client-agent-md-api.test.ts)、[Go客户端测试](../../go/ownership_client_test.go) | 申请审批、过期响应、消息拦截、identity导入、发送恢复、pending上传及release证据 |
|
|
162
|
+
| 跨SDK基础向量 | [Python conformance](../../python/tests/conformance/test_ownership_proof_cross_sdk.py) | 规范AID及旧三字段构造向量;现行v2与互验还需对照各端proof测试 |
|
|
163
|
+
| 单域端到端 | [Python ownership E2E](../../python/tests/e2e_test_ownership.py) | 双向绑定、托管故障后恢复、名片同步、解绑rekey、上传中断后重启恢复及旧owner上传被拒绝 |
|
|
164
|
+
| 跨语言端到端 | [cross-SDK用例集](../../tests/cross-sdk/cases.single-domain.json) | owner发起Python→TS、subject发起Go→JS |
|
|
165
|
+
| 跨域端到端 | [双域ownership测试](../../../docker-deploy/federation-test/tests/cross_domain_ownership.py) | 双域路由、资源域票据、owner授权与历史关系验签 |
|
|
166
|
+
|
|
167
|
+
移植时先验证原语,再验证单端编排,最后覆盖单域、跨SDK和双域链路。按仓库测试指南采用失败处停止和断点续跑;Kite/Docker环境按既有运行要求由使用者准备。以上为验收入口,本指南不将列举的用例等同于已通过的运行结果。
|
|
168
|
+
|
|
169
|
+
服务端校验对照:[Name Service上传处理](../../../extensions/services/nameservice/go/internal/httpserver/agentmd.go)、[Name Service Schema](../../../extensions/services/nameservice/go/internal/httpserver/agent_md_schema.go)。本实现的ownership字段见[Ownership协议定义](../protocol/Ownership协议定义.md);工作区的[agent.md Schema](../agent.md/SCHEMA.md)目前采用另一套Ownership 2.0声明契约,不能直接作为本协议的proof/escrow验收依据。
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# Ownership SDK编排指南(3.0)
|
|
2
|
+
|
|
3
|
+
本文定义 [Ownership 协议3.0](../protocol/Ownership协议定义3.0.md) 的主要应用场景与 SDK 编排契约。TypeScript 方法是拟定接口,用于说明调用和返回语义,不表示当前发布的 SDK 已提供这些方法。
|
|
4
|
+
|
|
5
|
+
参考基线为 Git 提交 `1f03bf2d` 中的 0.5.18:复用 Auth operation、幂等键、关系版本 CAS、证书校验和可恢复任务;保留2.0的各方独立文件声明,删除旧 SDK 的自动 identity 导入、代签、代上传和 ownership 专用 P2P 编排。当前工作区与该基线可能不同,实现时须按3.0契约核对。
|
|
6
|
+
|
|
7
|
+
## 1. 应用层快速接入
|
|
8
|
+
|
|
9
|
+
示例假设 `sub`、`owner`、`nextOwner` 分别是持有自己身份的 SDK 实例,已连接相应服务;托管关闭,服务能力完整。各方调用并列展示,实际由各自应用在独立进程中执行。应用通过自己的审批界面和已有消息传递 operation_id,各 SDK 都从关系权威重新读取上下文,不能把通知当作授权。
|
|
10
|
+
|
|
11
|
+
### 1.1 绑定
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const op = await sub.declareOwneraid('owner.agentid.pub', { idempotencyKey: 'bind-001' });
|
|
15
|
+
const id = op.operation_id;
|
|
16
|
+
await owner.declareSubaid('subject.agentid.pub', { operationId: id });
|
|
17
|
+
await sub.approveOwnershipOperation(id);
|
|
18
|
+
await owner.approveOwnershipOperation(id);
|
|
19
|
+
await sub.resumeOwnershipOperation(id);
|
|
20
|
+
await owner.resumeOwnershipOperation(id);
|
|
21
|
+
const checked = await sub.checkOwnershipConsensus('subject.agentid.pub');
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`declare*` 生成本端签名文件证据;证据齐全后上下文冻结,应用确认后才调用 `approveOwnershipOperation`。两方授权齐全后,任一参与方可通过 resume 推进提交;提交后双方各自 resume 发布自己的文件。SDK 不用一方身份上传另一方文件。
|
|
25
|
+
|
|
26
|
+
应用记录稳定的幂等键和 operation_id,不以“方法返回成功”判断关系全部完成。只有 `checked.authorized === true` 才开放需要完整 owner 共识的功能。
|
|
27
|
+
|
|
28
|
+
### 1.2 转移
|
|
29
|
+
|
|
30
|
+
`currentVersion` 来自当前权威关系查询。转移由当前 owner 创建,sub_aid 与新 owner 参与同一 operation:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const op = await owner.transferSubaid('subject.agentid.pub', 'next-owner.agentid.pub', {
|
|
34
|
+
expectedRelationVersion: currentVersion, idempotencyKey: 'transfer-001',
|
|
35
|
+
});
|
|
36
|
+
await sub.declareOwneraid('next-owner.agentid.pub', { operationId: op.operation_id });
|
|
37
|
+
await nextOwner.declareSubaid('subject.agentid.pub', { operationId: op.operation_id });
|
|
38
|
+
await owner.approveOwnershipOperation(op.operation_id);
|
|
39
|
+
await sub.approveOwnershipOperation(op.operation_id);
|
|
40
|
+
await nextOwner.approveOwnershipOperation(op.operation_id);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
之后各方用该 operation_id 调用 resume。当前 owner 的同意、sub_aid 的同意和新 owner 的接受缺一不可。版本冲突时重新读取关系并重新审批,SDK 不自动用最新版本覆盖原 expected version。
|
|
44
|
+
|
|
45
|
+
### 1.3 解绑
|
|
46
|
+
|
|
47
|
+
当前 owner 发起释放:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const op = await owner.revokeSubaid('subject.agentid.pub', { idempotencyKey: 'release-001' });
|
|
51
|
+
await owner.approveOwnershipOperation(op.operation_id);
|
|
52
|
+
await owner.resumeOwnershipOperation(op.operation_id);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
sub_aid 也可以调用 `revokeOwneraid({ idempotencyKey })` 发起解绑意向,但仍等待当前 owner 的 approval。未获授权时原关系保持 active,不能改文件后绑定别的 owner。解绑提交后,sub_aid 恢复在线时自行 resume,清除自己的 owner 字段并上传。
|
|
56
|
+
|
|
57
|
+
若旧 owner 曾拿到可解密身份材料,转移和解绑会先等待第5节的凭据隔离,不能直接按以上无托管示例提交。
|
|
58
|
+
|
|
59
|
+
## 2. SDK契约与职责
|
|
60
|
+
|
|
61
|
+
### 2.1 主要方法
|
|
62
|
+
|
|
63
|
+
| 方法 | 调用者 | 行为 |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `declareOwneraid(owner_aid, options)` | sub_aid | unbound 时创建 bind 并提交本端文件证据;给定 operationId 时加入对应 bind/transfer,不能替换当前 owner。 |
|
|
66
|
+
| `declareSubaid(sub_aid, { operationId })` | 拟绑定/新 owner | 加入已有操作,提交自己 owner.md 的签名证据。 |
|
|
67
|
+
| `transferSubaid(sub_aid, new_owner_aid, options)` | 当前 owner | 创建 transfer,固定当前 owner 与 expectedRelationVersion,不直接解绑。 |
|
|
68
|
+
| `revokeSubaid(sub_aid, options)` | 当前 owner | 创建 release,使用当前关系证据,不直接删除文件代替解绑。 |
|
|
69
|
+
| `revokeOwneraid(options)` | sub_aid | 创建 release 意向,不能替当前 owner 授权。 |
|
|
70
|
+
| `approveOwnershipOperation(operation_id)` | 该操作的批准者 | 校验完整固定上下文,显式签署并提交本端角色的 approval;不自动批准其它意向。 |
|
|
71
|
+
| `resumeOwnershipOperation(operation_id)` | 参与方 | 先查询权威阶段,继续本端任务;ready 时尝试幂等提交,committed 时只做发布/清理。 |
|
|
72
|
+
| `cancelOwnershipOperation(operation_id)` | 发起者或必须授权的参与方 | 仅取消未提交操作,不回滚已完成的 rekey,不释放当前关系。 |
|
|
73
|
+
| `checkOwnershipConsensus(sub_aid)` | 校验方 | 读取权威与双方文件,返回授权结论和可持久化证据。 |
|
|
74
|
+
|
|
75
|
+
TypeScript options 使用 camelCase,协议数据使用 snake_case;其它语言采用自己的命名约定。SDK 的既有 Result/异常封装可以保留,但必须暴露下列分离的结果:
|
|
76
|
+
|
|
77
|
+
| 返回信息 | 含义 |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `operation_id`、`stage`、`waiting_for` | 意向已保存以及尚缺的参与方/任务。 |
|
|
80
|
+
| `committed`、`commit_receipt`、`relation_version` | 权威关系是否已提交及不可变提交结果。 |
|
|
81
|
+
| `publication_state`、`cleanup_state` | 必需文件是否公开收敛,旧文件与元数据是否清理。 |
|
|
82
|
+
| `custody_state` | 可选托管自己的进度,不决定关系提交成功与否。 |
|
|
83
|
+
| `authorized`、`document_state` | 当前完整共识检查结果,不能用本地缓存替代。 |
|
|
84
|
+
|
|
85
|
+
默认调用只推进目前具备条件的阶段,返回等待原因,不无限等待另一方或文件服务。恢复可以由应用显式调用,也可以由 SDK 重连调度;重连只重试已经批准的任务,不代用户批准新操作。
|
|
86
|
+
|
|
87
|
+
### 2.2 托管方法
|
|
88
|
+
|
|
89
|
+
托管能力独立提供启用、查询、撤销和显式恢复入口。启用只能由 sub_aid 发起,应用提供 custodian、加密秘密或自己的密钥包装方式;默认 custodian 只拿密文。恢复在 sub_aid 自己的设备中显式解密、验证并导入,owner 客户端不装载 sub_aid 身份。
|
|
90
|
+
|
|
91
|
+
无托管能力时,上述绑定、转移、解绑仍可使用;历史私钥外发带来的凭据隔离要求不能一起关闭。
|
|
92
|
+
|
|
93
|
+
### 2.3 编排边界
|
|
94
|
+
|
|
95
|
+
| 执行者 | 职责 |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| 应用 | 发起意向、通知参与方、确认审批、管理恢复秘密和业务审计。 |
|
|
98
|
+
| 各方 SDK | 本端签名、证据提交、自有文件发布、任务持久化、能力判断与恢复。 |
|
|
99
|
+
| sub_aid 的关系权威 | 验证参与者与证据、保存 operation、CAS 提交关系及审计回执。 |
|
|
100
|
+
| Name Service / Storage | 校验当前版本与上传者、条件写入/删除、存储文件和可选密文。 |
|
|
101
|
+
| Auth/CA | 证书、身份代际、必要的 rekey 与旧凭据失效确认。 |
|
|
102
|
+
|
|
103
|
+
SDK不能把整个流程包装成一个必须全部成功才能返回的跨服务事务。稳定阶段为:
|
|
104
|
+
|
|
105
|
+
```mermaid
|
|
106
|
+
flowchart LR
|
|
107
|
+
P[prepared<br/>参数及准备任务已保存] --> A[awaiting_approvals<br/>证据与上下文已冻结]
|
|
108
|
+
A --> R[ready<br/>授权及安全条件齐全]
|
|
109
|
+
R --> C[committed<br/>权威关系与回执已保存]
|
|
110
|
+
C --> D[completed<br/>投影及清理已收敛]
|
|
111
|
+
P --> X[取消或过期<br/>原关系保留]
|
|
112
|
+
A --> X
|
|
113
|
+
R --> X
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
只有 ready→committed 是关系权威内部的小事务。可选托管另外计进度;completed 不等待可选托管服务恢复。
|
|
117
|
+
|
|
118
|
+
## 3. 绑定与转移流程
|
|
119
|
+
|
|
120
|
+
### 3.1 绑定
|
|
121
|
+
|
|
122
|
+
```mermaid
|
|
123
|
+
sequenceDiagram
|
|
124
|
+
participant S as sub_aid SDK
|
|
125
|
+
participant O as owner_aid SDK
|
|
126
|
+
participant R as sub_aid关系权威
|
|
127
|
+
participant N as Name Service
|
|
128
|
+
participant T as owner_aid Storage
|
|
129
|
+
S->>S: 保存intent与幂等键
|
|
130
|
+
S->>R: prepare bind,匹配unbound当前版本
|
|
131
|
+
R-->>S: operation_id、目标版本
|
|
132
|
+
S->>R: 本端签名agent.md证据
|
|
133
|
+
O->>R: 本端签名owner.md证据
|
|
134
|
+
R->>R: 验证证据,冻结操作上下文
|
|
135
|
+
S->>R: 应用确认后的sub_approval
|
|
136
|
+
O->>R: 应用确认后的owner_approval
|
|
137
|
+
R->>R: 授权齐全,持久化ready
|
|
138
|
+
S->>R: commit同一operation
|
|
139
|
+
R->>R: CAS关系、保存回执与审计
|
|
140
|
+
R-->>S: committed,新版本
|
|
141
|
+
par 各方自行发布
|
|
142
|
+
S->>N: 本端签名、本端认证上传agent.md
|
|
143
|
+
and
|
|
144
|
+
O->>R: 查询提交回执
|
|
145
|
+
O->>T: 本端签名、本端认证写owner.md
|
|
146
|
+
end
|
|
147
|
+
S->>R: 发布状态与当前关系复核
|
|
148
|
+
Note over S,T: 发布失败保留committed;共识功能等待完整投影
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
初始绑定为版本0→1;解绑后重绑使用保留的当前版本,例如5→6。SDK不能写死 expected version=0。self-owner 复用这条流程,由同一 AID 完成重合角色,仍创建两种文档投影,不启用自动托管。
|
|
152
|
+
|
|
153
|
+
owner应用希望发起绑定时,先通过已有消息邀请sub_aid创建上述operation,再由owner加入;不允许拟绑定owner单方面抢占一个尚未同意的sub_aid操作。
|
|
154
|
+
|
|
155
|
+
新注册场景先完成可独立使用的 AID 身份,再执行 bind;关系待审批不能锁死登录和普通消息通信。已有 owner 的 AID 不能被当作新注册身份重新初始化为 unbound。
|
|
156
|
+
|
|
157
|
+
### 3.2 三方转移
|
|
158
|
+
|
|
159
|
+
```mermaid
|
|
160
|
+
sequenceDiagram
|
|
161
|
+
participant O as 当前owner SDK
|
|
162
|
+
participant S as sub_aid SDK
|
|
163
|
+
participant W as 新owner SDK
|
|
164
|
+
participant R as sub_aid关系权威
|
|
165
|
+
participant F as 各方文件服务
|
|
166
|
+
O->>R: prepare transfer,旧owner与版本v
|
|
167
|
+
R-->>O: operation_id,目标版本v+1
|
|
168
|
+
Note over O,R: 旧owner关系保持active;新owner尚无权限
|
|
169
|
+
opt 旧身份材料或权限需要隔离
|
|
170
|
+
S->>S: 完成持久化的凭据隔离任务
|
|
171
|
+
S->>R: 提交身份权威与资源服务确认回执
|
|
172
|
+
end
|
|
173
|
+
S->>R: 新owner关系的agent.md签名证据
|
|
174
|
+
W->>R: 新owner的owner.md签名证据
|
|
175
|
+
R->>R: 固定证据摘要与上下文
|
|
176
|
+
O->>R: old_owner_approval
|
|
177
|
+
S->>R: sub_approval
|
|
178
|
+
W->>R: new_owner_approval
|
|
179
|
+
R->>R: 全部验证通过,进入ready
|
|
180
|
+
O->>R: commit
|
|
181
|
+
R->>R: CAS直接切换owner,版本v+1
|
|
182
|
+
R-->>O: 不可变提交回执
|
|
183
|
+
Note over O,F: v的关系权限已失效,不等待文件删除
|
|
184
|
+
S->>F: 自签自传agent.md
|
|
185
|
+
W->>R: 查询回执
|
|
186
|
+
W->>F: 自签自写owner.md
|
|
187
|
+
O->>F: 条件删除自己的旧owner.md
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
一方拒绝或离线时停留在 awaiting_approvals;过期或取消不改变当前关系。提交响应丢失时先查询 operation,不能重新转移一次。提交后文件缺失只影响完整共识,不让旧 owner 权限复活。
|
|
191
|
+
|
|
192
|
+
## 4. 解绑流程
|
|
193
|
+
|
|
194
|
+
```mermaid
|
|
195
|
+
flowchart TD
|
|
196
|
+
S[sub_aid发起release意向] --> P[准备release<br/>保存当前owner、版本与旧声明证据]
|
|
197
|
+
O[当前owner发起release] --> P
|
|
198
|
+
P --> G{需要凭据或旧权限隔离?}
|
|
199
|
+
G -->|是| I[完成各项隔离并保存回执]
|
|
200
|
+
G -->|否| A[等待当前owner签署approval]
|
|
201
|
+
I --> A
|
|
202
|
+
A --> R[ready<br/>复核当前owner与版本]
|
|
203
|
+
R --> C[小事务提交unbound<br/>保留relation_id、版本加一]
|
|
204
|
+
C --> D[旧版本管理权限立即失效]
|
|
205
|
+
D --> OS[owner自行条件删除旧owner.md]
|
|
206
|
+
D --> SS[sub_aid自行移除owner及ownership<br/>重新签名上传agent.md]
|
|
207
|
+
OS --> Q[分别记录完成;失败各自续跑]
|
|
208
|
+
SS --> Q
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
当前 owner 授权足以提交 release;sub_aid 离线时不会要求代签或代上传,而是保留该端发布任务。必须由 sub_aid 执行的私钥隔离尚未完成时,owner也只能等待,不能以离线为由绕过。
|
|
212
|
+
|
|
213
|
+
release使用已归档的旧关系声明及原提交回执;sub_aid完成rekey后旧证书虽然失去实时签名资格,仍可用于验证当时已验收的精确历史文件,不必让离线sub_aid重签旧声明。
|
|
214
|
+
|
|
215
|
+
release 后允许再绑定,新 bind 必须由 sub_aid 与拟绑定 owner 重新授权,并使用最新版本。主动转移优先使用 transfer,避免把计划中的转移拆成 release+bind 暴露 unbound 窗口。
|
|
216
|
+
|
|
217
|
+
## 5. 可选托管与凭据隔离
|
|
218
|
+
|
|
219
|
+
### 5.1 独立启用与恢复
|
|
220
|
+
|
|
221
|
+
```mermaid
|
|
222
|
+
sequenceDiagram
|
|
223
|
+
participant A as sub_aid应用
|
|
224
|
+
participant S as sub_aid SDK
|
|
225
|
+
participant T as Storage或托管服务
|
|
226
|
+
participant K as custodian
|
|
227
|
+
participant D as sub_aid恢复设备
|
|
228
|
+
A->>S: 显式启用托管,提供密钥管理方式
|
|
229
|
+
S->>S: 加密身份材料,绑定AID与代际
|
|
230
|
+
S->>T: 幂等写入密文封套
|
|
231
|
+
S->>T: 以当前关系版本设置custodian读取授权
|
|
232
|
+
T-->>S: 对象与授权回执
|
|
233
|
+
S-->>A: custody状态;关系保持不变
|
|
234
|
+
K->>T: 验证版本后下载密文
|
|
235
|
+
K->>D: 应用安排交付密文
|
|
236
|
+
A->>D: 在恢复设备显式提供解密材料
|
|
237
|
+
D->>D: 检查代际、证书、私钥匹配后导入本端身份
|
|
238
|
+
Note over K,D: custodian不自动解密、导入或代sub_aid执行操作
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
密文上传失败、ACL失败、恢复失败分别保存进度;不能撤销已提交的 owner 关系。需要重建新 owner 托管时,先依据新关系重新授予权限,不复用旧 owner 的下载凭证。
|
|
242
|
+
|
|
243
|
+
### 5.2 旧 owner 曾持有可解密私钥
|
|
244
|
+
|
|
245
|
+
这是 transfer/release 的强制安全前置步骤,不属于可忽略的后台清理:
|
|
246
|
+
|
|
247
|
+
```mermaid
|
|
248
|
+
flowchart TD
|
|
249
|
+
H[权威外发记录显示私钥可能已交旧owner] --> F[持久化冻结新的身份材料外发<br/>确认旧授权不能继续续发]
|
|
250
|
+
F --> K[sub_aid本地生成并加密保存新密钥<br/>保存独立rekey幂等键]
|
|
251
|
+
K --> C[调用Auth/CA完成rekey]
|
|
252
|
+
C --> V[确认旧证书、token、会话、恢复凭据失效]
|
|
253
|
+
V --> G[保存新credential generation<br/>与隔离回执]
|
|
254
|
+
G --> E[使用新身份生成目标签名证据]
|
|
255
|
+
E --> A[冻结上下文,收集本次操作授权]
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
崩溃后先查询 rekey 状态和凭据代际,再使用已保存的新私钥续跑,不盲目再生成密钥;CA已完成而本地未记完成时,以远端证书与本地候选密钥匹配确认。旧授权已撤销、身份已轮换都是稳定事实,后续操作取消也不回滚这些事实。
|
|
259
|
+
|
|
260
|
+
旧关系此时仍保留,托管及需完整共识的功能可以暂时降级。关系准备失败不恢复旧私钥,也不把新的密钥再次交给旧 owner。身份恢复或资源服务缺少可查询的幂等确认能力时,SDK返回能力不足并停止在提交前。
|
|
261
|
+
|
|
262
|
+
不支持权限版本检查的服务,还须在提交前撤销旧ACL/票据并阻断继续签发;支持版本检查的服务在关系CAS提交后立即拒绝旧版本,ACL元数据可以异步清理。
|
|
263
|
+
|
|
264
|
+
## 6. 持久化与崩溃恢复
|
|
265
|
+
|
|
266
|
+
SDK本地至少持久化:intent、幂等键、operation_id、authority issuer、操作角色与参数、期望/目标版本、冻结上下文、本端签名证据和approval、各准备/发布/清理任务进度及回执。密钥候选与解密秘密使用既有安全身份存储,不能放入公开状态或日志。
|
|
267
|
+
|
|
268
|
+
每个外部副作用遵循“先保存任务输入→幂等执行→查询或保存回执”。收到回执后才能更新本端完成标志;重试沿用原始内容和幂等键。服务端回执必须在对应阶段持久化后返回。
|
|
269
|
+
|
|
270
|
+
服务端重启恢复失败时,SDK将权威判为不可用,不把查不到数据解释成unbound,也不根据本地文件重建一条未经授权的关系。
|
|
271
|
+
|
|
272
|
+
```mermaid
|
|
273
|
+
flowchart TD
|
|
274
|
+
B[启动、重连或应用resume] --> Q[按operation_id查询权威阶段和当前关系]
|
|
275
|
+
Q --> U{权威可用?}
|
|
276
|
+
U -->|否| W[保留本地任务<br/>只读或离线等待]
|
|
277
|
+
U -->|是| T{操作阶段}
|
|
278
|
+
T -->|prepared| P[继续本端证据和安全准备]
|
|
279
|
+
T -->|awaiting_approvals| A[重发已批准的本端授权<br/>等待缺失参与方]
|
|
280
|
+
T -->|ready| C[重试同一operation的CAS提交]
|
|
281
|
+
T -->|committed| D[读取原回执<br/>只续跑本端发布与清理]
|
|
282
|
+
T -->|completed| F[返回原结果]
|
|
283
|
+
T -->|取消、失败或过期| X[保留权威当前关系与审计<br/>停止旧操作的发布]
|
|
284
|
+
P --> Q
|
|
285
|
+
A --> Q
|
|
286
|
+
C --> Q
|
|
287
|
+
D --> Q
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
| 中断点 | 恢复规则 |
|
|
291
|
+
| --- | --- |
|
|
292
|
+
| prepare已完成但响应丢失 | 用原幂等键查询/重发,取回同一operation_id。 |
|
|
293
|
+
| 证据或approval已验收但响应丢失 | 查询已接收字段;原字节重发,不替换上下文。 |
|
|
294
|
+
| rekey完成但本地尚未更新 | 查询身份代际,匹配已保存候选密钥,再确认旧凭据隔离。 |
|
|
295
|
+
| ready之后、提交之前 | 重新检查期限、版本、当前owner、凭据代际;冲突不自动重签。 |
|
|
296
|
+
| CAS提交成功但响应丢失 | 查询operation得到committed回执,不能当成失败创建另一次提交。 |
|
|
297
|
+
| 关系提交后某一份文件未上传 | 各方补发自己的文件;缺少该方不能由其它方补签/代上传。 |
|
|
298
|
+
| 文件上传或删除成功但本地未记完成 | HEAD/GET核对关系字段、签名、版本或条件删除结果,再记录任务完成。 |
|
|
299
|
+
| 更晚的关系操作已经提交 | 原回执永久保留;旧发布/删除任务标为superseded,不覆盖新owner文件。 |
|
|
300
|
+
| 可选托管失败 | 独立重试托管任务,不改变committed关系,不阻塞基本通信。 |
|
|
301
|
+
|
|
302
|
+
公开发布使用最新文档与ETag条件,合并关系字段时保留最新业务正文;必要时由文件所属AID重新签名,不替换operation中已冻结的原始证据。删除旧owner.md同时比较旧关系版本及文档ETag,避免旧清理任务删除后续重新绑定产生的新文件。
|
|
303
|
+
|
|
304
|
+
权威比本地状态优先:本地active不证明当前关系;已committed操作不会因TTL到期变回expired。发生网络不确定性时返回“结果待查询”,不能猜测提交失败。
|
|
305
|
+
|
|
306
|
+
## 7. 功能降级与审计接入
|
|
307
|
+
|
|
308
|
+
### 7.1 降级处理
|
|
309
|
+
|
|
310
|
+
| 场景 | SDK返回/处理 | 可继续的功能 |
|
|
311
|
+
| --- | --- | --- |
|
|
312
|
+
| 未启用托管或托管临时不可用 | `custody_state=disabled/pending` | 未外发私钥前提下的关系操作及普通通信。 |
|
|
313
|
+
| 参与方离线或未授权 | `waiting_for`指明缺失方 | 保留旧关系,等待同一operation;普通通信继续。 |
|
|
314
|
+
| 关系权威不可用 | `authority_unavailable`或本地intent待提交 | 历史声明展示与普通通信;需owner授权的操作暂停。 |
|
|
315
|
+
| 提交后文件发布不完整 | `committed=true`,`document_state=pending`,`authorized=false` | 重试投影与普通通信,不能声称完整共识。 |
|
|
316
|
+
| 服务仅支持旧协议 | `legacy_read`、`unsupported_capability` | 只读旧关系;升级后显式迁移,禁止自动走2.0绑定。 |
|
|
317
|
+
| 必需的隔离/撤权能力缺失 | 保留prepared,返回具体缺失能力 | 不涉及owner权限的业务;转移/解绑不提交。 |
|
|
318
|
+
|
|
319
|
+
SDK应分别探测控制面、文件服务、托管和凭据隔离能力,不以一个“支持ownership”布尔值掩盖缺项。升级迁移要导入真实的当前owner和既有私钥外发风险;迁移旧已托管身份时先完成隔离,不能只换schema版本。
|
|
320
|
+
|
|
321
|
+
### 7.2 需要owner关系的业务操作
|
|
322
|
+
|
|
323
|
+
应用先调用check,保存双方完整声明与签名文件、权威版本/回执和业务操作标识,再发起业务调用。服务端核对认证调用者、目标sub_aid和相同关系版本,重新授权并记录实际执行结果;如果期间发生转移/解绑,拒绝旧版本请求。审计不能只引用将来可能消失的owner.md URL。
|
|
324
|
+
|
|
325
|
+
SDK不得把“文件互相匹配”“当前权威active”“所有文件已发布”“业务操作已被授权”合并成一个本地active标志。审计存储失败时,受管理操作不继续执行。
|
|
326
|
+
|
|
327
|
+
## 8. 实现验收场景
|
|
328
|
+
|
|
329
|
+
| 场景 | 必须观察到的结果 |
|
|
330
|
+
| --- | --- |
|
|
331
|
+
| sub_aid自行改owner、删除声明、改类型或重注册 | 不能改变权威关系;普通公开上传不得绕过当前owner。 |
|
|
332
|
+
| sub_aid先发起解绑再绑定新owner | 未获旧owner release授权,解绑不提交,新bind被拒绝。 |
|
|
333
|
+
| 转移缺少任意一方签名,或复用其它operation签名 | 不进入committed。 |
|
|
334
|
+
| 并发转移/解绑或同请求重试 | CAS至多一个成功;同operation重试不重复递增版本。 |
|
|
335
|
+
| 未提交时SDK或服务崩溃 | 已批准事实可查询并续跑,原owner保持不变。 |
|
|
336
|
+
| 权威持久化数据恢复失败 | 返回unavailable,不能重置版本或以空unbound允许新绑定。 |
|
|
337
|
+
| 提交后进程崩溃或上传失败 | 新关系保持稳定,只补发各自文件,旧版本权限不能继续使用。 |
|
|
338
|
+
| 已托管身份只删除ACL,没有撤销旧token/证书 | 不得作为已完成的凭据隔离,阻止转移/解绑提交。 |
|
|
339
|
+
| 关闭托管配置或旧协议迁移 | 不能抹除历史外发记录并绕过rekey。 |
|
|
340
|
+
| 旧cleanup在新一轮绑定后到达 | 条件删除/版本检查保护新文件,旧任务收敛为superseded。 |
|
|
341
|
+
| 权威不可用但两份旧文件完全匹配 | 只能返回document_consensus,authorized=false。 |
|
|
342
|
+
| 共识检查后关系被更改 | 服务端拒绝原版本的管理请求。 |
|
|
343
|
+
| 后续删除双方声明 | 已保存的原始签名文件、授权与回执仍能证明历史操作。 |
|
|
344
|
+
|
|
345
|
+
## 9. 参考实现位置
|
|
346
|
+
|
|
347
|
+
Git基线中的可复用实现为 `1f03bf2d:extensions/services/auth/go/internal/service/service.go`(operation、关系与CAS)、同目录 `owner_relation_test.go`(状态、期限和重启恢复)及 `1f03bf2d:aun-sdk-core/ts/src/aid-store.ts`(注册/绑定/转移编排)。这些是Git版本位置,不能把当前工作区中的同名实现直接认定为0.5.18。
|
|
348
|
+
|
|
349
|
+
本端签名、身份存储与文件原语可参考 [AIDStore](../../ts/src/aid-store.ts)、[AID](../../ts/src/aid.ts)、[agent.md](../../ts/src/agent-md.ts)。旧P2P流程见[原SDK实现指南](Ownership-SDK实现指南.md),只复用其持久化和恢复经验,不复用自动托管、代签、代上传行为。
|