diff --git a/Makefile b/Makefile index 7e84a60..fdc428c 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SHELL := /bin/bash -PY_MODULE := sigstore_rekor_types +PY_MODULE := rekor_types ALL_PY_SRCS := $(shell find $(PY_MODULE) -name '*.py') diff --git a/codegen/codegen.sh b/codegen/codegen.sh index 3dc8a44..584be6c 100755 --- a/codegen/codegen.sh +++ b/codegen/codegen.sh @@ -40,29 +40,46 @@ git clone --quiet \ https://github.com/sigstore/rekor \ "${rekor_dir}" -# NOTE(ww): For whatever reason, the POST endpoint doesn't work. Instead, -# we tell the converter to retrieve the OpenAPI YAML URL itself. -curl -X 'GET' \ - "https://converter.swagger.io/api/convert?url=https%3A%2F%2Fraw.githubusercontent.com%2Fsigstore%2Frekor%2F${rekor_ref}%2Fopenapi.yaml" \ - -H 'accept: application/json' \ - > "${rekor_dir}/openapi.json" - -datamodel-codegen \ - --input "${rekor_dir}/openapi.json" \ - --input-file-type openapi \ - --target-python-version 3.8 \ - --snake-case-field \ - --capitalize-enum-members \ - --field-constraints \ - --use-schema-description \ - --use-subclass-enum \ - --disable-timestamp \ - --reuse-model \ - --use-default-kwarg \ - --allow-population-by-field-name \ - --strict-types str bytes int float bool \ - --output-model-type pydantic_v2.BaseModel \ - --output "${pkg_dir}/_internal.py" +# NOTE(ww): Everything below happens because of a confluence of unfortunate +# factors: +# +# * Rekor's top-level `openapi.yaml` is written in OpenAPI 2.0 (because go-swagger +# only supports 2.0) +# * `datamodel-codegen` only supports OpenAPI 3.0+ +# * If we convert Rekor's `openapi.yaml` into an OpenAPI 3.0 format, then +# `datamodel-codegen` *works*, but produces suboptimal code (lots +# of duplicated models like `Hash1`, `Hash2`, etc. in the same namespace). +# +# To get around all of this, we poke through each internal JSON Schema definition +# used by Rekor and generate them one-by-one into their own modules. +# +# See: +# * https://github.com/go-swagger/go-swagger/issues/1122 +# * https://github.com/koxudaxi/datamodel-code-generator/issues/1590 +# * https://github.com/sigstore/rekor/issues/1729 +mkdir -p "${pkg_dir}/_internal" +touch "${pkg_dir}/_internal/__init__.py" +rekor_types=(alpine cose dsse hashedrekord helm intoto jar rekord rfc3161 rpm tuf) +for type in "${rekor_types[@]}"; do + dbg "generating models for Rekor type: ${type}" + datamodel-codegen \ + --input "${rekor_dir}/pkg/types/${type}/${type}_schema.json" \ + --input-file-type jsonschema \ + --target-python-version 3.8 \ + --collapse-root-models \ + --snake-case-field \ + --capitalize-enum-members \ + --field-constraints \ + --use-schema-description \ + --use-subclass-enum \ + --disable-timestamp \ + --reuse-model \ + --use-default-kwarg \ + --allow-population-by-field-name \ + --strict-types str bytes int float bool \ + --output-model-type pydantic_v2.BaseModel \ + --output "${pkg_dir}/_internal/${type}.py" +done # Cap it off by auto-reformatting. make -C "${here}/.." reformat diff --git a/pyproject.toml b/pyproject.toml index 597bfee..71af50f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,10 @@ classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: Apache Software License", ] -dependencies = ["pydantic[email] >=2,<3"] +dependencies = [ + "pydantic[email] >=2,<3", + "typing-extensions; python_version < '3.9'", +] requires-python = ">=3.8" [project.optional-dependencies] @@ -28,6 +31,8 @@ lint = [ codegen = ["datamodel-code-generator", "sigstore-rekor-types[lint]"] dev = ["sigstore-rekor-types[codegen,doc,lint]", "build"] +[tool.flit.module] +name = "rekor_types" [project.urls] Homepage = "https://pypi.org/project/sigstore-rekor-types" @@ -60,7 +65,10 @@ line-length = 100 select = ["ALL"] [tool.ruff.per-file-ignores] -"sigstore_rekor_types/_internal.py" = [ +"rekor_types/__init__.py" = [ + "TCH001", # False positive: imports are re-exports, not just for type hints. +] +"rekor_types/_internal/*.py" = [ "A003", # some fields shadow python builtins "E501", # handled by black, and catches some docstrings we can't autofix "UP006", # pydantic doesn't support PEP 585 below Python 3.9 diff --git a/rekor_types/__init__.py b/rekor_types/__init__.py new file mode 100644 index 0000000..56c703b --- /dev/null +++ b/rekor_types/__init__.py @@ -0,0 +1,130 @@ +"""The `sigstore_rekor_types` APIs.""" + +from __future__ import annotations + +import sys +from typing import Literal, Union + +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr + +from ._internal import ( + alpine, + cose, + dsse, + hashedrekord, + helm, + intoto, + jar, + rekord, + rfc3161, + rpm, + tuf, +) + +if sys.version_info < (3, 9): + from typing_extensions import Annotated +else: + from typing import Annotated + +__version__ = "0.0.11" + + +class Error(BaseModel): + """A Rekor server error.""" + + code: StrictInt + message: StrictStr + + +class _ProposedEntryMixin(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + api_version: StrictStr = Field( + pattern=r"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$", + default="0.0.1", + alias="apiVersion", + ) + + +class Alpine(_ProposedEntryMixin): + """Proposed entry model for an `alpine` record.""" + + kind: Literal["alpine"] = "alpine" + spec: alpine.AlpinePackageSchema + + +class Cose(_ProposedEntryMixin): + """Proposed entry model for a `cose` record.""" + + kind: Literal["cose"] = "cose" + spec: cose.CoseSchema + + +class Dsse(_ProposedEntryMixin): + """Proposed entry model for a `dsse` record.""" + + kind: Literal["dsse"] = "dsse" + spec: dsse.DsseSchema + + +class Hashedrekord(_ProposedEntryMixin): + """Proposed entry model for a `dsse` record.""" + + kind: Literal["hashedrekord"] = "hashedrekord" + spec: hashedrekord.RekorSchema + + +class Helm(_ProposedEntryMixin): + """Proposed entry model for a `dsse` record.""" + + kind: Literal["helm"] = "helm" + spec: helm.HelmSchema + + +class Intoto(_ProposedEntryMixin): + """Proposed entry model for a `dsse` record.""" + + kind: Literal["intoto"] = "intoto" + spec: intoto.IntotoSchema + + +class Jar(_ProposedEntryMixin): + """Proposed entry model for a `jar` record.""" + + kind: Literal["jar"] = "jar" + spec: jar.JarSchema + + +class Rekord(_ProposedEntryMixin): + """Proposed entry model for a `rekord` record.""" + + kind: Literal["rekord"] = "rekord" + spec: rekord.RekorSchema + + +class Rfc3161(_ProposedEntryMixin): + """Proposed entry model for a `rfc3161` record.""" + + kind: Literal["rfc3161"] = "rfc3161" + spec: rfc3161.TimestampSchema + + +class Rpm(_ProposedEntryMixin): + """Proposed entry model for an `rpm` record.""" + + kind: Literal["rpm"] = "rpm" + spec: rpm.RpmSchema + + +class Tuf(_ProposedEntryMixin): + """Proposed entry model for a `tuf` record.""" + + kind: Literal["tuf"] = "tuf" + spec: tuf.TufSchema + + +ProposedEntry = Annotated[ + Union[Alpine, Cose, Dsse, Hashedrekord, Helm, Intoto, Jar, Rekord, Rfc3161, Rpm, Tuf], + Field(discriminator="kind"), +] diff --git a/sigstore_rekor_types/py.typed b/rekor_types/_internal/__init__.py similarity index 100% rename from sigstore_rekor_types/py.typed rename to rekor_types/_internal/__init__.py diff --git a/rekor_types/_internal/alpine.py b/rekor_types/_internal/alpine.py new file mode 100644 index 0000000..cad62b4 --- /dev/null +++ b/rekor_types/_internal/alpine.py @@ -0,0 +1,41 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from pydantic import BaseModel, ConfigDict, Field, RootModel + + +class PublicKey(BaseModel): + """The public key that can verify the package signature.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: str = Field( + ..., + description="Specifies the content of the public key inline within the document", + ) + + +class AlpineV001Schema(BaseModel): + """Schema for Alpine Package entries.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + public_key: PublicKey = Field( + ..., + alias="publicKey", + description="The public key that can verify the package signature", + ) + + +class AlpinePackageSchema(RootModel[AlpineV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: AlpineV001Schema = Field( + ..., + description="Schema for Alpine package objects", + title="Alpine Package Schema", + ) diff --git a/rekor_types/_internal/cose.py b/rekor_types/_internal/cose.py new file mode 100644 index 0000000..0d1ac63 --- /dev/null +++ b/rekor_types/_internal/cose.py @@ -0,0 +1,84 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from enum import Enum +from typing import Optional + +from pydantic import BaseModel, ConfigDict, Field, RootModel, StrictStr + + +class Algorithm(str, Enum): + """The hashing function used to compute the hash value.""" + + SHA256 = "sha256" + + +class PayloadHash(BaseModel): + """Specifies the hash algorithm and value for the content.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field(..., description="The hash value for the content") + + +class EnvelopeHash(BaseModel): + """Specifies the hash algorithm and value for the COSE envelope.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field(..., description="The hash value for the envelope") + + +class Data(BaseModel): + """Information about the content associated with the entry.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + payload_hash: Optional[PayloadHash] = Field( + default=None, + alias="payloadHash", + description="Specifies the hash algorithm and value for the content", + ) + envelope_hash: Optional[EnvelopeHash] = Field( + default=None, + alias="envelopeHash", + description="Specifies the hash algorithm and value for the COSE envelope", + ) + aad: Optional[str] = Field( + default=None, + description="Specifies the additional authenticated data required to verify the signature", + ) + + +class CoseV001Schema(BaseModel): + """Schema for cose object.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + message: Optional[str] = Field(default=None, description="The COSE Sign1 Message") + public_key: str = Field( + ..., + alias="publicKey", + description="The public key that can verify the signature", + ) + data: Data = Field(..., description="Information about the content associated with the entry") + + +class CoseSchema(RootModel[CoseV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: CoseV001Schema = Field(..., description="COSE for Rekord objects", title="COSE Schema") diff --git a/rekor_types/_internal/dsse.py b/rekor_types/_internal/dsse.py new file mode 100644 index 0000000..fefc23e --- /dev/null +++ b/rekor_types/_internal/dsse.py @@ -0,0 +1,122 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from enum import Enum +from typing import List, Optional + +from pydantic import BaseModel, ConfigDict, Field, RootModel, StrictStr + + +class ProposedContent(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + envelope: StrictStr = Field( + ..., + description="DSSE envelope specified as a stringified JSON object", + ) + verifiers: List[str] = Field( + ..., + description=( + "collection of all verification material (e.g. public keys or certificates) used to" + " verify signatures over envelope's payload, specified as base64-encoded strings" + ), + min_length=1, + ) + + +class Signature(BaseModel): + """a signature of the envelope's payload along with the verification material for the signature.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + signature: StrictStr = Field(..., description="base64 encoded signature of the payload") + verifier: str = Field( + ..., + description=( + "verification material that was used to verify the corresponding signature, specified" + " as a base64 encoded string" + ), + ) + + +class Algorithm(str, Enum): + """The hashing function used to compute the hash value.""" + + SHA256 = "sha256" + + +class EnvelopeHash(BaseModel): + """Specifies the hash algorithm and value encompassing the entire envelope sent to Rekor.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field( + ..., + description="The value of the computed digest over the entire envelope", + ) + + +class PayloadHash(BaseModel): + """Specifies the hash algorithm and value covering the payload within the DSSE envelope.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field( + ..., + description="The value of the computed digest over the payload within the envelope", + ) + + +class DsseV001Schema(BaseModel): + """Schema for DSSE envelopes.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + proposed_content: Optional[ProposedContent] = Field(default=None, alias="proposedContent") + signatures: Optional[List[Signature]] = Field( + default=None, + description=( + "extracted collection of all signatures of the envelope's payload; elements will be" + " sorted by lexicographical order of the base64 encoded signature strings" + ), + min_length=1, + ) + envelope_hash: Optional[EnvelopeHash] = Field( + default=None, + alias="envelopeHash", + description=( + "Specifies the hash algorithm and value encompassing the entire envelope sent to Rekor" + ), + ) + payload_hash: Optional[PayloadHash] = Field( + default=None, + alias="payloadHash", + description=( + "Specifies the hash algorithm and value covering the payload within the DSSE envelope" + ), + ) + + +class DsseSchema(RootModel[DsseV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: DsseV001Schema = Field( + ..., + description="log entry schema for dsse envelopes", + title="DSSE Schema", + ) diff --git a/rekor_types/_internal/hashedrekord.py b/rekor_types/_internal/hashedrekord.py new file mode 100644 index 0000000..56ccad6 --- /dev/null +++ b/rekor_types/_internal/hashedrekord.py @@ -0,0 +1,98 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from enum import Enum +from typing import Optional + +from pydantic import BaseModel, ConfigDict, Field, RootModel, StrictStr + + +class PublicKey(BaseModel): + """The public key that can verify the signature; this can also be an X509 code signing certificate that contains the raw public key information.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: Optional[str] = Field( + default=None, + description=( + "Specifies the content of the public key or code signing certificate inline within the" + " document" + ), + ) + + +class Signature(BaseModel): + """Information about the detached signature associated with the entry.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: Optional[str] = Field( + default=None, + description="Specifies the content of the signature inline within the document", + ) + public_key: Optional[PublicKey] = Field( + default=None, + alias="publicKey", + description=( + "The public key that can verify the signature; this can also be an X509 code signing" + " certificate that contains the raw public key information" + ), + ) + + +class Algorithm(str, Enum): + """The hashing function used to compute the hash value.""" + + SHA256 = "sha256" + + +class Hash(BaseModel): + """Specifies the hash algorithm and value for the content.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field(..., description="The hash value for the content") + + +class Data(BaseModel): + """Information about the content associated with the entry.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + hash: Optional[Hash] = Field( + default=None, + description="Specifies the hash algorithm and value for the content", + ) + + +class HashedrekordV001Schema(BaseModel): + """Schema for Hashed Rekord object.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + signature: Signature = Field( + ..., + description="Information about the detached signature associated with the entry", + ) + data: Data = Field(..., description="Information about the content associated with the entry") + + +class RekorSchema(RootModel[HashedrekordV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: HashedrekordV001Schema = Field( + ..., + description="Schema for Rekord objects", + title="Rekor Schema", + ) diff --git a/rekor_types/_internal/helm.py b/rekor_types/_internal/helm.py new file mode 100644 index 0000000..2b5e20c --- /dev/null +++ b/rekor_types/_internal/helm.py @@ -0,0 +1,75 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from enum import Enum +from typing import Optional + +from pydantic import BaseModel, ConfigDict, Field, RootModel, StrictStr + + +class PublicKey(BaseModel): + """The public key that can verify the package signature.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: str = Field( + ..., + description="Specifies the content of the public key inline within the document", + ) + + +class Algorithm(str, Enum): + """The hashing function used to compute the hash value.""" + + SHA256 = "sha256" + + +class Hash(BaseModel): + """Specifies the hash algorithm and value for the chart.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field(..., description="The hash value for the chart") + + +class Chart(BaseModel): + """Information about the Helm chart associated with the entry.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + hash: Optional[Hash] = Field( + default=None, + description="Specifies the hash algorithm and value for the chart", + ) + + +class HelmV001Schema(BaseModel): + """Schema for Helm object.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + public_key: PublicKey = Field( + ..., + alias="publicKey", + description="The public key that can verify the package signature", + ) + chart: Chart = Field( + ..., + description="Information about the Helm chart associated with the entry", + ) + + +class HelmSchema(RootModel[HelmV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: HelmV001Schema = Field(..., description="Schema for Helm objects", title="Helm Schema") diff --git a/rekor_types/_internal/intoto.py b/rekor_types/_internal/intoto.py new file mode 100644 index 0000000..091e0ec --- /dev/null +++ b/rekor_types/_internal/intoto.py @@ -0,0 +1,179 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from enum import Enum +from typing import List, Optional, Union + +from pydantic import BaseModel, ConfigDict, Field, RootModel, StrictStr + + +class Algorithm(str, Enum): + """The hashing function used to compute the hash value.""" + + SHA256 = "sha256" + + +class Hash(BaseModel): + """Specifies the hash algorithm and value encompassing the entire signed envelope; this is computed by the rekor server, client-provided values are ignored.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field(..., description="The hash value for the archive") + + +class PayloadHash(BaseModel): + """Specifies the hash algorithm and value covering the payload within the DSSE envelope; this is computed by the rekor server, client-provided values are ignored.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field(..., description="The hash value for the envelope's payload") + + +class Content(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + envelope: Optional[StrictStr] = Field(default=None, description="envelope") + hash: Optional[Hash] = Field( + default=None, + description=( + "Specifies the hash algorithm and value encompassing the entire signed envelope; this" + " is computed by the rekor server, client-provided values are ignored" + ), + ) + payload_hash: Optional[PayloadHash] = Field( + default=None, + alias="payloadHash", + description=( + "Specifies the hash algorithm and value covering the payload within the DSSE envelope;" + " this is computed by the rekor server, client-provided values are ignored" + ), + ) + + +class IntotoV001Schema(BaseModel): + """Schema for intoto object.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: Content + public_key: str = Field( + ..., + alias="publicKey", + description="The public key that can verify the signature", + ) + + +class Signature(BaseModel): + """a signature of the envelope's payload along with the public key for the signature.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + keyid: Optional[StrictStr] = Field( + default=None, + description="optional id of the key used to create the signature", + ) + sig: str = Field(..., description="signature of the payload") + public_key: str = Field( + ..., + alias="publicKey", + description="public key that corresponds to this signature", + ) + + +class Envelope(BaseModel): + """dsse envelope.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + payload: Optional[str] = Field(default=None, description="payload of the envelope") + payload_type: StrictStr = Field( + ..., + alias="payloadType", + description="type describing the payload", + ) + signatures: List[Signature] = Field( + ..., + description="collection of all signatures of the envelope's payload", + min_length=1, + ) + + +class Hash1(BaseModel): + """Specifies the hash algorithm and value encompassing the entire signed envelope.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field(..., description="The hash value for the archive") + + +class PayloadHash1(BaseModel): + """Specifies the hash algorithm and value covering the payload within the DSSE envelope.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + algorithm: Algorithm = Field( + ..., + description="The hashing function used to compute the hash value", + ) + value: StrictStr = Field(..., description="The hash value of the payload") + + +class Content1(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + envelope: Envelope = Field(..., description="dsse envelope") + hash: Optional[Hash1] = Field( + default=None, + description=( + "Specifies the hash algorithm and value encompassing the entire signed envelope" + ), + ) + payload_hash: Optional[PayloadHash1] = Field( + default=None, + alias="payloadHash", + description=( + "Specifies the hash algorithm and value covering the payload within the DSSE envelope" + ), + ) + + +class IntotoV002Schema(BaseModel): + """Schema for intoto object.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: Content1 + + +class IntotoSchema(RootModel[Union[IntotoV001Schema, IntotoV002Schema]]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Union[IntotoV001Schema, IntotoV002Schema] = Field( + ..., + description="Intoto for Rekord objects", + title="Intoto Schema", + ) diff --git a/rekor_types/_internal/jar.py b/rekor_types/_internal/jar.py new file mode 100644 index 0000000..f8efde9 --- /dev/null +++ b/rekor_types/_internal/jar.py @@ -0,0 +1,61 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from typing import Optional + +from pydantic import BaseModel, ConfigDict, Field, RootModel + + +class PublicKey(BaseModel): + """The X509 certificate containing the public key JAR which verifies the signature of the JAR.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: str = Field( + ..., + description=( + "Specifies the content of the X509 certificate containing the public key used to verify" + " the signature" + ), + ) + + +class Signature(BaseModel): + """Information about the included signature in the JAR file.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: str = Field( + ..., + description="Specifies the PKCS7 signature embedded within the JAR file ", + ) + public_key: PublicKey = Field( + ..., + alias="publicKey", + description=( + "The X509 certificate containing the public key JAR which verifies the signature of" + " the JAR" + ), + ) + + +class JarV001Schema(BaseModel): + """Schema for JAR entries.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + signature: Optional[Signature] = Field( + default=None, + description="Information about the included signature in the JAR file", + ) + + +class JarSchema(RootModel[JarV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: JarV001Schema = Field(..., description="Schema for JAR objects", title="JAR Schema") diff --git a/rekor_types/_internal/rekord.py b/rekor_types/_internal/rekord.py new file mode 100644 index 0000000..191122b --- /dev/null +++ b/rekor_types/_internal/rekord.py @@ -0,0 +1,69 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from enum import Enum + +from pydantic import BaseModel, ConfigDict, Field, RootModel + + +class Format(str, Enum): + """Specifies the format of the signature.""" + + PGP = "pgp" + MINISIGN = "minisign" + X509 = "x509" + SSH = "ssh" + + +class PublicKey(BaseModel): + """The public key that can verify the signature.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: str = Field( + ..., + description="Specifies the content of the public key inline within the document", + ) + + +class Signature(BaseModel): + """Information about the detached signature associated with the entry.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + format: Format = Field(..., description="Specifies the format of the signature") + content: str = Field( + ..., + description="Specifies the content of the signature inline within the document", + ) + public_key: PublicKey = Field( + ..., + alias="publicKey", + description="The public key that can verify the signature", + ) + + +class RekordV001Schema(BaseModel): + """Schema for Rekord object.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + signature: Signature = Field( + ..., + description="Information about the detached signature associated with the entry", + ) + + +class RekorSchema(RootModel[RekordV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: RekordV001Schema = Field( + ..., + description="Schema for Rekord objects", + title="Rekor Schema", + ) diff --git a/rekor_types/_internal/rfc3161.py b/rekor_types/_internal/rfc3161.py new file mode 100644 index 0000000..4fffd7c --- /dev/null +++ b/rekor_types/_internal/rfc3161.py @@ -0,0 +1,37 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from pydantic import BaseModel, ConfigDict, Field, RootModel + + +class Tsr(BaseModel): + """Information about the tsr file associated with the entry.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: str = Field( + ..., + description="Specifies the tsr file content inline within the document", + ) + + +class Rfc3161V001Schema(BaseModel): + """Schema for RFC3161 entries.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + tsr: Tsr = Field(..., description="Information about the tsr file associated with the entry") + + +class TimestampSchema(RootModel[Rfc3161V001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Rfc3161V001Schema = Field( + ..., + description="Schema for RFC 3161 timestamp objects", + title="Timestamp Schema", + ) diff --git a/rekor_types/_internal/rpm.py b/rekor_types/_internal/rpm.py new file mode 100644 index 0000000..0da265a --- /dev/null +++ b/rekor_types/_internal/rpm.py @@ -0,0 +1,37 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from pydantic import BaseModel, ConfigDict, Field, RootModel + + +class PublicKey(BaseModel): + """The PGP public key that can verify the RPM signature.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: str = Field( + ..., + description="Specifies the content of the public key inline within the document", + ) + + +class RpmV001Schema(BaseModel): + """Schema for RPM entries.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + public_key: PublicKey = Field( + ..., + alias="publicKey", + description="The PGP public key that can verify the RPM signature", + ) + + +class RpmSchema(RootModel[RpmV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: RpmV001Schema = Field(..., description="Schema for RPM objects", title="RPM Schema") diff --git a/rekor_types/_internal/tuf.py b/rekor_types/_internal/tuf.py new file mode 100644 index 0000000..9aad602 --- /dev/null +++ b/rekor_types/_internal/tuf.py @@ -0,0 +1,56 @@ +# generated by datamodel-codegen: + +from __future__ import annotations + +from typing import Any, Dict, Optional + +from pydantic import BaseModel, ConfigDict, Field, RootModel, StrictStr + + +class Metadata(BaseModel): + """TUF metadata.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: Dict[str, Any] = Field( + ..., + description="Specifies the metadata inline within the document", + ) + + +class Root(BaseModel): + """root metadata containing about the public keys used to sign the manifest.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + content: Dict[str, Any] = Field( + ..., + description="Specifies the metadata inline within the document", + ) + + +class TufV001Schema(BaseModel): + """Schema for TUF metadata entries.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + spec_version: Optional[StrictStr] = Field(default=None, description="TUF specification version") + metadata: Metadata = Field(..., description="TUF metadata") + root: Root = Field( + ..., + description="root metadata containing about the public keys used to sign the manifest", + ) + + +class TufSchema(RootModel[TufV001Schema]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: TufV001Schema = Field( + ..., + description="Schema for TUF metadata objects", + title="TUF Schema", + ) diff --git a/rekor_types/py.typed b/rekor_types/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/sigstore_rekor_types/__init__.py b/sigstore_rekor_types/__init__.py deleted file mode 100644 index 9ad0f0c..0000000 --- a/sigstore_rekor_types/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""The `sigstore_rekor_types` APIs.""" - -__version__ = "0.0.11" - -from ._internal import * # noqa: F403 diff --git a/sigstore_rekor_types/_internal.py b/sigstore_rekor_types/_internal.py deleted file mode 100644 index df4fad6..0000000 --- a/sigstore_rekor_types/_internal.py +++ /dev/null @@ -1,1094 +0,0 @@ -# generated by datamodel-codegen: - -from __future__ import annotations - -from enum import Enum -from typing import Any, Dict, List, Optional, Union - -from pydantic import AnyUrl, BaseModel, ConfigDict, EmailStr, Field, RootModel, StrictInt, StrictStr - - -class ProposedEntry(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - kind: StrictStr - - -class Format(str, Enum): - """Specifies the format of the signature.""" - - PGP = "pgp" - MINISIGN = "minisign" - X509 = "x509" - SSH = "ssh" - - -class PublicKey(BaseModel): - """The public key that can verify the signature.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: str = Field( - ..., - description="Specifies the content of the public key inline within the document", - ) - - -class Signature(BaseModel): - """Information about the detached signature associated with the entry.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - format: Format = Field(..., description="Specifies the format of the signature") - content: str = Field( - ..., - description="Specifies the content of the signature inline within the document", - ) - public_key: PublicKey = Field( - ..., - alias="publicKey", - description="The public key that can verify the signature", - ) - - -class RekordV001Schema(BaseModel): - """Schema for Rekord object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - signature: Signature = Field( - ..., - description="Information about the detached signature associated with the entry", - ) - - -class PublicKey1(BaseModel): - """The public key that can verify the signature; this can also be an X509 code signing certificate that contains the raw public key information.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: Optional[str] = Field( - default=None, - description=( - "Specifies the content of the public key or code signing certificate inline within the" - " document" - ), - ) - - -class Signature1(BaseModel): - """Information about the detached signature associated with the entry.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: Optional[str] = Field( - default=None, - description="Specifies the content of the signature inline within the document", - ) - public_key: Optional[PublicKey1] = Field( - default=None, - alias="publicKey", - description=( - "The public key that can verify the signature; this can also be an X509 code signing" - " certificate that contains the raw public key information" - ), - ) - - -class Algorithm(str, Enum): - """The hashing function used to compute the hash value.""" - - SHA256 = "sha256" - - -class Hash(BaseModel): - """Specifies the hash algorithm and value for the content.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field(..., description="The hash value for the content") - - -class Data(BaseModel): - """Information about the content associated with the entry.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - hash: Optional[Hash] = Field( - default=None, - description="Specifies the hash algorithm and value for the content", - ) - - -class HashedrekordV001Schema(BaseModel): - """Schema for Hashed Rekord object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - signature: Signature1 = Field( - ..., - description="Information about the detached signature associated with the entry", - ) - data: Data = Field(..., description="Information about the content associated with the entry") - - -class PublicKey2(BaseModel): - """The PGP public key that can verify the RPM signature.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: str = Field( - ..., - description="Specifies the content of the public key inline within the document", - ) - - -class RpmV001Schema(BaseModel): - """Schema for RPM entries.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - public_key: PublicKey2 = Field( - ..., - alias="publicKey", - description="The PGP public key that can verify the RPM signature", - ) - - -class Metadata(BaseModel): - """TUF metadata.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: Dict[str, Any] = Field( - ..., - description="Specifies the metadata inline within the document", - ) - - -class Root(BaseModel): - """root metadata containing about the public keys used to sign the manifest.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: Dict[str, Any] = Field( - ..., - description="Specifies the metadata inline within the document", - ) - - -class TufV001Schema(BaseModel): - """Schema for TUF metadata entries.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - spec_version: Optional[StrictStr] = Field(default=None, description="TUF specification version") - metadata: Metadata = Field(..., description="TUF metadata") - root: Root = Field( - ..., - description="root metadata containing about the public keys used to sign the manifest", - ) - - -class PublicKey3(BaseModel): - """The public key that can verify the package signature.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: str = Field( - ..., - description="Specifies the content of the public key inline within the document", - ) - - -class AlpineV001Schema(BaseModel): - """Schema for Alpine Package entries.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - public_key: PublicKey3 = Field( - ..., - alias="publicKey", - description="The public key that can verify the package signature", - ) - - -class Hash1(BaseModel): - """Specifies the hash algorithm and value for the chart.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field(..., description="The hash value for the chart") - - -class Chart(BaseModel): - """Information about the Helm chart associated with the entry.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - hash: Optional[Hash1] = Field( - default=None, - description="Specifies the hash algorithm and value for the chart", - ) - - -class HelmV001Schema(BaseModel): - """Schema for Helm object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - public_key: PublicKey3 = Field( - ..., - alias="publicKey", - description="The public key that can verify the package signature", - ) - chart: Chart = Field( - ..., - description="Information about the Helm chart associated with the entry", - ) - - -class Hash2(BaseModel): - """Specifies the hash algorithm and value encompassing the entire signed envelope; this is computed by the rekor server, client-provided values are ignored.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field(..., description="The hash value for the archive") - - -class PayloadHash(BaseModel): - """Specifies the hash algorithm and value covering the payload within the DSSE envelope; this is computed by the rekor server, client-provided values are ignored.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field(..., description="The hash value for the envelope's payload") - - -class Content(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - envelope: Optional[StrictStr] = Field(default=None, description="envelope") - hash: Optional[Hash2] = Field( - default=None, - description=( - "Specifies the hash algorithm and value encompassing the entire signed envelope; this" - " is computed by the rekor server, client-provided values are ignored" - ), - ) - payload_hash: Optional[PayloadHash] = Field( - default=None, - alias="payloadHash", - description=( - "Specifies the hash algorithm and value covering the payload within the DSSE envelope;" - " this is computed by the rekor server, client-provided values are ignored" - ), - ) - - -class IntotoV001Schema(BaseModel): - """Schema for intoto object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: Content - public_key: str = Field( - ..., - alias="publicKey", - description="The public key that can verify the signature", - ) - - -class Signature2(BaseModel): - """a signature of the envelope's payload along with the public key for the signature.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - keyid: Optional[StrictStr] = Field( - default=None, - description="optional id of the key used to create the signature", - ) - sig: str = Field(..., description="signature of the payload") - public_key: str = Field( - ..., - alias="publicKey", - description="public key that corresponds to this signature", - ) - - -class Envelope(BaseModel): - """dsse envelope.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - payload: Optional[str] = Field(default=None, description="payload of the envelope") - payload_type: StrictStr = Field( - ..., - alias="payloadType", - description="type describing the payload", - ) - signatures: List[Signature2] = Field( - ..., - description="collection of all signatures of the envelope's payload", - min_length=1, - ) - - -class Hash3(BaseModel): - """Specifies the hash algorithm and value encompassing the entire signed envelope.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field(..., description="The hash value for the archive") - - -class PayloadHash1(BaseModel): - """Specifies the hash algorithm and value covering the payload within the DSSE envelope.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field(..., description="The hash value of the payload") - - -class Content1(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - envelope: Envelope = Field(..., description="dsse envelope") - hash: Optional[Hash3] = Field( - default=None, - description=( - "Specifies the hash algorithm and value encompassing the entire signed envelope" - ), - ) - payload_hash: Optional[PayloadHash1] = Field( - default=None, - alias="payloadHash", - description=( - "Specifies the hash algorithm and value covering the payload within the DSSE envelope" - ), - ) - - -class IntotoV002Schema(BaseModel): - """Schema for intoto object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: Content1 - - -class PayloadHash2(Hash): - """Specifies the hash algorithm and value for the content.""" - - -class EnvelopeHash(BaseModel): - """Specifies the hash algorithm and value for the COSE envelope.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field(..., description="The hash value for the envelope") - - -class Data1(BaseModel): - """Information about the content associated with the entry.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - payload_hash: Optional[PayloadHash2] = Field( - default=None, - alias="payloadHash", - description="Specifies the hash algorithm and value for the content", - ) - envelope_hash: Optional[EnvelopeHash] = Field( - default=None, - alias="envelopeHash", - description="Specifies the hash algorithm and value for the COSE envelope", - ) - aad: Optional[str] = Field( - default=None, - description="Specifies the additional authenticated data required to verify the signature", - ) - - -class CoseV001Schema(BaseModel): - """Schema for cose object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - message: Optional[str] = Field(default=None, description="The COSE Sign1 Message") - public_key: str = Field( - ..., - alias="publicKey", - description="The public key that can verify the signature", - ) - data: Data1 = Field(..., description="Information about the content associated with the entry") - - -class PublicKey5(BaseModel): - """The X509 certificate containing the public key JAR which verifies the signature of the JAR.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: str = Field( - ..., - description=( - "Specifies the content of the X509 certificate containing the public key used to verify" - " the signature" - ), - ) - - -class Signature3(BaseModel): - """Information about the included signature in the JAR file.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: str = Field( - ..., - description="Specifies the PKCS7 signature embedded within the JAR file ", - ) - public_key: PublicKey5 = Field( - ..., - alias="publicKey", - description=( - "The X509 certificate containing the public key JAR which verifies the signature of" - " the JAR" - ), - ) - - -class JarV001Schema(BaseModel): - """Schema for JAR entries.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - signature: Optional[Signature3] = Field( - default=None, - description="Information about the included signature in the JAR file", - ) - - -class Tsr(BaseModel): - """Information about the tsr file associated with the entry.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - content: str = Field( - ..., - description="Specifies the tsr file content inline within the document", - ) - - -class Rfc3161V001Schema(BaseModel): - """Schema for RFC3161 entries.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - tsr: Tsr = Field(..., description="Information about the tsr file associated with the entry") - - -class ProposedContent(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - envelope: StrictStr = Field( - ..., - description="DSSE envelope specified as a stringified JSON object", - ) - verifiers: List[str] = Field( - ..., - description=( - "collection of all verification material (e.g. public keys or certificates) used to" - " verify signatures over envelope's payload, specified as base64-encoded strings" - ), - min_length=1, - ) - - -class Signature4(BaseModel): - """a signature of the envelope's payload along with the verification material for the signature.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - signature: StrictStr = Field(..., description="base64 encoded signature of the payload") - verifier: str = Field( - ..., - description=( - "verification material that was used to verify the corresponding signature, specified" - " as a base64 encoded string" - ), - ) - - -class EnvelopeHash1(BaseModel): - """Specifies the hash algorithm and value encompassing the entire envelope sent to Rekor.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field( - ..., - description="The value of the computed digest over the entire envelope", - ) - - -class PayloadHash3(BaseModel): - """Specifies the hash algorithm and value covering the payload within the DSSE envelope.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - algorithm: Algorithm = Field( - ..., - description="The hashing function used to compute the hash value", - ) - value: StrictStr = Field( - ..., - description="The value of the computed digest over the payload within the envelope", - ) - - -class DsseV001Schema(BaseModel): - """Schema for DSSE envelopes.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - proposed_content: Optional[ProposedContent] = Field(default=None, alias="proposedContent") - signatures: Optional[List[Signature4]] = Field( - default=None, - description=( - "extracted collection of all signatures of the envelope's payload; elements will be" - " sorted by lexicographical order of the base64 encoded signature strings" - ), - min_length=1, - ) - envelope_hash: Optional[EnvelopeHash1] = Field( - default=None, - alias="envelopeHash", - description=( - "Specifies the hash algorithm and value encompassing the entire envelope sent to Rekor" - ), - ) - payload_hash: Optional[PayloadHash3] = Field( - default=None, - alias="payloadHash", - description=( - "Specifies the hash algorithm and value covering the payload within the DSSE envelope" - ), - ) - - -class Attestation(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - data: Optional[Dict[str, Any]] = None - - -class Format1(str, Enum): - PGP = "pgp" - X509 = "x509" - MINISIGN = "minisign" - SSH = "ssh" - TUF = "tuf" - - -class PublicKey6(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - format: Format1 - content: Optional[str] = Field( - default=None, - pattern="^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", - ) - url: Optional[AnyUrl] = None - - -class Operator(str, Enum): - AND_ = "and" - OR_ = "or" - - -class SearchIndex(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - email: Optional[EmailStr] = None - public_key: Optional[PublicKey6] = Field(default=None, alias="publicKey") - hash: Optional[StrictStr] = None - operator: Optional[Operator] = None - - -class EntryUuiD(RootModel[StrictStr]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: StrictStr - - -class LogIndex(RootModel[StrictInt]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: StrictInt - - -class SearchLogQuery(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - entry_uui_ds: Optional[List[EntryUuiD]] = Field( - default=None, - alias="entryUUIDs", - max_length=10, - min_length=1, - ) - log_indexes: Optional[List[LogIndex]] = Field( - default=None, - alias="logIndexes", - max_length=10, - min_length=1, - ) - entries: Optional[List[ProposedEntry]] = Field(default=None, max_length=10, min_length=1) - - -class InactiveShardLogInfo(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - root_hash: StrictStr = Field( - ..., - alias="rootHash", - description="The current hash value stored at the root of the merkle tree", - ) - tree_size: StrictInt = Field( - ..., - alias="treeSize", - description="The current number of nodes in the merkle tree", - ) - signed_tree_head: StrictStr = Field( - ..., - alias="signedTreeHead", - description="The current signed tree head", - ) - tree_id: StrictStr = Field(..., alias="treeID", description="The current treeID") - - -class Hash4(RootModel[StrictStr]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: StrictStr = Field(..., description="SHA256 hash value expressed in hexadecimal format") - - -class ConsistencyProof(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - root_hash: StrictStr = Field( - ..., - alias="rootHash", - description=( - "The hash value stored at the root of the merkle tree at the time the proof was" - " generated" - ), - ) - hashes: List[Hash4] - - -class InclusionProof(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - log_index: StrictInt = Field( - ..., - alias="logIndex", - description="The index of the entry in the transparency log", - ) - root_hash: StrictStr = Field( - ..., - alias="rootHash", - description=( - "The hash value stored at the root of the merkle tree at the time the proof was" - " generated" - ), - ) - tree_size: StrictInt = Field( - ..., - alias="treeSize", - description="The size of the merkle tree at the time the inclusion proof was generated", - ) - hashes: List[Hash4] = Field( - ..., - description=( - "A list of hashes required to compute the inclusion proof, sorted in order from leaf to" - " root" - ), - ) - checkpoint: StrictStr = Field( - ..., - description="The checkpoint (signed tree head) that the inclusion proof is based on", - ) - - -class Error(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - code: Optional[StrictInt] = None - message: Optional[StrictStr] = None - - -class RekordSchema(RootModel[RekordV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: RekordV001Schema = Field( - ..., - description="Schema for Rekord objects", - title="Rekor Schema", - ) - - -class HashedrekordSchema(RootModel[HashedrekordV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: HashedrekordV001Schema = Field( - ..., - description="Schema for Rekord objects", - title="Rekor Schema", - ) - - -class RpmSchema(RootModel[RpmV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: RpmV001Schema = Field(..., description="Schema for RPM objects", title="RPM Schema") - - -class TufSchema(RootModel[TufV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: TufV001Schema = Field( - ..., - description="Schema for TUF metadata objects", - title="TUF Schema", - ) - - -class AlpineSchema(RootModel[AlpineV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: AlpineV001Schema = Field( - ..., - description="Schema for Alpine package objects", - title="Alpine Package Schema", - ) - - -class HelmSchema(RootModel[HelmV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: HelmV001Schema = Field(..., description="Schema for Helm objects", title="Helm Schema") - - -class IntotoSchema(RootModel[Union[IntotoV001Schema, IntotoV002Schema]]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: Union[IntotoV001Schema, IntotoV002Schema] = Field( - ..., - description="Intoto for Rekord objects", - title="Intoto Schema", - ) - - -class CoseSchema(RootModel[CoseV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: CoseV001Schema = Field(..., description="COSE for Rekord objects", title="COSE Schema") - - -class JarSchema(RootModel[JarV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: JarV001Schema = Field(..., description="Schema for JAR objects", title="JAR Schema") - - -class Rfc3161Schema(RootModel[Rfc3161V001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: Rfc3161V001Schema = Field( - ..., - description="Schema for RFC 3161 timestamp objects", - title="Timestamp Schema", - ) - - -class DsseSchema(RootModel[DsseV001Schema]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: DsseV001Schema = Field( - ..., - description="log entry schema for dsse envelopes", - title="DSSE Schema", - ) - - -class Verification(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - inclusion_proof: Optional[InclusionProof] = Field(default=None, alias="inclusionProof") - signed_entry_timestamp: Optional[str] = Field( - default=None, - alias="signedEntryTimestamp", - description="Signature over the logID, logIndex, body and integratedTime.", - pattern="^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", - ) - - -class LogEntry1(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - log_id: StrictStr = Field( - ..., - alias="logID", - description=( - "This is the SHA256 hash of the DER-encoded public key for the log at the time the" - " entry was included in the log" - ), - ) - log_index: StrictInt = Field(..., alias="logIndex") - body: Dict[str, Any] - integrated_time: StrictInt = Field( - ..., - alias="integratedTime", - description="The time the entry was added to the log as a Unix timestamp in seconds", - ) - attestation: Optional[Attestation] = None - verification: Optional[Verification] = None - - -class LogEntry(RootModel[Optional[Dict[str, LogEntry1]]]): - model_config = ConfigDict( - populate_by_name=True, - ) - root: Optional[Dict[str, LogEntry1]] = None - - -class LogInfo(BaseModel): - model_config = ConfigDict( - populate_by_name=True, - ) - root_hash: StrictStr = Field( - ..., - alias="rootHash", - description="The current hash value stored at the root of the merkle tree", - ) - tree_size: StrictInt = Field( - ..., - alias="treeSize", - description="The current number of nodes in the merkle tree", - ) - signed_tree_head: StrictStr = Field( - ..., - alias="signedTreeHead", - description="The current signed tree head", - ) - tree_id: StrictStr = Field(..., alias="treeID", description="The current treeID") - inactive_shards: Optional[List[InactiveShardLogInfo]] = Field( - default=None, - alias="inactiveShards", - ) - - -class Rekord(ProposedEntry): - """Rekord object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: RekordSchema - - -class Hashedrekord(ProposedEntry): - """Hashed Rekord object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: HashedrekordSchema - - -class Rpm(ProposedEntry): - """RPM package.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: RpmSchema - - -class Tuf(ProposedEntry): - """TUF metadata.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: TufSchema - - -class Alpine(ProposedEntry): - """Alpine package.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: AlpineSchema - - -class Helm(ProposedEntry): - """Helm chart.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: HelmSchema - - -class Intoto(ProposedEntry): - """Intoto object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: IntotoSchema - - -class Cose(ProposedEntry): - """COSE object.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: CoseSchema - - -class Jar(ProposedEntry): - """Java Archive (JAR).""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: JarSchema - - -class Rfc3161(ProposedEntry): - """RFC3161 Timestamp.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: Rfc3161Schema - - -class Dsse(ProposedEntry): - """DSSE envelope.""" - - model_config = ConfigDict( - populate_by_name=True, - ) - api_version: StrictStr = Field(..., alias="apiVersion") - spec: DsseSchema