第 2 章:数据模型

本章定义 CAP 协议中的核心数据结构,包括字段名称、类型、约束和默认值。本章中的字段定义是规范性的——任何符合 CAP 协议的实现 MUST 按本章定义生成和解析这些数据结构。

schema/{version}/schema.json 提供本章数据结构的形式化补充。当 schema.json 与本章描述存在冲突时,以 schema.json 为准。

2.1 数据类型约定

本规范使用以下基础类型描述字段:

类型说明编码
stringUTF-8 字符串UTF-8 字节序列
bytes字节序列原始字节
uint32 / uint64无符号整数大端序
timestampUnix 时间戳(秒)uint64
uuidRFC 4122 UUID v716 字节
enum枚举值字符串字面量
array<T>T 类型元素的有序集合数组
map<K,V>K 到 V 的映射对象

字段约束使用以下记号:

  • required:字段 MUST 出现,值不为 null
  • optional:字段 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_idrequired, unique本凭证的全局唯一标识
issuer_idrequired签发方标识,对应密钥信任路径中的 Descriptor_Issuer
subject_fay_idrequired被授权的 Fay 标识
terminal_idrequired授权范围限定的终端标识
grantsrequired, 1..256 个元素具体授权项列表(参见 §2.3.4)
issued_atrequired签发时间
not_beforerequired, ≥ issued_at生效起始时间
not_afterrequired, > not_before失效时间
grantor_idoptional授权人标识(Natural_Person 或 Official_Post)
metadataoptional签发方自定义元数据,对协议语义无影响

实现 MUST 拒绝以下条件不满足的 Authorization_Descriptor:

  1. not_after - not_before > 90 天:本规范限定单份凭证的最长有效期为 90 天
  2. not_before > 当前时间 + 24 小时:禁止签发过早生效的凭证(防止预签发滥用)
  3. 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:

  1. 仅支持上述三种语法,拒绝包含其他特殊字符的模式
  2. 通配符 * 仅匹配单层路径段
  3. 通配符 ** 仅可出现在模式末尾

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 字段
jtidescriptor_id
ississuer_id
subsubject_fay_id
audterminal_id
iatissued_at
nbfnot_before
expnot_after(但 MUST 不超过 iat + 7 天
grantsgrants

转换后的 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 协议使用以下序列化格式:

数据结构序列化格式用途
AuthorizationDescriptorRFC 8949 CBOR(确定性编码)离线存储与传输
Trusted_TicketRFC 7515 JWS Compact Serialization在线传输
ProtocolMessageJSON(UTF-8)iFay_Runtime ↔ Protocol_Engine 交互
RevocationStatementRFC 8949 CBOR(确定性编码)撤销列表分发

实现 MAY 在 ProtocolMessage 的传输层使用 CBOR 替代 JSON 以减少开销,但 schema.json 定义的字段名称和语义 MUST 保持一致。