第 2 章:資料模型
本章定義 CAP 協議中的核心資料結構,包括欄位名稱、類型、約束和預設值。本章中的欄位定義是規範性的——任何符合 CAP 協議的實作 MUST 按本章定義產生和解析這些資料結構。
schema/{version}/schema.json 提供本章資料結構的形式化補充。當 schema.json 與本章描述存在衝突時,以 schema.json 為準。
2.1 資料類型約定
本規範使用以下基礎類型描述欄位:
| 類型 | 說明 | 編碼 |
|---|---|---|
string | UTF-8 字串 | UTF-8 位元組序列 |
bytes | 位元組序列 | 原始位元組 |
uint32 / uint64 | 無符號整數 | 大端序 |
timestamp | Unix 時間戳記(秒) | uint64 |
uuid | RFC 4122 UUID v7 | 16 位元組 |
enum | 列舉值 | 字串字面量 |
array<T> | T 類型元素的有序集合 | 陣列 |
map<K,V> | K 到 V 的對映 | 物件 |
欄位約束使用以下記號:
required:欄位 MUST 出現,值不為 nulloptional:欄位 MAY 出現,省略時視為未設定unique:欄位值在系統範圍內唯一len(N..M):字串/位元組長度在 N 到 M 之間(含端點)regex(...):欄位值 MUST 比對指定正規表示式
2.2 識別碼
CAP 協議中的核心識別碼 MUST 滿足全域唯一性。本節定義各類識別碼的格式與產生規則。
2.2.1 Fay_ID
Fay_ID 唯一識別一個 Fay 實例。
| 屬性 | 取值 |
|---|---|
| 類型 | string |
| 格式 | "fay:" + uuid_v7 |
| 長度 | 40 字元(含前綴) |
| 唯一性 | 全域唯一 |
| 產生方 | 身分管理子系統(不在 CAP 協議範圍) |
範例:fay:01927b34-7e21-7c4d-a89f-1234567890ab
2.2.2 Terminal_ID
Terminal_ID 唯一識別一個終端裝置。
| 屬性 | 取值 |
|---|---|
| 類型 | string |
| 格式 | "terminal:" + uuid_v7 |
| 長度 | 45 字元(含前綴) |
| 唯一性 | 全域唯一 |
| 產生方 | Registration_Authority |
2.2.3 Resource_ID
Resource_ID 識別終端上的一個具體資源。
| 屬性 | 取值 |
|---|---|
| 類型 | string |
| 格式 | terminal_id + "/" + resource_path |
| 長度 | 最長 256 字元 |
| 唯一性 | 終端範圍內唯一 |
| 產生方 | 終端作業系統 |
resource_path MUST 滿足正規式 ^[a-zA-Z0-9._\-/]+$。
範例:terminal:01927b34-.../device/camera/front
2.2.4 Descriptor_ID
Descriptor_ID 唯一識別一份 Authorization_Descriptor。
| 屬性 | 取值 |
|---|---|
| 類型 | uuid |
| 格式 | UUID v7 |
| 唯一性 | 全域唯一(在所有 Descriptor_Issuer 範圍內) |
| 產生方 | Descriptor_Issuer |
撤銷清單使用 Descriptor_ID 標識被撤銷的憑證。Descriptor_Issuer MUST NOT 重複使用已使用過的 Descriptor_ID。
2.2.5 Session_ID
Session_ID 唯一識別一個活躍會話。
| 屬性 | 取值 |
|---|---|
| 類型 | uuid |
| 格式 | UUID v7 |
| 唯一性 | 終端範圍內唯一 |
| 產生方 | 終端 Protocol_Engine |
| 生命週期 | 僅在會話活躍期間有效,會話終止後該 ID 不重複使用 |
2.3 Authorization_Descriptor
Authorization_Descriptor 是離線授權的核心資料結構。一份 Authorization_Descriptor 由兩部分組成:載荷(payload) 和 簽章(signature)。
2.3.1 頂層結構
AuthorizationDescriptor {
required version : uint32
required payload : DescriptorPayload
required signature : DescriptorSignature
}
| 欄位 | 說明 |
|---|---|
version | 協議版本號,v1 實作 MUST 設為 1 |
payload | 授權資訊載荷(參見 §2.3.2) |
signature | 對 payload 的數位簽章(參見 §2.3.3) |
2.3.2 DescriptorPayload
DescriptorPayload {
required descriptor_id : Descriptor_ID
required issuer_id : string
required subject_fay_id : Fay_ID
required terminal_id : Terminal_ID
required grants : array<Grant> (len 1..256)
required issued_at : timestamp
required not_before : timestamp
required not_after : timestamp
optional grantor_id : string
optional metadata : map<string, string>
}
| 欄位 | 約束 | 說明 |
|---|---|---|
descriptor_id | required, unique | 本憑證的全域唯一識別碼 |
issuer_id | required | 簽發方識別碼,對應金鑰信任路徑中的 Descriptor_Issuer |
subject_fay_id | required | 被授權的 Fay 識別碼 |
terminal_id | required | 授權範圍限定的終端識別碼 |
grants | required, 1..256 個元素 | 具體授權項列表(參見 §2.3.4) |
issued_at | required | 簽發時間 |
not_before | required, ≥ issued_at | 生效起始時間 |
not_after | required, > not_before | 失效時間 |
grantor_id | optional | 授權人識別碼(Natural_Person 或 Official_Post) |
metadata | optional | 簽發方自訂中繼資料,對協議語意無影響 |
實作 MUST 拒絕以下條件不滿足的 Authorization_Descriptor:
not_after - not_before > 90 天:本規範限定單份憑證的最長有效期為 90 天not_before > 目前時間 + 24 小時:禁止簽發過早生效的憑證(防止預簽發濫用)grants陣列為空:無授權項的憑證無意義
2.3.3 DescriptorSignature
DescriptorSignature {
required algorithm : enum["ed25519", "ecdsa-p256-sha256"]
required key_id : string
required signature_value : bytes
}
| 欄位 | 說明 |
|---|---|
algorithm | 簽章演算法,參見第 8 章 |
key_id | 用於簽章的金鑰識別碼,對應 Verification_Key 識別碼 |
signature_value | 對 payload 的 CBOR 序列化位元組進行簽章的結果 |
簽章輸入:將 DescriptorPayload 按 RFC 8949 CBOR 確定性編碼(Deterministic Encoding)序列化為位元組序列,作為簽章演算法的輸入。
2.3.4 Grant
Grant {
required resource_pattern : string
required modes : array<AccessMode> (len 1..4)
optional constraints : map<string, string>
}
| 欄位 | 說明 |
|---|---|
resource_pattern | 資源比對模式(參見 §2.3.5) |
modes | 授權的存取模式列表,元素類型 AccessMode |
constraints | 附加約束(如時間視窗、地理圍欄等),對協議語意的影響參見第 7 章 |
2.3.5 資源比對模式
resource_pattern 支援以下比對語法:
- 精確比對:
terminal:xxx/device/camera/front - 萬用字元比對:
terminal:xxx/device/camera/*(比對該終端下所有攝影機) - 全終端比對:
terminal:xxx/device/camera/**(比對該路徑下所有層級)
實作 MUST:
- 僅支援上述三種語法,拒絕包含其他特殊字元的模式
- 萬用字元
*僅比對單層路徑段 - 萬用字元
**僅可出現在模式末尾
2.3.6 AccessMode
AccessMode = enum["read", "write", "execute", "configure"]
各存取模式的語意參見第 7 章。
2.4 Trusted_Ticket
Trusted_Ticket 是線上授權憑證。其結構基於 RFC 7515 JWS Compact Serialization。
2.4.1 頂層結構
Trusted_Ticket 是一個 JWS 字串,由三部分用 . 分隔:
base64url(header) . base64url(payload) . base64url(signature)
2.4.2 Header
TicketHeader {
required alg : enum["EdDSA", "ES256"]
required typ : "cap-ticket+jws"
required kid : string
}
| 欄位 | 說明 |
|---|---|
alg | 簽章演算法(與 §8 一致) |
typ | 固定值 "cap-ticket+jws",用於區分票據類型 |
kid | 金鑰識別碼,用於校驗簽章 |
2.4.3 Payload
TicketPayload {
required jti : uuid // 票據唯一 ID
required iss : string // Ticket_Issuer 識別碼
required sub : Fay_ID // 被授權的 Fay
required aud : Terminal_ID // 目標終端
required iat : timestamp // 簽發時間
required nbf : timestamp // 生效起始時間
required exp : timestamp // 失效時間
required grants : array<Grant> // 與 §2.3.4 同結構
optional convertible : boolean (default true) // 是否可轉換為 Authorization_Descriptor
}
實作 MUST 拒絕 exp - nbf > 7 天 的 Trusted_Ticket。線上票據的最長有效期短於離線授權,以確保線上撤銷機制能夠及時生效。
2.4.4 Trusted_Ticket 到 Authorization_Descriptor 的轉換
當 convertible == true 時,終端 MAY 將 Trusted_Ticket 轉換為本地 Authorization_Descriptor 格式以供離線使用。轉換規則:
| TicketPayload 欄位 | 對映到 DescriptorPayload 欄位 |
|---|---|
jti | descriptor_id |
iss | issuer_id |
sub | subject_fay_id |
aud | terminal_id |
iat | issued_at |
nbf | not_before |
exp | not_after(但 MUST 不超過 iat + 7 天) |
grants | grants |
轉換後的 Authorization_Descriptor 由終端使用其本地儲存金鑰重新簽章,簽章 key_id 標記為轉換來源(參見第 4 章)。原始 Trusted_Ticket 的簽章資訊 MUST 保留在 metadata 中以備稽核。
2.5 Session
Session 是終端內部的會話狀態結構,不透過協議訊息傳輸完整結構。本節定義 Session 的欄位以便規範狀態機和介面約定。
Session {
required session_id : Session_ID
required fay_id : Fay_ID
required runtime_id : string
required resource_id : Resource_ID
required access_mode : AccessMode
required granted_modes : array<AccessMode>
required state : SessionState
required created_at : timestamp
required last_heartbeat_at : timestamp
required credential_ref : CredentialRef
}
SessionState = enum[
"creating",
"active",
"handover_pending",
"terminating",
"terminated"
]
CredentialRef {
required type : enum["descriptor", "ticket"]
required id : string // descriptor_id 或 jti
required not_after : timestamp
}
SessionState 狀態機參見第 5 章。
2.6 協議訊息封裝
iFay_Runtime 與 Protocol_Engine 之間的所有訊息共用以下封裝結構:
ProtocolMessage {
required version : uint32 (= 1)
required message_id : uuid
required message_type : string
required timestamp : timestamp
required sender_id : string
required body : object
optional correlation_id : uuid
}
| 欄位 | 說明 |
|---|---|
version | 協議版本號,v1 設為 1 |
message_id | 本訊息的唯一識別碼 |
message_type | 訊息類型字面量(如 "AuthRequest") |
timestamp | 訊息傳送時間 |
sender_id | 傳送方識別碼(runtime_id 或 terminal_id) |
body | 訊息主體,結構由 message_type 決定 |
correlation_id | 關聯的請求訊息 ID(回應訊息 MUST 設定此欄位) |
各 message_type 對應的 body 結構在相應章節定義。
2.7 Verification_Key
Verification_Key 是終端持有的簽章校驗金鑰。
VerificationKey {
required key_id : string
required algorithm : enum["ed25519", "ecdsa-p256-sha256"]
required key_material : bytes // 公鑰位元組
required issuer_id : string // 該金鑰對應的簽發方識別碼
required valid_from : timestamp
optional valid_until : timestamp
required source : enum["pre-installed", "ra-distributed"]
}
| 欄位 | 說明 |
|---|---|
key_id | 金鑰識別碼,與 DescriptorSignature.key_id 對應 |
algorithm | 該金鑰支援的簽章演算法 |
key_material | 公鑰的原始位元組,編碼方式由 algorithm 決定(參見第 8 章) |
issuer_id | 該金鑰對應的 Descriptor_Issuer 識別碼 |
valid_from | 金鑰生效起始時間 |
valid_until | 金鑰失效時間,未設定表示長期有效 |
source | 金鑰來源:pre-installed(終端出廠預置)或 ra-distributed(Registration_Authority 線上分發) |
終端 MUST 安全儲存所有 Verification_Key(參見第 8 章)。
2.8 撤銷聲明
撤銷聲明用於通知終端某份憑證已被撤銷。
RevocationStatement {
required version : uint32 (= 1)
required revocation_id : uuid
required target_descriptor_id : Descriptor_ID
required issuer_id : string
required revoked_at : timestamp
optional reason : enum["unspecified", "compromised", "superseded", "no_longer_needed"]
required signature : DescriptorSignature
}
撤銷聲明 MUST 由原始 Authorization_Descriptor 的 issuer_id 簽發並簽章。
2.9 序列化與傳輸
CAP 協議使用以下序列化格式:
| 資料結構 | 序列化格式 | 用途 |
|---|---|---|
| AuthorizationDescriptor | RFC 8949 CBOR(確定性編碼) | 離線儲存與傳輸 |
| Trusted_Ticket | RFC 7515 JWS Compact Serialization | 線上傳輸 |
| ProtocolMessage | JSON(UTF-8) | iFay_Runtime ↔ Protocol_Engine 互動 |
| RevocationStatement | RFC 8949 CBOR(確定性編碼) | 撤銷清單分發 |
實作 MAY 在 ProtocolMessage 的傳輸層使用 CBOR 取代 JSON 以減少額外負擔,但 schema.json 定義的欄位名稱和語意 MUST 保持一致。
