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)。
