第 4 章:線上票據協議
本章定義 Trusted_Ticket 的簽發、查詢、轉換和降級流程。本章流程對應藍圖 §2.2 的設計意圖。
4.1 適用前提
Trusted_Ticket 僅在終端能夠聯網存取 Ticket_Issuer 或線上撤銷服務時使用。當線上服務不可用時,終端按 §4.5 自動回退到離線授權。
終端 MUST 同時支援 Authorization_Descriptor(第 3 章)和 Trusted_Ticket。終端 MUST NOT 拒絕接受合法簽章的 Trusted_Ticket,即使該終端策略偏好離線授權。
4.2 簽發流程
4.2.1 簽發請求
授權人透過支援 CAP 的客戶端(如手機 App、Web 控制台)向 Ticket_Issuer 發起簽發請求。客戶端與 Ticket_Issuer 之間的互動不在本規範範圍內,但 Ticket_Issuer MUST:
- 驗證請求來源是經過身分驗證的授權人
- 驗證授權人有權對目標 Fay 和資源進行授權
- 套用本地策略校驗授權範圍(如最長有效期、資源白名單)
4.2.2 簽發步驟
Ticket_Issuer MUST 按以下步驟產生 Trusted_Ticket:
- 建構 Header:按 §2.4.2 設定
alg、typ、kid - 建構 Payload:按 §2.4.3 填充 TicketPayload,所有 required 欄位 MUST 設定
- 校驗約束:本地校驗
exp - nbf ≤ 7 天 - JSON 序列化:將 Header 和 Payload 序列化為 UTF-8 JSON 位元組
- Base64URL 編碼:對 Header 和 Payload 位元組分別進行 Base64URL 編碼
- 簽章:按 RFC 7515 計算簽章輸入
base64url(header) + "." + base64url(payload) - 產生 Compact Serialization:拼接為
header.payload.signature字串 - 登記記錄:在 Ticket_Issuer 內部維護已簽發票據狀態(用於撤銷查詢)
4.2.3 簽發後交付
Trusted_Ticket 透過 HTTPS 等加密通道交付給目標 Fay 或其 iFay_Runtime。交付的具體方式不在本規範範圍內。
4.3 終端校驗流程
終端校驗 Trusted_Ticket 與校驗 Authorization_Descriptor 的差異在於:
- Trusted_Ticket 在請求時由 iFay_Runtime 完整傳輸給終端(不預先儲存)
- 終端在聯網時 MAY 即時查詢 Ticket_Issuer 的撤銷狀態
- 校驗失敗時的錯誤碼以
E_TICKET_*前綴
4.3.1 校驗請求
iFay_Runtime 傳送的 AuthRequest 攜帶完整 Trusted_Ticket:
AuthRequest (body of ProtocolMessage) {
required fay_id : Fay_ID
required resource_id : Resource_ID
required access_mode : AccessMode
required credential : CredentialContent
}
CredentialContent {
required type : enum["descriptor_ref", "ticket"]
oneof:
descriptor_id : string // type == "descriptor_ref"
ticket : string // type == "ticket",JWS Compact 字串
}
4.3.2 校驗步驟(按順序執行)
終端 MUST 按以下順序執行校驗。任一步驟失敗立即返回錯誤。
第 1 步:JWS 解析
終端解析 JWS Compact 字串:
- 拆分
header.payload.signature三部分 - Base64URL 解碼 header 和 payload
- 驗證
header.typ == "cap-ticket+jws" - 驗證
header.alg在 §8 允許的演算法集合內
任一步驟失敗 → 返回 E_TICKET_MALFORMED
第 2 步:簽章校驗
終端使用 header.kid 對應的 Verification_Key 校驗 JWS 簽章(按 RFC 7515)。
- 簽章校驗失敗 → 返回
E_INVALID_SIGNATURE kid對應的金鑰未註冊或已撤銷 → 返回E_VERIFICATION_KEY_INVALID
第 3 步:有效期
按 §3.3.2 第 3 步的規則校驗 nbf 和 exp。
第 4 步:主體、終端、資源、模式比對
按 §3.3.2 第 4–6 步的規則進行比對。錯誤碼使用 E_TICKET_* 前綴(參見 §9)。
第 5 步:線上撤銷查詢(可選)
若終端策略要求線上撤銷驗證,終端 MAY 向 Ticket_Issuer 發起撤銷狀態查詢:
TicketRevocationQuery {
required jti : uuid
}
TicketRevocationResponse {
required jti : uuid
required revoked : boolean
optional revoked_at : timestamp
}
- 查詢逾時(預設 2 秒)→ 終端 SHOULD 拒絕該請求並返回
E_REVOCATION_QUERY_TIMEOUT,但 MAY 配置為允許通過(接受撤銷延遲風險) - 查詢返回
revoked == true→ 返回E_TICKET_REVOKED - 查詢失敗(如服務不可達)→ 終端 MAY 按本地快取的撤銷狀態決定,超出快取有效期則按逾時處理
終端 SHOULD 快取撤銷查詢結果,快取有效期不超過 5 分鐘。
4.3.3 校驗通過後
校驗通過後處理與 §3.3.3 一致,建立 Session 並返回 AuthResult。
4.4 轉換為離線 Authorization_Descriptor
當 TicketPayload.convertible == true(預設)時,終端可在校驗通過後將 Trusted_Ticket 轉換為本地 Authorization_Descriptor 以供離線使用。
4.4.1 轉換觸發
轉換 SHOULD 在以下情況自動執行:
- Trusted_Ticket 校驗通過且
convertible == true - 終端策略允許離線後續存取
TicketPayload.exp距目前時間足夠長(建議 > 1 小時)
4.4.2 轉換步驟
- 欄位對映:按 §2.4.4 表格將 TicketPayload 欄位對映到 DescriptorPayload
- 有效期約束:轉換後的
not_afterMUST 不超過min(TicketPayload.exp, 轉換時間 + 7 天) - 元資料保留:將原始 Trusted_Ticket 的關鍵稽核資訊存入 metadata:
metadata["origin"] = "converted_from_ticket"metadata["origin_jti"] = TicketPayload.jtimetadata["origin_iss"] = TicketPayload.issmetadata["origin_kid"] = TicketHeader.kid
- 本地簽章:終端使用其本地儲存金鑰對轉換後的 payload 重新簽章(參見 §4.4.3)
- 本地儲存:將轉換後的 Authorization_Descriptor 按 §3.2.3 加密儲存
4.4.3 終端本地簽章金鑰
為支援轉換流程,終端 MUST 持有一對本地簽章金鑰:
- 私鑰:保存在終端安全儲存中,僅供本地轉換流程使用
- 公鑰:作為
source == "pre-installed"類型的 Verification_Key 註冊到自身的金鑰儲存
轉換後的 Authorization_Descriptor 的 signature.key_id MUST 標識該本地金鑰,且 payload.issuer_id MUST 設定為 "local-conversion:" + terminal_id。
終端在校驗本地轉換的 Authorization_Descriptor 時,使用本地公鑰校驗簽章。這種設計確保:
- 轉換後的憑證可獨立離線校驗,不依賴原始 Ticket_Issuer
- 轉換信任鏈錨定在終端自身的金鑰安全性
4.4.4 轉換的局限性
本地轉換的 Authorization_Descriptor MUST NOT:
- 在其他終端被信任(其簽章 key_id 是本地的)
- 跨終端遷移使用
- 透過 Descriptor_Issuer 的撤銷機制被撤銷(必須透過本地刪除)
終端 SHOULD 在以下情況主動刪除本地轉換的 Authorization_Descriptor:
- 收到原始 Trusted_Ticket 的撤銷通知(透過 jti 關聯)
- 憑證已過期超過 24 小時
4.5 線上到離線降級
4.5.1 降級觸發
終端持續監測線上服務可用性。當滿足以下任一條件時,觸發降級:
- 與 Ticket_Issuer 的連線超過 30 秒不可達
- 撤銷查詢請求連續 3 次逾時
- 網路堆疊回報全域網路不可用
4.5.2 降級行為
降級後,終端按以下規則處理:
- 拒絕接受新的 Trusted_Ticket(除非配置為離線接受)——避免無法在線驗證撤銷狀態
- 已轉換為本地 Authorization_Descriptor 的票據繼續按 §3 規則使用
- 直接以 Authorization_Descriptor 進行授權校驗的請求不受降級影響
- 終端 MAY 提示 iFay_Runtime 目前處於離線模式,使 Fay 可調整行為策略
4.5.3 恢復
終端偵測到線上服務恢復後 MUST:
- 優先同步撤銷清單,將離線期間可能漏掉的撤銷聲明套用到本地狀態
- 重新檢查活躍 Session,對於使用本地轉換 Authorization_Descriptor 且已被原始 ticket 撤銷的 Session,按第 5 章規則強制終止
- 恢復正常的 Trusted_Ticket 接受策略
恢復過程對 iFay_Runtime 透明,但終端 MAY 透過 SessionStateChanged 通知模式變更。
4.6 雙憑證場景的優先級
當一個 Fay 同時持有針對同一資源的 Trusted_Ticket 和 Authorization_Descriptor 時,iFay_Runtime 的選擇策略:
| 網路狀態 | 推薦選擇 | 原因 |
|---|---|---|
| 線上且 Ticket_Issuer 可達 | Trusted_Ticket | 時效性更強,可即時撤銷 |
| 離線 | Authorization_Descriptor 或轉換後的本地憑證 | Trusted_Ticket 無法在線驗證撤銷 |
iFay_Runtime MAY 在 AuthRequest 中提供回退憑證,使終端在主憑證校驗失敗時嘗試備用憑證。本規範不強制定義回退機制的具體格式,但 SHOULD 透過兩次獨立的 AuthRequest 實作以避免協議複雜化。
4.7 Trusted_Ticket 與 Authorization_Descriptor 的語意一致性
當 iFay_Runtime 同時使用兩種憑證類型時,終端 MUST 保證:
- 校驗結果一致性:相同授權範圍在兩種憑證下校驗通過/拒絕的判定結果一致
- 錯誤碼語意一致性:等價的失敗原因(如有效期、簽章、撤銷)使用語意對應的錯誤碼(參見第 9 章)
- Session 建立一致性:透過兩種憑證建立的 Session 在生命週期管理上無差異
