ANP Profile 4:群组基础语义
- 文档编号:ANP-P4
- 标题:群组基础语义
- 状态:已发布
- 版本:1.2
- 规范集版本:ANP Messaging 1.2
- 语言:中文
- Profile:
anp.group.base.v2 - 依赖:
anp.core.binding.v1、anp.identity.discovery.v1 - 适用范围:本 Profile 适用于基于 Group DID 的群生命周期、群管理与群消息基础语义,不包含群端到端加密算法本身。
说明:本 v2 规范保留“自助加入、直接加人”两条路径:
group.invite、group.accept_invite与标准invitation对象保持在核心之外;membership_request、membership_request_digest、group.approve_membership、group.reject_membership保持在核心之外;group_policy收敛为message_security_profile + bootstrap_security_profile + admission_mode + permissions;- 非成员治理定向通知
group.governance_notice保持在核心之外;- 保留
group.state_changed作为群内有序状态通知。
1. 目的
本 Profile 定义 ANP 的群基础语义层,规定:
- Group DID 作为群的应用层全球标识;
- 群的创建、自助加入、直接加人、移除成员、离群、更新群资料、更新群策略等基础动作;
- 群消息
group.send的基础语义; - Group Host Service 的排序职责;
- Group E2EE Overlay 如何在本 Profile 的应用语义之上叠加。
- DID-only 成员关系,以及 Agent DID 被替代时由 Host 协调的连续性更新。
本 Profile 不定义:
- 具体群 E2EE 算法;
- 历史消息拉取;
- 已读与在线状态;
- 设备或内部副本概念;
- 群外部目录同步细节;
- 部署私有邀请链接、Join Token 或其它带外入群凭据的具体投递机制;
- 动态群状态如何存储在 Agent 内部。
2. 术语与规范性约定
2.1 规范性关键字
本文中的 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、RECOMMENDED、NOT RECOMMENDED、MAY、OPTIONAL 按照其大写形式解释为规范性要求。
2.2 术语
- Group:由
group_did标识的群协议主体。 - Group Host Service:负责该群的基础状态排序、策略应用与群消息入口的服务。
- Group State:一个群在某一时刻的应用层状态,包括资料、策略和成员关系等。
- Group State Version:由 Group Host Service 赋予的当前群状态版本标识。
- Group Event Sequence:由 Group Host Service 赋予的群事件单调递增序号,覆盖控制操作与群消息。
- Member:群中的 Agent 成员。
- Admission Mode:群对非成员默认开放的入群路径。本 Profile v2 的标准值为
admin-add、open-join。其中,中文“自动加入”在线协议取值上统一写作open-join。 - Policy:决定谁可以发消息、直接加人、移除成员、更新资料和更新策略的应用层规则。
- Origin Proof:由发起群操作或群消息的 Agent 按 P1 附录 A 的 ANP-02 消息绑定生成的应用层原发者证明。
- Group Receipt:由 Group Host 生成、用于证明某个群操作或群消息已被群接受并获得确定状态位置的可验证回执对象。
- Logical Target URI:为使应用层签名能够跨转发保持稳定,由 P1 附录 A 全局定义的逻辑目标 URI,而不是某一跳的具体 HTTP URL。
- Group State Changed Event:由 Group Host 排序并向当前活跃成员同步的群状态变化事件对象。
- 稳定主体路径(Stable Subject Path):验证
e1_DID 迁移时使用的 did:wba 方法内部路径约束;它不是 Messaging 身份或 wire 字段。 - 成员 DID 更新(Member DID Update):迁移经验证且被业务策略接受后,Group Host 原子替换活动成员记录当前
agent_did的状态变化。 - Host DID Update Action:保留动作标识
group.member_did_update,只用于状态事件和回执,不是客户端可调用的 JSON-RPC 方法。 - Continuity Assurance:P2 迁移验证结果,包括
verified、recovery_verified、provider_asserted或unverified。
3. 设计原则
3.1 一个群,一个 Group DID
每个群 MUST 具有一个 group_did。group_did 是该群的应用层全局标识,用于:
- 群发现;
- 群管理;
- 群消息寻址;
- 后续 Group E2EE Overlay 的绑定锚点。
3.2 Group Host 负责排序
所有会改变群状态的操作 MUST 经过 Group Host Service 接受与排序。
Group Host Service MUST 对群状态变更维护可判定的线性顺序,并为每次已接受的状态变更分配新的 group_state_version。
3.3 应用语义与密码学语义分离
本 Profile 只定义群的应用层动作与对象;具体的群密钥建立、成员加密状态演进、欢迎消息、加密应用消息等能力由 Group E2EE Profile 定义。
3.4 协议终点仍然是 Agent
群成员在协议层仍然是 Agent。任何 Agent 内部存在的副本、工作器、设备或终端均不进入本 Profile 的互通语义。
因此,一个 P4 业务成员及其角色均以一个 Agent DID 为作用域。成员关系、成员计数、角色检查、群治理、group.send、group.incoming 与 group.state_changed 均以 Agent DID 或 Group DID 寻址和判定。
Group E2EE Profile(P6)可将一个成员 DID 表示为多个设备级 MLS Leaf。增加、移除、轮换或撤销 P6 Leaf 本身 MUST NOT 增加或移除 P4 成员、更改其角色、影响成员计数或群策略,也不得产生 P4 状态变化事件。
3.5 非目标
本 Profile 不提供:
- 全局历史回放;
- 强同步语义;
- 设备级成员关系;
- 设备级投递;
- 内部执行器级权限控制;
- 标准化的审批流。
3.6 发起者认证与群结果见证分离
群场景中通常存在两种不同语义的签名:
- 发起者签名:证明某个
sender_did确实发起了该群操作或群消息; - 群结果见证:证明某个操作或消息已经被该群接受,并获得了确定的
group_state_version、group_event_seq或等价状态位置。
本 Profile 要求:
- 所有会改变群状态的请求,以及
group.send,MUST 携带发起者的auth.origin_proof; - 群 DID 的签名 SHOULD 出现在 Group Host 返回的
group_receipt中; - 接收方 MUST NOT 用群签名替代发起者签名,也 MUST NOT 用发起者签名替代群结果见证。
3.7 入群路径收敛
v2 核心中,非成员入群只保留两种标准动作:
group.join:目标 Agent 自主发起加入,并在成功时立即成为active成员;group.add:现有有权限成员直接把目标 Agent 加入群,并在成功时立即生效。
本 Profile v2 不定义标准 invitation 对象、invitation_id、group.invite 或 group.accept_invite。若部署需要邀请链接、Join Token 或其它带外凭据来辅助 group.join,这些能力 MUST 作为部署扩展处理,且 MUST NOT 在 group.join 成功前制造标准成员状态。
本 Profile v2 不定义标准化审批流,也 不在核心里引入 pending 中间治理状态。
3.8 DID-only 成员关系与 DID 连续性
P4 v2 只使用完整 Agent DID 作为 wire 成员身份:
group_member.agent_did是当前用于认证、授权、路由和安全 Overlay 的 DID;- 可读名称、名称服务记录、稳定主体路径和本地账户 ID MUST NOT 作为 P4 成员标识进入 wire;
- Group Host MUST NOT 仅凭名称、
alsoKnownAs或相同稳定主体路径推导连续性; - P2 从已保存旧 DID 验证到当前 DID,且 Group Host 业务策略接受其 assurance 后,Host 更新同一内部成员记录,而不是先退群再重新加入;
provider_asserted不由协议强制失败,由 Group Host 业务策略决定是否接受以及继承哪些成员授权;- 历史消息、回执、事件、签名和 DID MUST NOT 被重写。
DID 更新被接受后,role、status、joined_at、added_by 和活动成员数量保持不变,旧 DID 立即失去发起新操作的权限。
4. 群治理模型总览(非规范性)
4.1 规则总表
| 场景 | 入口方法 | 立即结果 | 权威对象 / 状态 | 何时成为 active | 备注 |
|---|---|---|---|---|---|
| 自助加入 | group.join | 调用方加入群 | group_member.status = active | 在本次加入中立即生效 | 仅适用于 open-join |
| 直接加人 | group.add | 目标被直接加入 | group_member.status = active | 在本次加人中立即生效 | 典型用于 admin-add |
| 成员主动离群 | group.leave | 成员退出群 | group_member.status = left | 不适用 | 只针对当前 active 成员 |
| 管理员移除成员 | group.remove | 成员被移出群 | group_member.status = removed | 不适用 | 仅适用于当前 active 成员 |
| 更新成员 DID | Host 协调的 group.member_did_update 动作 | 旧 DID 失去权限,被接受的后继 DID 成为当前 DID | 同一 group_member 保持 active | Group Host 原子接受更新时 | 不是客户端可调用方法 |
说明:若部署方通过带外邀请链接、Join Token 或站内提醒来引导加入,标准互通层最终仍 MUST 表现为一次
group.join或group.add的成功结果。
4.2 状态对象对照表
| 对象 | 关键状态 | 含义 |
|---|---|---|
group_member | active | 应用层成员资格已生效 |
group_member | left / removed | 成员关系已结束 |
4.3 状态机示意图
stateDiagram-v2
[*] --> NonMember
NonMember --> Active: group.join (open-join)
NonMember --> Active: group.add
Active --> Left: group.leave
Active --> Removed: group.remove
Active --> Active: Host 接受成员 DID 更新2
3
4
5
6
7
8
9
5. Profile 标识与依赖
5.1 Profile 名称
本 Profile 的标准名称为:
anp.group.base.v2
5.2 依赖关系
本 Profile MUST 依赖以下 Profile:
anp.core.binding.v1anp.identity.discovery.v1
5.3 安全模式
本 Profile 作为独立运行的基础群 Profile 时:
meta.profileMUST 等于anp.group.base.v2meta.security_profileMUST 等于transport-protected
若后续叠加 Group E2EE Overlay,则对应安全 Profile MUST 明确如何对本 Profile 的群状态对象与群消息对象进行密码学绑定。
6. 群模型
6.1 group_did
group_did 是群的应用层全局标识。
group_did:
- MUST 作为群管理操作的目标标识;
- MUST 作为群消息操作的目标标识;
- MUST NOT 自动等同于任何特定密码学实现中的内部
group_id。
6.2 group_state_version
group_state_version 表示当前群应用状态的版本。
其要求如下:
- MUST 由 Group Host Service 分配;
- MUST 作为不透明字符串处理;
- 每次成功的群状态变更 MUST 产生新的
group_state_version; - 群消息发送 MUST NOT 因消息本身推进新的
group_state_version; - 群消息成功响应中返回的
group_state_version表示该消息被接受时所属的群状态快照。
6.3 group_event_seq
group_event_seq 表示群事件序号。
其要求如下:
- MUST 在同一群内单调递增;
- MUST 覆盖群控制操作与群消息;
- MUST 采用十进制字符串表示;
- MUST NOT 直接作为安全语义的唯一依据。
P4 中最容易混淆的是:哪些动作推进群状态版本、哪些动作只推进群事件序、而 group_receipt 又到底锚定了哪一个位置。下图把这三者的关系集中画出,帮助读者建立统一理解。
flowchart TD
COps[群状态变更操作<br/>create / join / add / group.member_did_update / remove / leave / update_*]
Msg[group.send]
COps --> SV[推进 group_state_version]
COps --> SEQ[推进 group_event_seq]
Msg --> SEQ
Msg --> SNAP[引用当前 group_state_version 快照]
SV --> RC[group_receipt]
SEQ --> RC
SNAP --> RC
RC --> OUT[响应 / 通知中的锚定结果]2
3
4
5
6
7
8
9
10
11
12
13
14
15
图 P4-1:group_state_version、group_event_seq 与 group_receipt 的关系(非规范性)。
阅读后续 group.send、group.state_changed 与 group_receipt 语义时,应始终回到这张图:群消息参与事件排序,但不会因为消息本身推进新的 group_state_version。
6.4 角色模型
本 Profile 最小互通 MUST 支持以下角色:
owneradminmember
角色层级固定为:
owner > admin > member
解释规则如下:
- 当某动作要求最小角色为
member时,admin与owner自动满足; - 当某动作要求最小角色为
admin时,owner自动满足; - v1 最小互通范围内 MUST NOT 引入自定义角色。
角色分配给 DID 级 P4 业务成员;该 DID 下的设备或 MLS Leaf 不获得独立的 P4 角色。
6.5 成员状态
本 Profile 最小互通 MUST 支持以下成员状态:
activeleftremoved
7. 标准对象
7.1 group_policy
group_policy 表示群的应用层授权与入群规则对象。
推荐结构如下:
{
"message_security_profile": "transport-protected",
"bootstrap_security_profile": "transport-protected",
"admission_mode": "open-join",
"permissions": {
"send": "member",
"add": "admin",
"remove": "admin",
"update_profile": "admin",
"update_policy": "owner"
},
"attachments_allowed": true,
"max_members": "500"
}2
3
4
5
6
7
8
9
10
11
12
13
14
字段说明:
message_security_profile:字符串,SHOULD,推荐值:transport-protected、group-e2eebootstrap_security_profile:字符串,SHOULD,推荐值:transport-protected、group-e2eeadmission_mode:字符串,MUSTpermissions:对象,MUSTattachments_allowed:布尔值,MAYmax_members:十进制字符串,MAY
解释规则如下:
message_security_profile约束:group.send- 已成为
active成员之后的 member-only 群操作
bootstrap_security_profile约束:group.join- 以及后续 Overlay 明确定义的 onboarding / bootstrap 方法
admission_modeMUST 取以下之一:admin-addopen-join
permissionsMUST 包含且仅包含以下标准键:sendaddremoveupdate_profileupdate_policy
permissions.*的取值 MUST 为:owneradminmember
默认解释规则如下:
- 当
admission_mode = "admin-add"时,group.joinMUST 被拒绝;典型入群路径是group.add - 当
admission_mode = "open-join"时,group.joinMUST 被允许 group.add是否可用,仍由permissions.add决定
- 当
若存在
max_members,Group Host MUST 将其解释为active业务成员 DID 上限。同一 DID 下的多个设备或 MLS Leaf 仍只计为一个成员。
7.2 group_member
group_member 表示当前群成员关系对象。最小推荐字段:
agent_did:字符串,MUSTrole:字符串,MUSTstatus:字符串,MUSTjoined_at:RFC 3339 时间字符串,MAYadded_by:DID 字符串,MAY
说明:
role未明确时,接收方 MUST 解释为member;status = active表示应用层成员关系已生效;status = left或removed表示成员关系已终止;- 只有当前成员关系由
group.add建立时才建议提供added_by; agent_did始终表示当前用于认证、授权、消息、路由和安全 Overlay 的成员 DID;- 被接受的 DID 更新只改变当前
agent_did,其它成员元数据保持不变。
本 Profile 不定义或传输第二套、基于名称、稳定路径或本地数据库的成员身份。实现 MAY 在内部关联稳定本地记录,但该记录不是 ANP 标识,MUST NOT 用于跨域认证或授权。
group_member MUST NOT 包含设备标识或列表、设备 selector、设备级角色或状态、MLS Leaf 标识。
7.3 部署扩展入群凭据
本 Profile v2 不定义标准 invitation 对象,也 不定义 invitation_id。
若部署需要邀请链接、Join Token 或其它带外凭据来辅助 group.join,这些对象 MAY 存在,但它们:
- MUST NOT 被视为 v2 核心互通对象;
- MUST NOT 在
group.join成功前制造标准成员状态; - SHOULD 通过受控渠道传播。
7.4 group_profile
group_profile 表示群的展示性资料对象。
推荐字段:
display_name:字符串,创建群时 SHOULD 提供description:字符串,MAYavatar_uri:字符串,MAYdiscoverability:字符串,MAY,推荐值:private、listed、publiclabels:对象,MAY
7.5 group_state_ref
group_state_ref 表示群状态引用对象。
最小推荐字段:
group_did:字符串,MUSTgroup_state_version:字符串,MUSTpolicy_hash:字符串,MAYroster_hash:字符串,MAY
7.6 群消息负载
group.send 的 meta.content_type MUST 存在。
本 Profile 最小互通 MUST 支持以下内容类型:
text/plainapplication/jsonapplication/anp-attachment-manifest+json
group.send 的 body 中,text、payload、payload_b64u 三者中:
- MUST 恰好出现一个;
- 若出现多个,接收方 MUST 拒绝请求;
- 若三者均不存在,接收方 MUST 拒绝请求。
对于 payload_b64u:
- MUST 使用无填充 base64url;
- SHOULD 仅用于二进制扩展或私有扩展对象。
当 meta.content_type = "application/json" 时,body.payload MUST
直接承载 JSON 对象。本 Profile 不定义该对象内部字段的业务含义;群应用或
群宿主自行决定如何解释。
7.7 auth 对象
除 group.get_info 外,所有会改变群状态的请求,以及 group.send,其 params MUST 包含 auth 对象。
本节的 proof 承载规则、Signed Request Object 与签名组件映射 MUST 复用 P1 附录 A 的统一定义;P4 不再 定义独立的 proof 字段名、独立的 Signed Payload 结构或本地 @target-uri 映射。
推荐结构如下:
{
"auth": {
"scheme": "anp-rfc9421-origin-proof-v1",
"origin_proof": {
"contentDigest": "sha-256=:BASE64_SHA256_DIGEST:",
"signatureInput": "sig1=(\"@method\" \"@target-uri\" \"content-digest\");created=1733402096;expires=1733402156;nonce=\"abc123\";keyid=\"did:wba:example.com:user:alice:e1_<fingerprint>#key-1\"",
"signature": "sig1=:BASE64_SIGNATURE:"
}
}
}2
3
4
5
6
7
8
9
10
字段要求:
auth.schemeMUST 等于anp-rfc9421-origin-proof-v1auth.origin_proofMUST 存在于所有状态改变型群操作及group.sendauth本身 MUST NOT 进入contentDigest
7.8 Binding to the Shared Signed Request Object
auth.origin_proof.contentDigest MUST 绑定 P1 附录 A 定义的共享 Signed Request Object。
对 Group Base 而言:
- 对
group.send等消息类方法,meta.message_id与meta.content_typeMUST 存在 - 对
group.create,meta.target.kindMUST 为service - 对其它以既有群为目标的群操作,
meta.target.kindMUST 为group
7.8.1 Reference to the Global Component Mapping
所有要求 auth.origin_proof 的 Group Base 方法 MUST 使用 P1 附录 A 定义的全局签名组件映射。
因此:
- 对
group.create,验证方依据meta.target.kind = "service"重建@target-uri = anp://service/<pct-encoded meta.target.did> - 对面向既有群的群操作,验证方依据
meta.target.kind = "group"重建@target-uri = anp://group/<pct-encoded meta.target.did> - 上述结果来自 P1 的全局规则,而 不是 P4 独立定义的一套本地映射
7.9 group_receipt
group_receipt 表示某个群操作或群消息已被 Group Host 接受并写入该群状态机的可验证见证对象。
推荐字段:
receipt_type:字符串,MUST,推荐值:group-operation-accepted、group-message-acceptedgroup_did:字符串,MUSTgroup_state_version:字符串,MUSTgroup_event_seq:十进制字符串,MUSTsubject_method:字符串,MUSToperation_id:字符串,MUSTmessage_id:字符串,MAYactor_did:字符串,MUSTaccepted_at:RFC 3339 时间字符串,MUSTpayload_digest:字符串,MUSTproof:对象,SHOULD;当group_receipt会离开 Group Host 所在域并被其他域依赖时 MUST
group_receipt.proof MUST 复用 P1 附录 B 定义的共享 Object Proof Profile。
对 group_receipt 而言:
- issuer DID MUST 为
group_did - 被保护文档 MUST 是移除
proof后的整个group_receipt proof.verificationMethodMUST 指向group_didDID 文档中被assertionMethod授权的验证方法group_receipt的签名目的是证明“该群已接受此结果”,而不是证明“请求由谁发起”
除 P1 附录 B 的共享规则外,group_receipt 仍 MUST 至少包含并因此整体受 proof 保护以下安全关键字段:
receipt_typegroup_didgroup_state_versiongroup_event_seqsubject_methodoperation_idactor_didaccepted_atpayload_digest- 若存在
message_id,则也 MUST 包含并受保护
验证方在 group_receipt.proof 验证通过后,MUST 继续检查上述字段与实际响应、通知上下文及对应群状态位置一致。
7.10 群状态变化事件对象
7.10.1 共同字段
成员 DID 更新事件推荐结构:
{
"event_id": "evt-didupd-001",
"event_type": "member-did-updated",
"group_did": "did:wba:groups.example:team:e1_group",
"group_state_version": "43",
"group_event_seq": "129",
"subject_method": "group.member_did_update",
"changed_at": "2026-08-25T02:11:00Z",
"actor_did": "did:wba:groups.example",
"previous_subject_did": "did:wba:example.com:user:alice:e1_old",
"subject_did": "did:wba:example.com:user:alice:e1_current",
"membership_status": "active",
"group_receipt": { "...": "..." }
}2
3
4
5
6
7
8
9
10
11
12
13
14
共同规则:
group.state_changed.bodyMUST 直接承载事件对象;- 不得用于投递带外入群凭据或非成员提醒;
- SHOULD 与
group_event_seq保持相同有序语义; group.join与group.add映射为member-activated;- Host 动作
group.member_did_update映射为member-did-updated; group.remove映射为member-removed,存在membership_status时必须为removed;group.leave映射为member-left,存在membership_status时必须为left。
7.10.2 标准 event_type
P4 v2 推荐:
member-activatedmember-removedmember-leftmember-did-updatedgroup-profile-updatedgroup-policy-updated
member-did-updated MUST 包含 previous_subject_did、subject_did 和 membership_status = "active",且 MUST NOT 包含名称、稳定主体路径或稳定主体标识。其 subject_method MUST 为 group.member_did_update,actor_did MUST 为 Group Host 的 ANPMessageService.serviceDid,operation_id MUST 确定性绑定群、旧 DID 和新 DID,payload_digest MUST 覆盖该状态变化。回执只证明群接受并排序了更新,不能独立证明 DID 连续性。
8. 标准方法与通知
除 group.get_info 外,本节所有状态改变型方法的请求 MUST 满足以下通用规则:
params.auth.schemeMUST 等于anp-rfc9421-origin-proof-v1params.auth.origin_proofMUST 存在并绑定对应的 Signed Request Object- 若请求穿越域边界,原始
auth.origin_proofMUST 随消息一起转发且 MUST NOT 被中间服务重写
对所有被 Group Host 接受的状态改变型方法,以及 group.send:
- 在非跨域实现中,成功响应 SHOULD 返回
group_receipt - 当响应结果会离开 Group Host 所在域并被其他域依赖时,成功响应 MUST 返回
group_receipt,且返回的group_receipt.proofMUST 存在
以下两个 Notification / 异步消息方法:
group.incominggroup.state_changed
属于 OPTIONAL push capability。它们不是本 Profile 的最小互通必选方法;但一旦实现,发送方 MUST 使用本 Profile 定义的标准 Notification envelope 与标准 body 结构。
本节中的成员关系、角色、策略与群治理判定均以 DID 为作用域。普通 P4 请求或结果 MUST NOT 携带 meta.sender_device_id、meta.recipient_device_id、任何设备 selector 或列表,也不得携带逐设备结果。
8.1 group.create
8.1.1 语义
由 Group Host Service 创建新群并分配新的 group_did 与初始 group_state_version。
8.1.2 请求要求
group.create 请求 MUST 满足:
method = "group.create"meta.profile = "anp.group.base.v2"meta.security_profile = "transport-protected"meta.sender_didMUST 存在meta.target.kind = "service"meta.target.didMUST 等于目标ANPMessageService.serviceDidmeta.operation_idMUST 存在body.group_profileSHOULD 存在body.group_policyMUST 存在body.initial_membersMAY 存在params.auth.origin_proofMUST 存在
创建者只由 meta.sender_did 确定并成为活动 owner。
其它 initial_members 条目 MUST 包含 member_did,并 MAY 包含 role;非 DID target 非法。Group Host MUST 确认 DID 当前活动。若 DID 已被替代,MUST 返回 anp.did_superseded,且 MUST NOT 改写已签名请求。
8.1.3 成功响应
成功响应 MUST 至少包含 group_did、group_state_version、created_at 和 creator_did,并 MAY 包含 group_event_seq、group_profile、group_policy 和 group_receipt。
8.2 group.get_info
8.2.1 语义
获取当前群的基础信息快照。
8.2.2 请求要求
meta.target.kindMUST 为"group"meta.target.didMUST 为目标group_did
body MAY 包含:
include_policyinclude_member_list
身份要求如下:
- 当群的
discoverability = "public"或"listed"时,group.get_infoMAY 作为匿名读取调用;此时meta.sender_didMAY 省略; - 当群的
discoverability = "private"时,调用方 MUST 提供身份; - 若请求的投影超出调用方可见范围,接收方 MUST 返回
group.policy_violation。
8.2.3 成功响应
成功响应 MUST 至少包含:
group_didgroup_state_versiongroup_profile
成功响应 MAY 包含:
group_policy(仅当include_policy = true且调用方有权查看时)member_list(仅当include_member_list = true且调用方有权查看时;其元素类型 MUST 为group_member)member_count(十进制字符串;若存在,SHOULD 表示当前active成员数量)
若返回 member_list,其内容 SHOULD 仅包含当前 active 成员。
8.3 group.join
8.3.1 语义
group.join 供非成员自主加入,成功后调用方成为 active 成员。
8.3.2 请求要求
body MAY 包含 reason_text,但 MUST NOT 包含名称、稳定主体字段或其它成员标识;成员 DID 精确等于 meta.sender_did。若新 DID 对应旧 DID 已被替代的现有活动成员,Group Host MUST 先执行 8.12 节,再按当前成员状态处理。若群不处于 open-join 且没有更新既有成员关系,接收方 MUST 拒绝请求,并 SHOULD 返回 group.policy_violation。
8.3.3 成功响应
成功响应 MUST 包含 group_did、等于当前 meta.sender_did 的 member_did、membership_status = "active" 和 group_state_version,并 MAY 包含 group_receipt。
8.4 group.add
8.4.1 语义
有权限的成员直接添加一个目标 Agent DID;成功后目标立即成为 active 成员。
8.4.2 请求要求
body MUST 包含 member_did,并 MUST NOT 包含名称、稳定主体字段或其它成员标识;body MAY 包含 role 和 reason_text,省略 role 时解释为 member。Group Host MUST 确认 member_did 当前活动。若已被替代,Host MUST 返回 anp.did_superseded,且 MUST NOT 替换已签名请求中的 DID;调用方验证迁移、更新请求并重新签名。
8.4.3 成功响应
成功响应 MUST 包含 group_did、member_did、membership_status = "active" 和 group_state_version,并 MAY 包含 group_receipt。
8.5 group.remove
8.5.1 语义
由有权限的成员将某个当前 active 成员移出群。
8.5.2 请求要求
body MUST 包含:
member_did
body MAY 包含:
reason_text
8.5.3 处理规则
- 若目标当前处于
active,则group.removeMUST 使其group_member.status = "removed"; - 若目标已经是
left、removed或不存在,接收方 MUST 拒绝请求; - 接受之后,Group Host 按第 8.11 节发出
member-removed,包括发给被移除member_did的自身作用域最终 envelope。
8.5.4 成功响应
成功响应 MUST 至少包含:
group_didmember_didgroup_state_version
成功响应 MAY 包含:
membership_statusgroup_receipt
8.6 group.leave
8.6.1 语义
表示当前发送方主动退出群。
8.6.2 请求要求
meta.sender_didMUST 是当前离群成员
8.6.3 处理规则
- 接受后,离群者的
group_member.status变为left; - 接受后,Group Host 按第 8.11 节发出
member-left事件,包括发给已离群leaver_did的最终自身作用域信封。
8.6.4 成功响应
成功响应 MUST 至少包含:
group_didleaver_didgroup_state_version
成功响应 MAY 包含:
group_receipt
8.7 group.update_profile
8.7.1 语义
更新群展示资料对象。
8.7.2 请求要求
body MUST 包含:
group_profile_patch
group_profile_patch MUST 使用 RFC 7386 JSON Merge Patch 语义。
8.7.3 成功响应
成功响应 MUST 至少包含:
group_didgroup_state_versiongroup_profile
成功响应 MAY 包含:
group_receipt
8.8 group.update_policy
8.8.1 语义
更新群策略对象。
8.8.2 请求要求
body MUST 包含:
group_policy_patch
group_policy_patch MUST 使用 RFC 7386 JSON Merge Patch 语义。
8.8.3 成功响应
成功响应 MUST 至少包含:
group_didgroup_state_versiongroup_policy
成功响应 MAY 包含:
group_receipt
8.9 group.send
8.9.1 语义
向某群发送一条应用层群消息。
8.9.2 请求要求
一个合规的 group.send 请求 MUST 满足:
method = "group.send"meta.profile = "anp.group.base.v2"meta.security_profile = "transport-protected"meta.target.kind = "group"meta.target.didMUST 是目标group_didmeta.sender_didMUST 是当前发送方 Agent DIDmeta.message_idMUST 存在meta.operation_idMUST 存在meta.content_typeMUST 存在bodyMUST 满足负载互斥规则params.auth.origin_proofMUST 存在并绑定 Signed Request Objectmeta.sender_device_id、meta.recipient_device_id与任何其它设备 selector 或列表 MUST NOT 存在
8.9.3 group.send 的 body
group.send 的 body 可包含:
thread_id:字符串,MAYreply_to_message_id:字符串,MAYannotations:对象,MAYtext/payload/payload_b64u:三者中 MUST 恰好出现一个
8.9.4 成功响应
成功响应 MUST 至少包含:
accepted = truegroup_didmessage_idoperation_idgroup_event_seqgroup_state_versionaccepted_at
成功响应 MAY 包含:
group_receipt
该响应仅针对已接受的群事件,MUST NOT 包含逐设备接受、投递、回执或 fan-out 结果。
8.10 group.incoming
group.incoming 用于向当前活跃成员 Agent 异步推送一条已被 Group Host 接受的群消息。它 MUST 作为 Notification 使用。
若实现 group.incoming,其 Notification envelope MUST 满足:
meta.profile = "anp.group.base.v2"meta.security_profileMUST 等于该群消息被接受时的安全模式meta.target.kind = "agent"meta.target.didMUST 等于当前通知接收方 DIDmeta.sender_didMUST 等于原始群消息的业务发送方 DIDmeta.operation_idMUST 等于原始group.send.meta.operation_idmeta.message_idMUST 等于原始group.send.meta.message_idmeta.content_typeMUST 等于原始群消息的meta.content_type
推荐 body 结构如下:
{
"group_did": "did:example:group-123",
"group_state_version": "42",
"group_event_seq": "128",
"accepted_at": "2026-03-29T14:10:01Z",
"group_receipt": { "...": "..." },
"thread_id": "thr-001",
"reply_to_message_id": "msg-0009",
"annotations": {},
"text": "hello group"
}2
3
4
5
6
7
8
9
10
11
规则如下:
bodyMUST 承载与原始群消息一致的业务负载;- 若存在
params.auth,则:params.auth.schemeMUST 等于anp-rfc9421-origin-proof-v1params.auth.origin_proofMUST 为原始origin_proof的无损副本- 中间服务 MUST NOT 重写新的业务 proof。
group.incoming 只寻址到接收方 Agent DID。它 MUST NOT 携带 meta.sender_device_id、meta.recipient_device_id、任何设备 selector 或列表,也不得携带逐设备结果。接收域可以在内部将通知 fan-out 到本地设备,但该 fan-out 及其部分结果是域内实现,MUST NOT 出现在 P4 线协议中。
8.11 group.state_changed
group.state_changed 是群状态变化的标准异步通知方法,用于向当前活跃成员同步已排序的成员状态变化、群资料变化和群策略变化。它 MUST 作为 Notification 使用。
其 Notification envelope MUST 满足:
meta.profile = "anp.group.base.v2"meta.security_profile = "transport-protected"meta.target.kind = "agent"meta.target.didMUST 等于当前通知接收方 DIDmeta.sender_didMUST 等于body.group_didbodyMUST 直接承载且只承载一个第 7.10 节定义的 event 对象
group.state_changed MUST NOT 用于带外入群凭据投递、非成员提醒或任何替代 direct.send 的定向治理通知。
存在一个仅限于事件 subject 本身的例外。对 member-removed 或 member-left 事件,Group Host MUST 额外向该事件的 subject_did 发出一份最终 group.state_changed envelope,携带与其余 active 成员所收到的相同的已排序 event 对象。成员关系变化是双方共同的事实,缺少这份 envelope,被移除成员没有任何带内方式把"被移除"与"传输失败"区分开。因此这份自身作用域的最终通知不是非成员提醒、不是对局外人的治理广播,也不是凭据投递;上述禁令对其它所有非成员目标和其它所有事件类型继续适用。
该自身作用域的最终 envelope MUST 精确以该事件的 subject_did 为目标,不得指向任何其它非成员。它的重试与保留 MUST 受显式的部署上限约束,到限后 Group Host MAY 将它连同该 DID 的剩余投递状态一起丢弃;Group Host MUST NOT 为已移除或已离群成员无限期保留投递状态。因此投递是"必须尝试但不保证送达"的:无论该 envelope 是否到达,移除或离群都已生效,subject MUST NOT 把未收到它当作成员资格仍然存续的证据,后续请求收到的 group.not_member 拒绝仍是同等权威的同一终态信号。subject 处理该事件只用于收敛本地视图;该事件不授予任何持续成员资格、读取权限或治理地位。
group.state_changed 从 Group DID 寻址到接收方 Agent DID。它 MUST NOT 携带设备 selector 或列表,也不得暴露逐设备投递结果;成员域内的任何 fan-out 均属内部实现。
8.12 Host 协调的成员 DID 更新
group.member_did_update 是事件和回执使用的保留 Host 动作标识,不是 JSON-RPC 方法。客户端调用该方法时 MUST 返回 -32601 Method not found。
DID 缓存过期、已保存 DID 停用、投递失败、对端报告 DID 已被替代,或可能的后继 DID 发起请求时,Group Host MAY 触发更新。Host MUST 从活动成员记录保存的精确 agent_did 出发,按 P2 验证到候选当前 DID 的完整迁移。
接受更新前,Host MUST:
- 找到当前 DID 为旧 DID 的唯一活动成员记录;
- 取得旧 DID 到新 DID 的真实 P2 continuity assurance;
- 接受
verified或recovery_verified;provider_asserted由自身业务策略判断;unverifiedMUST NOT 建立连续性; - 确认新 DID 不属于另一活动成员,且不存在候选歧义、分叉、循环或可信缓存冲突;
- 通过 compare-and-swap 确认记录仍保存预期旧 DID。
接受后,Host MUST 原子替换当前 agent_did,保持其它成员元数据和活动成员数量,推进 group_state_version 与 group_event_seq,停止授权旧 DID,并追加一个 member-did-updated 事件和对应回执。
operation_id SHOULD 是 group_did、previous_subject_did 和 subject_did 的确定性摘要。历史消息、回执、事件、签名和 DID MUST NOT 被重写。
新 DID 在 roster 刷新前发起成员操作或 private group.get_info 时,Host 先完成更新并排序 member-did-updated,再以保留角色授权请求。向 roster 旧 DID 投递时发现经验证且被业务策略接受的后继,Host 先更新 roster,再为当前 DID 生成新的 group.incoming。
9. 流程图总览(非规范性)
9.1 自助加入路径(open-join)
sequenceDiagram
participant B as 申请方
participant H as Group Host
B->>H: group.join
H-->>B: membership_status = active2
3
4
5
6
9.2 直接加人路径(admin-add)
sequenceDiagram
participant A as 管理员
participant H as Group Host
participant B as 目标成员
A->>H: group.add
H-->>A: member_did + membership_status = active
H-->>B: group.state_changed / 或部署自定义通知2
3
4
5
6
7
8
9.3 群消息路径
sequenceDiagram
participant A as 发送方成员
participant H as Group Host
participant M as 其它成员
A->>H: group.send
H-->>A: accepted + group_event_seq
H-->>M: group.incoming2
3
4
5
6
7
8
9.4 Host 协调的成员 DID 更新
sequenceDiagram
participant H as Group Host
participant D as DID Resolver
participant M as 活动成员
H->>D: 解析已保存旧 DID 并验证迁移
D-->>H: 当前 DID + assurance
H->>H: 执行业务策略 + CAS 成员记录
H-->>M: group.state_changed(member-did-updated)2
3
4
5
6
7
8
9
Host 更新是有序群状态;通知可以异步投递,投递结果不决定状态是否生效。
10. 排序、并发与冲突
10.1 排序职责
Group Host Service MUST 为同一 group_did 的所有已接受事件维护线性顺序。排序覆盖:
group.creategroup.joingroup.add- Host 动作
group.member_did_update group.removegroup.leavegroup.update_profilegroup.update_policygroup.send
10.2 群消息与状态版本
group.send 被接受后:
- MUST 分配新的
group_event_seq; - MUST NOT 因消息本身推进新的
group_state_version; - 响应与
group_receipt中返回的group_state_version表示“该消息被接受时所属的群状态快照”。
10.3 幂等与去重
对于群状态变更与群消息,接收方 MUST 基于:
sender_didgroup_didmethodoperation_id
执行幂等判断。
对于 group.send,接收方 SHOULD 进一步基于:
sender_didgroup_didmessage_id
进行重复识别。
11. 安全与策略
11.1 安全传输要求
本 Profile 在独立运行时,MUST 依赖经过认证的安全传输层。
11.2 群操作发起者认证
对于所有状态改变型群操作以及 group.send:
- Group Host Service MUST 验证
auth.origin_proof; auth.origin_proof的keyid所属 DID MUST 与meta.sender_did一致;keyid指向的验证方法 MUST 被 DID 文档的authentication关系授权;- Group Host Service MUST 按 P2 方法验证验证主体 DID 文档,包括对应 DID 方法要求的绑定检查;
- proof 承载规则 MUST 同时满足 P1 附录 A 的共享 Origin Proof 约定。
11.3 发起者认证与群策略授权的关系
群内“谁能加人、踢人、更新资料、更新策略、发送消息”等权限,MUST 由 group_policy 决定。
具体而言,接收方 MUST 基于:
group_policy.permissions.sendgroup_policy.permissions.addgroup_policy.permissions.removegroup_policy.permissions.update_profilegroup_policy.permissions.update_policygroup_policy.admission_mode
判断当前请求是否被授权。
11.4 群 DID 签名的使用位置
群 DID 的签名 不是 客户端入站请求的第二签名。它的正确用途是:
- 对已接受的群状态变更结果进行见证;
- 对已接受的
group.send结果进行见证; - 为跨域调用方提供“该群确实接受了此操作 / 消息”的可迁移证明。
对 group_receipt.proof 而言,其 proof 语法、被保护文档与验证步骤 MUST 复用 P1 附录 B 的共享 Object Proof Profile。
11.5 跨域转发
若群操作或群消息经由其他服务转发:
- 原始
auth.origin_proofMUST 保持不变并随请求一起转发; - 目标 Group Host MUST 独立验证
auth.origin_proof; - 各服务跳之间 MUST 另外执行服务级身份认证。
11.6 Access Token 优化
ANP-02 的可选 access token 流程 MAY 用于优化调用方与 Group Host、或服务与服务之间的重复调用,但:
- access token MUST NOT 替代
auth.origin_proof; - sender-constrained access token SHOULD 优先于普通 Bearer token。
11.7 安全模式要求
若群策略中的 message_security_profile 要求 group-e2ee:
- 对
group.send以及已成为active成员后的 member-only 群操作,发送方 MUST 使用 Group E2EE Profile; - Group Host Service 收到
transport-protected的相关请求时 MUST 拒绝。
若群策略中的 bootstrap_security_profile 要求 group-e2ee:
- 对
group.join以及后续 Overlay 明确定义的 onboarding / bootstrap 方法,发送方 MUST 使用 Group E2EE Profile; - Group Host Service MUST NOT 在未显式协商的情况下静默降级到
transport-protected。
被接受的 member-did-updated 是 P4 业务状态变化。若群使用 E2EE,P6 MUST 独立验证 DID 迁移及其 assurance,确认 P4 roster 已使用新 DID,先添加选定的新 DID 设备 leaves,再移除旧 DID leaves。P4 接受不能替代 MLS Commit。
11.8 与 Overlay 的绑定点
后续 Group E2EE Overlay SHOULD 至少绑定以下字段:
group_didsender_didgroup_state_version或等价状态引用message_idcontent_typesecurity_profileauth.origin_proof.contentDigest或等价的原发者证明摘要
11.9 DID 迁移安全
- Group Host MUST 从成员记录保存的 DID 出发独立执行 P2 迁移验证;
alsoKnownAs、可读名称和相同稳定主体路径只能作为候选 hint,MUST NOT 独立授权更新;- Host MUST 保留真实 assurance;
provider_asserted由业务策略接受或拒绝,且 MUST NOT 被表示为更高 assurance; - 回执证明群接受并排序了更新,不表示其它验证方可以跳过 DID 迁移验证;
- 更新被接受后,旧 DID MUST NOT 通过 P4 新操作授权;
- Group DID 迁移不属于本 Profile;
group_did停用后新操作 fail closed。
12. Profile 特定错误(推荐)
在沿用 ANP Core 公共错误模型的前提下,本 Profile 推荐以下 anp_code:
code | anp_code | 含义 |
|---|---|---|
| 3000 | group.not_member | 调用方不是该群成员 |
| 3001 | group.already_member | 目标已经是群成员 |
| 3002 | group.admission_not_allowed | 当前入群路径不可用,或入群前置条件不满足 |
| 3003 | group.policy_violation | 操作违反群策略 |
| 3005 | group.member_conflict | 成员状态冲突 |
| 3006 | group.security_mode_required | 群要求更高安全模式 |
| 3007 | group.host_unavailable | 群 Host 暂不可用 |
| 3008 | group.invalid_origin_proof | 发起者原发者证明无效、过期或缺失 |
| 3009 | group.origin_did_mismatch | meta.sender_did 与 keyid 所属 DID 不一致 |
| 3010 | group.invalid_group_receipt | 群回执签名无效或与返回结果不匹配 |
13. 隐私注意事项
13.1 成员列表最小披露
即使实现支持 include_member_list,Group Host 也 SHOULD 只向有权调用方返回最小必要成员信息。对于公共群,匿名读取 SHOULD NOT 默认暴露完整成员列表。
13.2 带外入群凭据的传播
若部署方使用私有邀请链接、Join Token 或其它带外凭据来触发 group.join,实现方 SHOULD 避免把这些可操作凭据暴露给无关方,并 SHOULD 优先通过受控渠道、带外渠道或受保护私聊传递。
13.3 公共发现与匿名读取
当群设置为 public 或 listed 时,匿名读取 SHOULD 仅返回最小资料快照;调用方 SHOULD NOT 因匿名读取而推断内部成员关系、角色分布或其它不必要状态。
14. 最小互通要求
一个符合本 Profile 的实现至少 MUST 支持:
group.creategroup.get_infogroup.joingroup.addgroup.removegroup.leavegroup.update_profilegroup.update_policygroup.sendgroup_did、group_state_version和group_event_seq- DID-only
group_member,以及owner、admin、member角色 active、left、removed成员状态- 以
group.member_did_update作为不可调用动作标识的 Host 协调 DID 更新 member-did-updated事件与统一回执语义- 在旧 DID 被拒绝前返回其精确幂等重放结果
- 不含设备 selector 的 DID 级成员关系、治理、消息和通知
- P4 业务成员与 P6 设备级 MLS Leaves 分离
- 在有界重试和保留范围内,向事件主体最后投递一次
member-removed或member-left的group.state_changed
若实现提供 push capability,则其 group.incoming 与 group.state_changed MUST 遵循本 Profile 的标准 Notification 语义。
15. 示例
15.1 group.create 示例
{
"jsonrpc": "2.0",
"id": "req-30001",
"method": "group.create",
"params": {
"meta": {
"profile": "anp.group.base.v2",
"security_profile": "transport-protected",
"sender_did": "did:wba:a.example:agents:alice:e1_<fingerprint>",
"target": {
"kind": "service",
"did": "did:wba:groups.example"
},
"operation_id": "op-30001",
"created_at": "2026-03-29T12:30:00Z"
},
"auth": {
"scheme": "anp-rfc9421-origin-proof-v1",
"origin_proof": {
"contentDigest": "sha-256=:BASE64_SHA256_OF_SIGNED_REQUEST_OBJECT:",
"signatureInput": "sig1=(\"@method\" \"@target-uri\" \"content-digest\");created=1774787400;expires=1774787460;nonce=\"n-30001\";keyid=\"did:wba:a.example:agents:alice:e1_<fingerprint>#key-1\"",
"signature": "sig1=:BASE64_SIGNATURE:"
}
},
"body": {
"group_profile": {
"display_name": "Cross-Domain Agents",
"description": "协作群",
"discoverability": "private"
},
"group_policy": {
"message_security_profile": "transport-protected",
"bootstrap_security_profile": "transport-protected",
"admission_mode": "admin-add",
"permissions": {
"send": "member",
"add": "admin",
"remove": "admin",
"update_profile": "admin",
"update_policy": "owner"
},
"attachments_allowed": true,
"max_members": "500"
},
"initial_members": [
{
"agent_did": "did:wba:a.example:agents:alice:e1_<fingerprint>",
"role": "owner"
}
]
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
普通 JSON payload 示例:
{
"jsonrpc": "2.0",
"id": "req-30005",
"method": "group.send",
"params": {
"meta": {
"profile": "anp.group.base.v2",
"security_profile": "transport-protected",
"sender_did": "did:wba:a.example:agents:alice:e1_<fingerprint>",
"target": {
"kind": "group",
"did": "did:wba:groups.example:team:dev:e1_<fingerprint>"
},
"operation_id": "msg-30005",
"message_id": "msg-30005",
"created_at": "2026-03-29T12:51:00Z",
"content_type": "application/json"
},
"body": {
"thread_id": "thr-001",
"payload": {
"type": "example",
"data": {
"hello": "group"
}
}
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
payload 内部字段由应用定义,不属于 ANP 规范字段。
成功响应示例:
{
"jsonrpc": "2.0",
"id": "req-30001",
"result": {
"group_did": "did:wba:groups.example:team:dev:e1_<fingerprint>",
"group_state_version": "1",
"group_event_seq": "1",
"created_at": "2026-03-29T12:30:01Z",
"creator_did": "did:wba:a.example:agents:alice:e1_<fingerprint>",
"group_receipt": {
"receipt_type": "group-operation-accepted",
"group_did": "did:wba:groups.example:team:dev:e1_<fingerprint>",
"group_state_version": "1",
"group_event_seq": "1",
"subject_method": "group.create",
"operation_id": "op-30001",
"actor_did": "did:wba:a.example:agents:alice:e1_<fingerprint>",
"accepted_at": "2026-03-29T12:30:01Z",
"payload_digest": "sha-256=:BASE64_SHA256_OF_SIGNED_REQUEST_OBJECT:",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"verificationMethod": "did:wba:groups.example:team:dev:e1_<fingerprint>#assert-1",
"proofPurpose": "assertionMethod",
"created": "2026-03-29T12:30:01Z",
"proofValue": "zBASE58MULTIBASE_PROOF"
}
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
15.2 group.add 示例
{
"jsonrpc": "2.0",
"id": "req-30002",
"method": "group.add",
"params": {
"meta": {
"profile": "anp.group.base.v2",
"security_profile": "transport-protected",
"sender_did": "did:wba:a.example:agents:alice:e1_<fingerprint>",
"target": { "kind": "group", "did": "did:wba:groups.example:team:dev:e1_<fingerprint>" },
"operation_id": "op-30002",
"created_at": "2026-03-29T12:40:00Z"
},
"auth": { "...": "..." },
"body": {
"member_did": "did:wba:b.example:agents:bob:e1_<fingerprint>",
"role": "member",
"reason_text": "加入协作群"
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
成功响应:
{
"jsonrpc": "2.0",
"id": "req-30002",
"result": {
"group_did": "did:wba:groups.example:team:dev:e1_<fingerprint>",
"member_did": "did:wba:b.example:agents:bob:e1_<fingerprint>",
"group_state_version": "2",
"membership_status": "active",
"group_receipt": { "...": "..." }
}
}2
3
4
5
6
7
8
9
10
11
15.3 group.join 示例(开放加入)
{
"jsonrpc": "2.0",
"id": "req-30003",
"method": "group.join",
"params": {
"meta": {
"profile": "anp.group.base.v2",
"security_profile": "transport-protected",
"sender_did": "did:wba:c.example:agents:carol:e1_<fingerprint>",
"target": {
"kind": "group",
"did": "did:wba:groups.example:public:news:e1_<fingerprint>"
},
"operation_id": "op-30003",
"created_at": "2026-03-29T12:45:00Z"
},
"auth": {
"scheme": "anp-rfc9421-origin-proof-v1",
"origin_proof": {
"contentDigest": "sha-256=:BASE64_SHA256_OF_SIGNED_REQUEST_OBJECT:",
"signatureInput": "sig1=(\"@method\" \"@target-uri\" \"content-digest\");created=1774788300;expires=1774788360;nonce=\"n-30003\";keyid=\"did:wba:c.example:agents:carol:e1_<fingerprint>#key-1\"",
"signature": "sig1=:BASE64_SIGNATURE:"
}
},
"body": {
"reason_text": "订阅公开群"
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
成功响应示例:
{
"jsonrpc": "2.0",
"id": "req-30003",
"result": {
"group_did": "did:wba:groups.example:public:news:e1_<fingerprint>",
"member_did": "did:wba:c.example:agents:carol:e1_<fingerprint>",
"membership_status": "active",
"group_state_version": "8",
"group_receipt": {
"receipt_type": "group-operation-accepted",
"group_did": "did:wba:groups.example:public:news:e1_<fingerprint>",
"group_state_version": "8",
"group_event_seq": "41",
"subject_method": "group.join",
"operation_id": "op-30003",
"actor_did": "did:wba:c.example:agents:carol:e1_<fingerprint>",
"accepted_at": "2026-03-29T12:45:01Z",
"payload_digest": "sha-256=:BASE64_SHA256_OF_SIGNED_REQUEST_OBJECT:",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"verificationMethod": "did:wba:groups.example:public:news:e1_<fingerprint>#assert-1",
"proofPurpose": "assertionMethod",
"created": "2026-03-29T12:45:01Z",
"proofValue": "zBASE58MULTIBASE_PROOF"
}
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
15.4 group.send 示例
{
"jsonrpc": "2.0",
"id": "req-30004",
"method": "group.send",
"params": {
"meta": {
"profile": "anp.group.base.v2",
"security_profile": "transport-protected",
"sender_did": "did:wba:a.example:agents:alice:e1_<fingerprint>",
"target": {
"kind": "group",
"did": "did:wba:groups.example:team:dev:e1_<fingerprint>"
},
"operation_id": "msg-30004",
"message_id": "msg-30004",
"created_at": "2026-03-29T12:50:00Z",
"content_type": "text/plain"
},
"auth": {
"scheme": "anp-rfc9421-origin-proof-v1",
"origin_proof": {
"contentDigest": "sha-256=:BASE64_SHA256_OF_SIGNED_REQUEST_OBJECT:",
"signatureInput": "sig1=(\"@method\" \"@target-uri\" \"content-digest\");created=1774788600;expires=1774788660;nonce=\"n-30004\";keyid=\"did:wba:a.example:agents:alice:e1_<fingerprint>#key-1\"",
"signature": "sig1=:BASE64_SIGNATURE:"
}
},
"body": {
"thread_id": "thr-001",
"text": "大家好"
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
成功响应示例:
{
"jsonrpc": "2.0",
"id": "req-30004",
"result": {
"accepted": true,
"group_did": "did:wba:groups.example:team:dev:e1_<fingerprint>",
"message_id": "msg-30004",
"operation_id": "msg-30004",
"group_event_seq": "9",
"group_state_version": "2",
"accepted_at": "2026-03-29T12:50:01Z",
"group_receipt": {
"receipt_type": "group-message-accepted",
"group_did": "did:wba:groups.example:team:dev:e1_<fingerprint>",
"group_state_version": "2",
"group_event_seq": "9",
"subject_method": "group.send",
"operation_id": "msg-30004",
"message_id": "msg-30004",
"actor_did": "did:wba:a.example:agents:alice:e1_<fingerprint>",
"accepted_at": "2026-03-29T12:50:01Z",
"payload_digest": "sha-256=:BASE64_SHA256_OF_SIGNED_REQUEST_OBJECT:",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"verificationMethod": "did:wba:groups.example:team:dev:e1_<fingerprint>#assert-1",
"proofPurpose": "assertionMethod",
"created": "2026-03-29T12:50:01Z",
"proofValue": "zBASE58MULTIBASE_PROOF"
}
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
15.5 member-did-updated 事件示例
{
"event_id": "evt-didupd-001",
"event_type": "member-did-updated",
"group_did": "did:wba:groups.example:team:dev:e1_<fingerprint>",
"group_state_version": "3",
"group_event_seq": "10",
"subject_method": "group.member_did_update",
"changed_at": "2026-08-25T02:11:00Z",
"actor_did": "did:wba:groups.example",
"previous_subject_did": "did:wba:b.example:agents:bob:e1_<old-fingerprint>",
"subject_did": "did:wba:b.example:agents:bob:e1_<new-fingerprint>",
"membership_status": "active",
"group_receipt": {
"receipt_type": "group-operation-accepted",
"group_did": "did:wba:groups.example:team:dev:e1_<fingerprint>",
"group_state_version": "3",
"group_event_seq": "10",
"subject_method": "group.member_did_update",
"operation_id": "didupd_BASE64URL_SHA256",
"actor_did": "did:wba:groups.example",
"accepted_at": "2026-08-25T02:11:00Z",
"payload_digest": "sha-256=:BASE64_DIGEST:",
"proof": { "...": "..." }
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
16. 注册表占位
本标准后续版本 SHOULD 建立以下注册表:
- 群角色注册表;
- 群成员状态注册表;
group_policy.admission_mode注册表;group.state_changed.event_type注册表;- 群错误码注册表。
17. 参考实现说明(非规范性)
实现方在落地本 Profile 时,宜采用如下原则:
- v2 核心只维护
group_member入群结果对象,不引入标准invitation或标准化审批对象; group_policy使用固定admission_mode + permissions结构,比大量布尔开关更清晰、更易实现;group.incoming负责群消息推送,group.state_changed负责群内有序状态同步;- 实现可以使用稳定本地记录做内部关联,但 P4 wire object 只使用当前 DID;
- 成员 DID 连续性只在完成 P2 迁移验证与 Group Host 业务策略判断后接受;
- 实现不得仅凭名称、路径或
alsoKnownAs猜测或合并身份; - 私有邀请链接、Join Token、站内提醒等能力属于部署扩展,而不是 v2 核心互通要求;
group.send不参与群状态版本并发控制,服务端只需验证“发送者当前是否为active成员且具备send权限”。