第 3 章:離線授權協議

本章定義 Authorization_Descriptor 的完整生命週期協議流程,包括簽發、本地儲存、校驗、撤銷、更新五個階段。本章流程對應藍圖 §2.1 的設計意圖。

3.1 簽發流程(Issuance)

簽發流程由 Descriptor_Issuer 在收到授權人的明確授權後執行。本規範定義簽發結果的格式約束,但不規定授權人與 Descriptor_Issuer 之間的具體互動方式(不同部署可採用 Web 表單、行動 App 授權、企業授權管理系統等不同形式)。

3.1.1 簽發輸入

Descriptor_Issuer 在簽發時 MUST 已確認以下資訊:

  1. 授權人身分(grantor_id)已通過 Descriptor_Issuer 自身的身分驗證機制
  2. 授權範圍(目標 subject_fay_idterminal_idgrants)由授權人明確指定
  3. 有效期(not_beforenot_after)由授權人明確指定或採用預設策略

3.1.2 簽發步驟

Descriptor_Issuer MUST 按以下步驟產生 Authorization_Descriptor:

  1. 產生識別碼:分配新的 descriptor_id(UUID v7),MUST NOT 重複使用已使用過的 ID
  2. 建構載荷:按 §2.3.2 填充 DescriptorPayload,所有 required 欄位 MUST 設定
  3. 校驗約束:本地校驗 not_after - not_before ≤ 90 天 等約束(參見 §2.3.2)
  4. CBOR 序列化:按 RFC 8949 確定性編碼序列化 payload
  5. 數位簽章:使用 Descriptor_Issuer 私鑰按 §8 定義的演算法對 payload 位元組簽章
  6. 組裝結構:建構完整的 AuthorizationDescriptor,包含 version、payload、signature
  7. 登記記錄:在 Descriptor_Issuer 內部狀態庫中登記該憑證(用於後續撤銷管理)

3.1.3 簽發後交付

簽發完成後,Descriptor_Issuer 將 Authorization_Descriptor 交付給目標 Fay。交付方式不在本規範範圍內,但 SHOULD 滿足:

  1. 透過加密通道交付,避免憑證在傳輸過程中被攔截
  2. 交付到 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 按以下順序處理:

  1. 結構校驗:驗證 descriptor 符合 §2.3 定義的結構
  2. 簽章校驗:使用對應 key_id 的 Verification_Key 校驗 signature(參見 §3.3.4)
  3. 去重檢查:若本地已儲存同 descriptor_id 的憑證,且新提交的內容與已儲存的位元組級一致,返回成功;否則按重複 ID 錯誤拒絕
  4. 儲存:將 Authorization_Descriptor 加密儲存到本地安全儲存區域(參見 §3.2.3)
  5. 返回結果:向 iFay_Runtime 返回 DescriptorSubmitResult 訊息,包含成功或錯誤碼

3.2.3 儲存要求

終端 MUST:

  1. 加密儲存 Authorization_Descriptor,加密金鑰不可被未授權程序讀取
  2. 儲存媒介 SHOULD 具備防實體拆解能力(如安全晶片、TEE 等)
  3. 儲存容量上限 SHOULD 不少於 1024 份憑證;超過上限時按 LRU 策略淘汰已過期的憑證

終端 MUST NOT:

  1. 將 Authorization_Descriptor 以明文形式儲存
  2. 在儲存前修改 descriptor 的任何欄位(包括 metadata)

3.2.4 錯誤碼

錯誤碼觸發條件
E_INVALID_STRUCTURE結構不符合 §2.3
E_INVALID_SIGNATURE簽章校驗失敗
E_UNKNOWN_ISSUERkey_id 對應的 Verification_Key 未在終端註冊
E_DUPLICATE_DESCRIPTOR_ID與已儲存的 descriptor_id 衝突且內容不一致
E_STORAGE_FULL儲存容量已滿且無法淘汰
E_VALIDITY_OUT_OF_RANGEnot_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

  1. Grant.resource_pattern 按 §2.3.5 規則比對 AuthRequest.resource_id
  2. Grant.modes 包含 AuthRequest.access_mode
  3. 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 簽章校驗細節

簽章校驗的具體步驟:

  1. 取出 descriptor.signature.key_id,在終端 Verification_Key 儲存中尋找對應公鑰
  2. 驗證該 Verification_Key 在目前時間有效(valid_from ≤ 目前時間 ≤ valid_until,若 valid_until 已設定)
  3. 按 §2.3.3 規則將 descriptor.payload 重新 CBOR 序列化
  4. 使用 Verification_Key 和 descriptor.signature.algorithm 校驗序列化位元組的簽章
  5. 校驗成功後 MUST 快取結果(同一 descriptor 在生命週期內僅需校驗一次簽章)

3.4 撤銷流程(Revocation)

3.4.1 撤銷發起

授權人透過 Descriptor_Issuer 發起撤銷請求。撤銷請求的具體互動形式不在本規範範圍內。

Descriptor_Issuer 收到撤銷請求後 MUST:

  1. 驗證撤銷請求來自原始授權人或具備撤銷權限的實體
  2. 按 §2.8 產生 RevocationStatement
  3. 使用與原始 Authorization_Descriptor 相同的簽章金鑰對撤銷聲明簽章
  4. 將撤銷聲明加入 Descriptor_Issuer 維護的撤銷清單

3.4.2 撤銷分發

撤銷聲明透過以下方式分發到終端,終端 MUST 至少支援其中兩種:

  1. 拉取同步(Pull-based):終端聯網時主動從 Descriptor_Issuer 或撤銷服務拉取增量撤銷清單。同步頻率由終端策略決定,SHOULD 不低於每小時一次(聯網期間)
  2. 推送通知(Push-based):Descriptor_Issuer 透過 Registration_Authority 或專門的撤銷分發服務向終端推送撤銷聲明
  3. 憑證內嵌(In-band):在 Trusted_Ticket 的 metadata 中攜帶最近撤銷清單的摘要,使聯網期間取得的票據自動捎帶撤銷資訊

3.4.3 終端撤銷清單維護

終端的本地撤銷清單 MUST:

  1. 永久儲存所有未過期的撤銷聲明
  2. 在憑證 not_after 時間過去後 MAY 刪除對應的撤銷聲明(憑證已自然失效)
  3. 驗證每條撤銷聲明的簽章,拒絕無效簽章的撤銷聲明

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 更新策略

授權人或自動續期機制可在以下場景觸發更新:

  1. 憑證臨近 not_after 且授權關係仍然有效
  2. 授權範圍需要調整(增加/減少 grants)
  3. 授權約束需要調整(修改 constraints)

3.5.2 更新流程

更新過程:

  1. Descriptor_Issuer 按 §3.1 流程簽發新的 Authorization_Descriptor,使用新的 descriptor_id
  2. 新憑證按 §3.2 流程提交到終端並儲存
  3. 舊憑證 MAY 由簽發方主動撤銷(按 §3.4),也 MAY 由其自然過期失效

終端在新舊憑證並存期間,處理優先順序:

  • 校驗請求 MUST 優先比對未過期的憑證
  • 多個未過期憑證均比對時,使用 issued_at 最近的憑證

3.5.3 不允許的更新行為

實作 MUST NOT:

  1. 修改已發布憑證的任何欄位(包括 metadata)
  2. 重複使用舊憑證的 descriptor_id
  3. 在舊憑證仍有效期間修改其語意(必須透過撤銷 + 新簽發實現)

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