1import typing as t
2
3import typing_extensions as te
4from pydantic import model_validator
5
6from sigstore_models._core import Base, ProtoBytes, ProtoU64
7from sigstore_models.common.v1 import LogId
8
9
10class KindVersion(Base):
11 kind: str
12 version: str
13
14
15class Checkpoint(Base):
16 envelope: str
17
18
19class InclusionProof(Base):
20 log_index: ProtoU64
21 root_hash: ProtoBytes
22 tree_size: ProtoU64
23 hashes: list[ProtoBytes]
24 checkpoint: t.Optional[Checkpoint] = None
25
26 @model_validator(mode="after")
27 def validate_log_index_in_tree_size(self) -> te.Self:
28 if self.tree_size <= self.log_index:
29 raise ValueError(
30 f"logIndex {self.log_index} must be less than treeSize {self.tree_size}"
31 )
32 return self
33
34
35class InclusionPromise(Base):
36 signed_entry_timestamp: ProtoBytes
37
38
39class TransparencyLogEntry(Base):
40 log_index: ProtoU64
41 log_id: LogId
42 kind_version: KindVersion
43 # NOTE: protobuf-specs claims this is mandatory, but in practice
44 # it's optional.
45 integrated_time: t.Optional[ProtoU64] = None
46 inclusion_promise: t.Optional[InclusionPromise] = None
47 inclusion_proof: InclusionProof
48 # NOTE: Technically optional in protobuf-specs, but
49 # de facto required by sigstore-python.
50 canonicalized_body: ProtoBytes