Faying Protocol/1.0 — §5 Protocol Messages
§5 Protocol Messages
本章列出协议的全部报文:编码规则、信封结构、七类业务报文和一类错误响应,以及错误码与审计、HP 视野推送的对应关系。
类型权威性提示:本章 TypeScript 块中所引用的
Mandate / Scope / Grade / PresenceSignal / PresenceRequirement / Endorsement / SignatureBundle / Attestation / WebAuthnAssertion / AtomicAction / RevokeReason等类型,其权威定义位于 §4 Data Models(CDDL);TypeScript 视图为 Non-normative 的人读视图,凡两者出现差异以 §4 CDDL 为准。
§5.1 编码规则
- 主格式(CBOR):所有线上传输的默认编码为 CBOR(RFC 8949);HTTP
Content-Type必须声明为application/faying-protocol+cbor。 - 互操作回退(JSON):JSON(RFC 8259)仅在调试 / 浏览器 / 人读审阅场景使用,HTTP
Content-Type必须显式声明为application/faying-protocol+json;安全等价性由相同的字段语义与签名格式保证。 - Deterministic Encoding:所有签名对象在签名前必须先按 RFC 8949 §4.2.1 Deterministic Encoding 规则做 CBOR 序列化,避免 JSON 序列化歧义;JSON 形态下的签名输入仍是 Deterministic CBOR 序列化的字节串哈希(详见 §6.3)。
- 传输绑定:默认 HTTP/1.1 与 HTTP/2,Mandate Service 端点遵循
POST /faying-protocol/v1/{verb};亦可绑定到 gRPC(faying-protocol.v1service)或 WebSocket / SSE(faying-protocol.v1streaming)。所有传输层绑定必须保留报文层签名与 nonce,禁止以传输层 TLS 通道身份替代报文级签名。
§5.2 信封结构
所有报文使用统一信封 FayingProtocolEnvelope:
interface FayingProtocolEnvelope<TPayload> {
header: {
version: "Faying Protocol/1.0";
msg_type: FayingProtocolMsgType;
msg_id: string; // ULID
issued_at: IsoTime;
expiry: IsoTime;
nonce: Nonce;
grade: Grade; // 当前会话等级(用于 RP 拒绝低等级请求)
issuer: HumanPrimeID | string;
subject: FayID;
};
claims: TPayload;
attestation: Attestation;
signature: SignatureBundle;
}
type FayingProtocolMsgType =
| "BOOTSTRAP" | "BOOTSTRAP_RESP"
| "PRESENCE" | "PRESENCE_ACK"
| "GRADE_SWITCH" | "GRADE_SWITCH_RESP"
| "DELEGATE" | "DELEGATE_RESP"
| "REVOKE" | "REVOKE_RECEIPT"
| "FAYING_REQUEST" | "FAYING_REQUEST_RESP"
| "DISCLOSURE"
| "ERROR";
信封层不变式:
- 任一字段缺失或类型错误一律以
E_PROTOCOL拒绝(详见 §5.4)。 nonce在2 × max_message_lifetime窗口内对相同subject至多被接受一次;重复即E_REPLAY。expiry必须有限且> issued_at;过期信封不进入业务校验路径,直接以E_PROTOCOL拒绝。signature的输入必须是H( Deterministic-CBOR( Envelope_without_signature ) )(详见 §6.3)。
§5.3 报文清单
本协议共定义 7 类业务报文:BOOTSTRAP / PRESENCE / GRADE_SWITCH / DELEGATE / REVOKE / FAYING_REQUEST / DISCLOSURE,外加 1 类错误响应 ERROR(详见 §5.4)。
§5.3.1 BOOTSTRAP(Faying Action)
用途:Human Prime 通过 BOOTSTRAP 在 MS 处建立一份 Mandate,向 iFay 颁发监护授权。BOOTSTRAP 是 Faying Protocol 的唯一合法 Faying Action 入口。
interface BootstrapClaims {
human_prime: HumanPrimeID;
fay: FayID;
scope: Scope;
grade: Grade;
presence_req: PresenceRequirement;
not_after: IsoTime; // 必须有限
human_witness: WebAuthnAssertion; // user-verification = true
endorsement?: Endorsement; // 可选;存在即颁发 Endorsed Mandate(见 §4 / §11)
faying_request_ref?: string; // IF-initiated 路径下,引用对应 FAYING_REQUEST.msg_id
}
成功响应:返回 Mandate 完整对象(含 signature_bundle)。
协议层硬约束:
not_after必须有限且> not_before,禁止∞与负值;违反一律以E_PROTOCOL拒绝(与 §3.1 I-MS-1 / Property 7 一致)。human_witness字段缺失或验签失败一律以E_HUMAN_WITNESS_REQUIRED拒绝;不存在由 IF / MS / Supervisory Agent 替代 HP 完成认可确认的合法路径。- 当 BOOTSTRAP 响应一份此前由 iFay 发起的
FAYING_REQUEST时,faying_request_ref必须指向该请求的msg_id;MS 必须在 Attestation Chain 上把"iFay 发起 → HP 见证 → 生效"三步串联为一条不可分割的证据链(详见 §5.3.6 与 §3.3)。 - 当
endorsement字段存在时,MS 必须在签发前校验endorsed_scope ⊆ scope∧endorsed_grade.autonomy ≤ grade.autonomy∧0 < endorsed_lifetime_ms ≤ (not_after − not_before);任一不满足以E_ENDORSEMENT_INVALID(错误码 1013)拒绝。
§5.3.2 PRESENCE(持续校准)
用途:iFay_Instance 周期性地向 MS 推送由 Presence Device 产生的在场信号,刷新对应 Mandate 的 PresenceState.last_freshness。
interface PresenceClaims {
mandate_id: MandateID;
signal: PresenceSignal;
device_health: {
secure_element: boolean;
tampered: boolean;
last_boot_at: IsoTime;
};
}
协议层硬约束:
signal必须携带 §3.2 I-PC-1 强制三元组(nonce / produced_at / device_attestation)并由 Presence Device 签名;缺一即E_PROTOCOL。新鲜度窗口由对应 Mandate 的presence_req.max_staleness_ms给定,不由信号自带。- 信号超出
presence_req.max_staleness_ms即E_PRESENCE_STALE,并按 §3.2 I-PC-3 触发收紧(迁移到更严的 grade 或 Suspended)。 - 同一
(subject, nonce)在2 × max_message_lifetime窗口内重复出现一律E_REPLAY。
§5.3.3 GRADE_SWITCH(等级切换)
用途:在 Mandate 生命周期内调整其授权等级(升级 / 降级)。
interface GradeSwitchClaims {
mandate_id: MandateID;
target_grade: Grade;
reason: "human-initiated" | "presence-loss" | "policy-trigger";
human_witness?: WebAuthnAssertion; // 升级方向必填,降级方向可选
}
协议层不变式(升级强见证):当 target_grade.autonomy > current.autonomy(即在自主性方向上严格强于当前等级)时,human_witness 为 MUST;缺失或验签失败一律以 E_HUMAN_WITNESS_REQUIRED 拒绝。降级方向(target_grade.autonomy ≤ current.autonomy)允许由协议自动触发(如 presence-loss / policy-trigger),不强制 human_witness。
§5.3.4 DELEGATE(跨设备 / 子代理派生)
用途:从父 Mandate 派生子 Mandate,用于跨设备或子代理场景。
interface DelegateClaims {
parent_mandate: MandateID;
child_subject: FayID; // 派生体 FayID
child_scope: Scope; // 必须 ⊆ parent.scope
child_grade: Grade; // child_grade.autonomy 必须 ≤ parent.grade.autonomy(自主性更低或相等,即更严或相等)
device_id?: string; // 跨设备派生时绑定具体终端
}
协议层硬约束:
child_scope ⊆ parent.scope∧child_grade.autonomy ≤ parent.grade.autonomy;任何方向上的扩张以E_PROTOCOL拒绝(与 §3.1 I-MS-4 / Property 6 一致)。- 子 Mandate 的
signature_bundle.chain必须携带父 Mandate 副签,构成 Attestation Chain 上的一条派生节点。 - 当父 Mandate 携带
endorsement时,子 Mandate 的endorsement(若存在)必须收敛于父 endorsement;不收敛以E_ENDORSEMENT_INVALID拒绝。
§5.3.5 REVOKE
用途:撤销一份 Mandate;可选级联撤销其全部派生子 Mandate。
interface RevokeClaims {
mandate_id: MandateID;
cascade: boolean; // 是否级联撤销所有派生子 Mandate(默认 true)
reason: RevokeReason;
effective_at: IsoTime; // 默认 = now,允许预定撤销
}
type RevokeReason =
| "human-initiated"
| "expiry"
| "task-completed"
| "human-prime-unreachable"
| "ego-deviation"
| "fay-credential-invalid"
| "human-prime-credential-invalid"
| "regulatory-order"
| "terminal-disconnected";
RevokeReason 与 §13 章九项触发条件一一对应。
协议层硬约束:
- 撤销可达性必须 ≥ Bootstrap 可达性(与 Property 4 / R4.1 一致);不存在 iFay 自身合法发起 REVOKE 的路径。
cascade = true时全部派生子 Mandate 必须在RevocationVisibilityBudget内可见revoked(与 Property 14 一致)。- 撤销不可逆:
Revoked是吸收态,恢复授权必须重新走 BOOTSTRAP 且新mandate_id不等于旧mandate_id(与 Property 10 一致)。
§5.3.6 FAYING_REQUEST / FAYING_REQUEST_RESP(IF-initiated 双向 Faying)
用途:iFay 主动向 Human Prime 寻求 Faying(请求建立或调整监护关系)。该报文不直接产生 Mandate;MS 仅作为转交方,将请求推送至 HP 视野通道,随后由 HP 通过 BOOTSTRAP 完成认可生效(见 §2.4 Phase A0)。
interface FayingRequestClaims {
initiator: FayID; // iFay 自身
target_human: HumanPrimeID; // 目标 HP
proposed_scope: Scope; // 建议的监护范围
proposed_grade: Grade; // 建议的等级
reason: string; // 自由文本补充
reason_code:
| "establish"
| "adjust-scope"
| "adjust-grade"
| "renew"
| "endorsement-request";
expected_lifetime_ms?: number; // 期望的 Mandate 寿命
proposed_endorsement?: Endorsement; // 若同时寻求 Endorsed Mandate
}
interface FayingRequestRespClaims {
request_msg_id: string; // 引用上游 FAYING_REQUEST.msg_id
status: "accepted" | "rejected" | "timeout";
bootstrap_ref?: string; // 当 status=accepted 时,指向 HP 完成的 BOOTSTRAP.msg_id
reject_reason?: string;
}
协议层硬约束:
- iFay 主动发起的 FAYING_REQUEST 不直接产生任何 Faying 状态变化;只有 HP 在
BootstrapTimeout内以 BOOTSTRAP(携faying_request_ref与可验证的human_witness)回应才使请求生效。 - 若 HP 在
BootstrapTimeout内未给出明确认可确认,MS 必须以FAYING_REQUEST_RESP { status="timeout" }返回,并将事件写入 Attestation Chain,对应错误码E_FAYING_REQUEST_NOT_CONFIRMED(1014)。 - 不存在任何由 MS / IF / Supervisory Agent 替代 HP 完成认可确认的合法路径;缺
human_witness一律E_HUMAN_WITNESS_REQUIRED(1010)。 - 对每对
(HP, IF)的 FAYING_REQUEST 频次受ConfirmationRateLimit(详见附录 B)约束,超限按 §9.10.7 T6 处理。
§5.3.7 DISCLOSURE(结构化披露报文)
用途:iFay 在汇报或请求确认时使用的结构化披露报文。监管方与 MS 可对该报文进行 schema-level 审计,禁止以纯自由文本掩盖关键信息(详见 §9.10.4 T3)。
interface DisclosureClaims {
mandate_id: MandateID;
/** mandatory_fields(任一缺失即视为协议错误) */
action: AtomicAction; // 一次披露恰好对应一个 Atomic_Action
scope_used: Scope; // 实际使用的 scope 子集
risk_level: "low" | "normal" | "high" | "critical";
reversibility: "reversible" | "partially-reversible" | "irreversible";
affected_resources: string[];
uncertainty_flags: string[]; // 例如 ["ambiguous-target", "stale-context"]
/** 可选补充 */
free_text?: string;
intent?: "report" | "request-confirmation";
endorsement_id?: string; // 若发生在 Disconnected 期间,指向对应 endorsement
}
mandatory_fields 强制清单(与 R13.3 / §9.10.4 一致):
action / scope_used / risk_level / reversibility / affected_resources / uncertainty_flags。
协议层硬约束:
- 任一
mandatory_fields缺失或不可解析 → MS 必须以E_PROTOCOL(1099)拒绝并推送至 HP 视野通道; - 高敏感动作(
risk_level ∈ {high, critical})必须在 D 维度执行之前先发出 DISCLOSURE 并等待 HP 显式确认(除非当前 grade 已是 G4 Autonomous 且动作落在主 scope 内,详见 §7); - 后续审计若发现 DISCLOSURE 中
mandatory_fields与实际动作不一致,MS 必须以RevokeReason="ego-deviation"撤销该 Mandate; - Disconnected 期间执行的动作其 DISCLOSURE 必须携带
endorsement_id,使该动作可被独立追溯到具体一份 endorsement。
§5.4 错误码
错误响应统一使用 ERROR 报文(信封 msg_type = "ERROR"),claims 体形如 { code, message, mandate_id?, recovery_hint? }。下表给出全部错误码及其审计与 HP 视野推送约束(与 §EH.3 一致)。
| Code | 名称 | 含义 | 响应 | 必入审计 | 必入 HP 视野 |
|---|---|---|---|---|---|
| 1001 | E_NO_MANDATE | 请求未携带 Mandate | 拒绝 | ✗ | ✗ |
| 1002 | E_MANDATE_EXPIRED | Mandate 已过期 | 拒绝 + 触发 Revoke | ✓ | ✗ |
| 1003 | E_SCOPE_VIOLATION | 调用超出 scope | 拒绝 + 记录可疑 | ✓ | ✗ |
| 1004 | E_GRADE_INSUFFICIENT | 当前等级不足以执行该敏感动作 | 拒绝 + 提示升级 | ✓ | ✗ |
| 1005 | E_PRESENCE_STALE | 在场信号过期 | 拒绝 + 触发降级 | ✓ | ✗ |
| 1006 | E_REVOKED | Mandate 已撤销 | 拒绝 | ✓ | ✓ |
| 1007 | E_ATTESTATION_INVALID | Attestation 校验失败 | 拒绝 + 触发 Revoke | ✓ | ✓ |
| 1008 | E_RR_UNAVAILABLE | 撤销注册中心不可达 | 按 Default-Deny 拒绝 | ✓ | ✗ |
| 1009 | E_REPLAY | nonce 重复 | 拒绝 + 安全告警 | ✓ | ✓ |
| 1010 | E_HUMAN_WITNESS_REQUIRED | 等级升级 / 双向 Faying 缺人类见证 | 拒绝 | ✓ | ✗ |
| 1011 | E_ROGUE_DETECTED | 检测到 Rogue 行为 | 拒绝 + 强制 Revoke | ✓ | ✓ |
| 1012 | E_BUDGET_EXCEEDED | 超过 ResourceBudget | 拒绝 + 触发降级 | ✓ | ✗ |
| 1013 | E_ENDORSEMENT_INVALID | Endorsement 字段不合法(含 endorsed_scope ⊄ scope / endorsed_grade.autonomy > grade.autonomy / endorsed_lifetime 缺失或超长 / 篡改) | 拒绝 + 触发该 Mandate 的 Revoke | ✓ | ✓ |
| 1014 | E_FAYING_REQUEST_NOT_CONFIRMED | iFay 主动发起的 FAYING_REQUEST 未在 BootstrapTimeout 内获 HP 明确认可 | 拒绝 + 写入 Attestation Chain | ✓ | ✗ |
| 1099 | E_PROTOCOL | 协议层错误(版本 / 格式 / 签名 / DISCLOSURE mandatory_fields 缺失或不可解析) | 拒绝 | ✓ | ✗* |
*注:E_PROTOCOL默认仅写入审计;但当其触发自 §5.3.7 DISCLOSURE 的mandatory_fields缺失或不可解析路径时,MS 必须额外推送至 HP 视野通道(详见 §5.3.7 与 §9.10.4 T3)。审计 / HP 视野语义说明:
- 必入审计:错误必须以
(error_code, mandate_id, ts, RP_id, reason)五元组写入 Attestation Chain / audit-log;除E_NO_MANDATE(无 Mandate 上下文)外全部错误码均为 ✓。- 必入 HP 视野:错误必须 push 至 HP 视野通道,禁止被 RP 静默吞掉。基础四类(
E_REVOKED/E_ATTESTATION_INVALID/E_REPLAY/E_ROGUE_DETECTED)由 §EH.3 强制;E_ENDORSEMENT_INVALID因其触发链路必然伴随E_REVOKED,亦推送至 HP 视野通道。- 错误响应中禁止携带 MS 内部状态、Mandate 私钥指纹、其他 Human Prime 标识等敏感信息(详见 §EH.3)。
