第 3 章:離線授權協議
本章定義 Authorization_Descriptor 的完整生命週期協議流程,包括簽發、本地儲存、校驗、撤銷、更新五個階段。本章流程對應藍圖 §2.1 的設計意圖。
3.1 簽發流程(Issuance)
簽發流程由 Descriptor_Issuer 在收到授權人的明確授權後執行。本規範定義簽發結果的格式約束,但不規定授權人與 Descriptor_Issuer 之間的具體互動方式(不同部署可採用 Web 表單、行動 App 授權、企業授權管理系統等不同形式)。
3.1.1 簽發輸入
Descriptor_Issuer 在簽發時 MUST 已確認以下資訊:
- 授權人身分(
grantor_id)已通過 Descriptor_Issuer 自身的身分驗證機制 - 授權範圍(目標
subject_fay_id、terminal_id、grants)由授權人明確指定 - 有效期(
not_before、not_after)由授權人明確指定或採用預設策略
3.1.2 簽發步驟
Descriptor_Issuer MUST 按以下步驟產生 Authorization_Descriptor:
- 產生識別碼:分配新的
descriptor_id(UUID v7),MUST NOT 重複使用已使用過的 ID - 建構載荷:按 §2.3.2 填充
DescriptorPayload,所有 required 欄位 MUST 設定 - 校驗約束:本地校驗
not_after - not_before ≤ 90 天等約束(參見 §2.3.2) - CBOR 序列化:按 RFC 8949 確定性編碼序列化 payload
- 數位簽章:使用 Descriptor_Issuer 私鑰按 §8 定義的演算法對 payload 位元組簽章
- 組裝結構:建構完整的
AuthorizationDescriptor,包含 version、payload、signature - 登記記錄:在 Descriptor_Issuer 內部狀態庫中登記該憑證(用於後續撤銷管理)
3.1.3 簽發後交付
簽發完成後,Descriptor_Issuer 將 Authorization_Descriptor 交付給目標 Fay。交付方式不在本規範範圍內,但 SHOULD 滿足:
- 透過加密通道交付,避免憑證在傳輸過程中被攔截
- 交付到 Fay 所屬的
iFay_Runtime,由 iFay_Runtime 代為持有
3.2 本地儲存流程(Local Storage)
Fay 透過 iFay_Runtime 將 Authorization_Descriptor 提交給目標終端進行本地儲存。
3.2.1 提交訊息
iFay_Runtime 向 Protocol_Engine 傳送 DescriptorSubmit 訊息:
DescriptorSubmit (body of ProtocolMessage) {
required descriptor : AuthorizationDescriptor
}
3.2.2 終端處理
終端收到 DescriptorSubmit 後 MUST 按以下順序處理:
- 結構校驗:驗證
descriptor符合 §2.3 定義的結構 - 簽章校驗:使用對應
key_id的 Verification_Key 校驗 signature(參見 §3.3.4) - 去重檢查:若本地已儲存同
descriptor_id的憑證,且新提交的內容與已儲存的位元組級一致,返回成功;否則按重複 ID 錯誤拒絕 - 儲存:將 Authorization_Descriptor 加密儲存到本地安全儲存區域(參見 §3.2.3)
- 返回結果:向 iFay_Runtime 返回
DescriptorSubmitResult訊息,包含成功或錯誤碼
3.2.3 儲存要求
終端 MUST:
- 加密儲存 Authorization_Descriptor,加密金鑰不可被未授權程序讀取
- 儲存媒介 SHOULD 具備防實體拆解能力(如安全晶片、TEE 等)
- 儲存容量上限 SHOULD 不少於 1024 份憑證;超過上限時按 LRU 策略淘汰已過期的憑證
終端 MUST NOT:
- 將 Authorization_Descriptor 以明文形式儲存
- 在儲存前修改 descriptor 的任何欄位(包括 metadata)
3.2.4 錯誤碼
| 錯誤碼 | 觸發條件 |
|---|---|
E_INVALID_STRUCTURE | 結構不符合 §2.3 |
E_INVALID_SIGNATURE | 簽章校驗失敗 |
E_UNKNOWN_ISSUER | key_id 對應的 Verification_Key 未在終端註冊 |
E_DUPLICATE_DESCRIPTOR_ID | 與已儲存的 descriptor_id 衝突且內容不一致 |
E_STORAGE_FULL | 儲存容量已滿且無法淘汰 |
E_VALIDITY_OUT_OF_RANGE | not_after - not_before 超出限制 |
3.3 校驗流程(Validation)
校驗流程在每次資源存取請求時執行。本節定義校驗的完整步驟和判定規則。
3.3.1 校驗觸發
當 iFay_Runtime 傳送 AuthRequest 請求資源存取時,終端 Protocol_Engine 觸發校驗流程:
AuthRequest (body of ProtocolMessage) {
required fay_id : Fay_ID
required resource_id : Resource_ID
required access_mode : AccessMode
required credential : CredentialReference
}
CredentialReference {
required type : enum["descriptor", "ticket"]
required id : string // descriptor_id 或 jti
}
注意:本規範的離線授權場景下,credential 引用的是已儲存在終端的 Authorization_Descriptor,不需要在請求中傳輸完整憑證。
3.3.2 校驗步驟(按順序執行)
終端 MUST 按以下順序執行校驗。任一步驟失敗立即返回對應錯誤碼,不繼續執行後續步驟。
第 1 步:憑證存在性
終端在本地儲存中尋找 credential.id 對應的 Authorization_Descriptor。
- 未找到 → 返回
E_DESCRIPTOR_NOT_FOUND
第 2 步:撤銷狀態
終端檢查本地撤銷清單,確認該 descriptor_id 未被撤銷。
- 已撤銷 → 返回
E_DESCRIPTOR_REVOKED
第 3 步:有效期
終端檢查目前時間在 [not_before, not_after] 區間內。
- 目前時間 <
not_before→ 返回E_DESCRIPTOR_NOT_YET_VALID - 目前時間 ≥
not_after→ 返回E_DESCRIPTOR_EXPIRED
終端時鐘來源:MUST 使用經過校準的系統時鐘。終端 SHOULD 在長時間未聯網時謹慎處理校驗請求(參見 §3.6 時鐘漂移處理)。
第 4 步:主體比對
終端驗證 payload.subject_fay_id == AuthRequest.fay_id。
- 不比對 → 返回
E_SUBJECT_MISMATCH
第 5 步:終端比對
終端驗證 payload.terminal_id == 目前終端 ID。
- 不比對 → 返回
E_TERMINAL_MISMATCH
第 6 步:資源與模式比對
終端遍歷 payload.grants,尋找滿足以下條件的 Grant:
Grant.resource_pattern按 §2.3.5 規則比對AuthRequest.resource_idGrant.modes包含AuthRequest.access_mode- 若
Grant.constraints非空,所有約束條件滿足(約束的語意參見 §7.4)
- 找不到滿足的 Grant → 返回
E_AUTHORIZATION_INSUFFICIENT
第 7 步:簽章校驗
終端使用 signature.key_id 對應的 Verification_Key 重新校驗 payload 的簽章。
注意:步驟 1–6 的快速校驗完成後才執行簽章校驗,以提供合理的失敗語意(如先告知「憑證已撤銷」而非「簽章失敗」)。但在校驗通過返回成功前,簽章校驗 MUST 已執行並通過。
- 簽章校驗失敗 → 返回
E_INVALID_SIGNATURE - 簽章金鑰已撤銷或過期 → 返回
E_VERIFICATION_KEY_INVALID
3.3.3 校驗通過後
所有 7 步均通過後,終端按第 5 章流程建立 Session,並向 iFay_Runtime 返回:
AuthResult (body of ProtocolMessage, success) {
required status : "granted"
required session_id : Session_ID
required granted_modes : array<AccessMode>
required session_expires_at : timestamp
}
session_expires_at SHOULD 等於 min(not_after, 目前時間 + 預設會話最長時間)。
3.3.4 簽章校驗細節
簽章校驗的具體步驟:
- 取出
descriptor.signature.key_id,在終端 Verification_Key 儲存中尋找對應公鑰 - 驗證該 Verification_Key 在目前時間有效(
valid_from ≤ 目前時間 ≤ valid_until,若 valid_until 已設定) - 按 §2.3.3 規則將
descriptor.payload重新 CBOR 序列化 - 使用 Verification_Key 和
descriptor.signature.algorithm校驗序列化位元組的簽章 - 校驗成功後 MUST 快取結果(同一 descriptor 在生命週期內僅需校驗一次簽章)
3.4 撤銷流程(Revocation)
3.4.1 撤銷發起
授權人透過 Descriptor_Issuer 發起撤銷請求。撤銷請求的具體互動形式不在本規範範圍內。
Descriptor_Issuer 收到撤銷請求後 MUST:
- 驗證撤銷請求來自原始授權人或具備撤銷權限的實體
- 按 §2.8 產生
RevocationStatement - 使用與原始 Authorization_Descriptor 相同的簽章金鑰對撤銷聲明簽章
- 將撤銷聲明加入 Descriptor_Issuer 維護的撤銷清單
3.4.2 撤銷分發
撤銷聲明透過以下方式分發到終端,終端 MUST 至少支援其中兩種:
- 拉取同步(Pull-based):終端聯網時主動從 Descriptor_Issuer 或撤銷服務拉取增量撤銷清單。同步頻率由終端策略決定,SHOULD 不低於每小時一次(聯網期間)
- 推送通知(Push-based):Descriptor_Issuer 透過 Registration_Authority 或專門的撤銷分發服務向終端推送撤銷聲明
- 憑證內嵌(In-band):在 Trusted_Ticket 的 metadata 中攜帶最近撤銷清單的摘要,使聯網期間取得的票據自動捎帶撤銷資訊
3.4.3 終端撤銷清單維護
終端的本地撤銷清單 MUST:
- 永久儲存所有未過期的撤銷聲明
- 在憑證
not_after時間過去後 MAY 刪除對應的撤銷聲明(憑證已自然失效) - 驗證每條撤銷聲明的簽章,拒絕無效簽章的撤銷聲明
3.4.4 撤銷生效時間
撤銷聲明的生效時間為:
生效時間 = max(撤銷聲明到達終端的時間, RevocationStatement.revoked_at)
終端 MUST 確保撤銷聲明到達後的下次校驗請求即拒絕該憑證。終端 MAY 主動檢查所有活躍 Session 是否引用了被撤銷的憑證,若是則按第 5 章規則強制終止這些 Session。
3.4.5 撤銷延遲視窗
由於離線分發的固有延遲,存在以下不可避免的撤銷延遲視窗:
| 場景 | 最大延遲 |
|---|---|
| 終端持續聯網 | 一次同步週期(預設 ≤ 1 小時) |
| 終端短期離線 | 重新聯網後的下次同步 |
| 終端長期離線 | 最長延遲為憑證 not_after - 撤銷時間,但不超過 90 天(憑證最長有效期) |
簽發方 SHOULD 透過設定較短的 not_after(如 7 天)來限制最長撤銷延遲。
3.5 更新流程(Renewal)
更新本質上是簽發新的 Authorization_Descriptor 取代舊版本,並非修改現有憑證。
3.5.1 更新策略
授權人或自動續期機制可在以下場景觸發更新:
- 憑證臨近
not_after且授權關係仍然有效 - 授權範圍需要調整(增加/減少 grants)
- 授權約束需要調整(修改 constraints)
3.5.2 更新流程
更新過程:
- Descriptor_Issuer 按 §3.1 流程簽發新的 Authorization_Descriptor,使用新的
descriptor_id - 新憑證按 §3.2 流程提交到終端並儲存
- 舊憑證 MAY 由簽發方主動撤銷(按 §3.4),也 MAY 由其自然過期失效
終端在新舊憑證並存期間,處理優先順序:
- 校驗請求 MUST 優先比對未過期的憑證
- 多個未過期憑證均比對時,使用
issued_at最近的憑證
3.5.3 不允許的更新行為
實作 MUST NOT:
- 修改已發布憑證的任何欄位(包括 metadata)
- 重複使用舊憑證的
descriptor_id - 在舊憑證仍有效期間修改其語意(必須透過撤銷 + 新簽發實現)
3.6 時鐘漂移處理
終端時鐘可能因長期離線或硬體問題出現漂移。本節定義時鐘漂移情況下的處理規則。
3.6.1 時鐘容差
終端在校驗有效期時 MAY 引入容差:
- 對
not_before:可允許至多 5 分鐘的早期容差(接受目前時間 ≥ not_before - 5min) - 對
not_after:MUST NOT 引入容差(過期就是過期)
容差僅用於補償短期時鐘偏移,不應用於繞過有效期約束。
3.6.2 時鐘可信性
終端 SHOULD 偵測以下時鐘異常並採取保護措施:
- 時鐘顯著回退(系統時鐘向過去跳變 > 1 小時):拒絕校驗請求直至時鐘同步
- 時鐘顯著前移(系統時鐘向未來跳變 > 24 小時):拒絕校驗請求直至時鐘同步
3.7 完整流程示意
[Descriptor_Issuer] [Fay/iFay_Runtime] [Terminal/Protocol_Engine]
│ │ │
│── 簽發 AuthorizationDescriptor ─────→│ │
│ (含數位簽章) │ │
│ │ │
│ │── DescriptorSubmit ─────────────────→│
│ │ │── 校驗簽章 + 儲存
│ │←─ DescriptorSubmitResult ──────────── │
│ │ │
│ │── AuthRequest(帶 descriptor_id)───→│
│ │ │── 7 步校驗
│ │←─ AuthResult(granted)──────────────│
│ │ │── 建立 Session
│ │ │
│ │ 【Fay 持續存取資源】 │
│ │ │
│── 撤銷 RevocationStatement ──────────────────────────────────────────────────→│
│ │ │── 加入撤銷清單
│ │ │── 強制終止關聯 Session
