sigstore

    Pure, portable verification of Sigstore bundles and GitHub artifact attestations

    sigstore
    attestation
    supply-chain
    verification
    Download zip
    Author
    Version
    0.10.0
    License
    Apache-2.0
    Last updated
    6 hours ago
    Downloads
    5

    #moonrockz/sigstore

    Verify Sigstore bundles and GitHub artifact attestations in MoonBit, on the wasm, wasm-gc, js and native targets.

    actions/attest signs a release in GitHub Actions and stores a Sigstore bundle. This module checks that bundle offline. It is a pure function of five inputs: the artifact digest, the bundle, a trusted root, an identity policy and the time "now". It does no network, filesystem or clock I/O, so a program can verify a bundle at install time and verify it again later from a lock file, with the same result.

    The verifier does these checks, in this order, with the rules of sigstore-go:

    StepCheck
    Transparency logThe Rekor v1 entry is from a log of the trusted root. Its signed entry timestamp (SET) verifies, and its integrated time is in the log's validity and not after "now"
    InclusionThe RFC 6962 inclusion proof gives the root hash of a checkpoint that the log key signed
    CertificateThe Fulcio leaf chains to a certificate authority of the trusted root at the integrated time, for code signing
    Certificate timestampAn embedded SCT from a trusted CT log verifies
    Log bodyThe logged signature, certificate and payload hash are those of the bundle
    ContentThe DSSE signature (or message signature) verifies with the leaf key
    ArtifactA subject of the in-toto statement (or the message digest) is the artifact digest
    PolicyThe certificate has the issuer, identity and GitHub claims of a policy

    #Verify a GitHub release

    Parse each input once at the boundary, then call verify. The caller reads the clock and gives "now". TrustedRoot::public_good() is a pinned copy of the Sigstore public-good root, so it needs no I/O:

    ///|
    test "verify the attestation of a GitHub release" {
    let bundle = @sigstore.Bundle::parse(
    github_fixture("cli-2.50.0.sigstore.json"),
    )
    let digest = @sigstore.ArtifactDigest::parse(
    "sha256:7f9795b3ce99351a1bfc6ea3b09b7363cb1eccca19978a046bcb477839efab82",
    )
    let policy = @sigstore.Policy::github_workflow(
    @sigstore.GitHubRepository::parse("cli/cli"),
    workflow=@sigstore.WorkflowPath::parse(".github/workflows/deployment.yml"),
    )
    let now = @sigstore.Instant::from_unix_seconds(1793000000L)
    match
    @sigstore.verify(
    bundle,
    digest,
    @sigstore.TrustedRoot::public_good(),
    policy,
    now~,
    ) {
    Verified(facts) => {
    assert_eq(facts.integrated_time.unix_seconds(), 1716998983L)
    assert_eq(facts.claims.source_repository_ref, Some("refs/heads/trunk"))
    guard facts.statement is Some(statement) else { fail("no statement") }
    assert_eq(statement.predicate_type, @sigstore.PredicateType::slsa_provenance_v1())
    }
    Rejected(reason) => fail(reason.message())
    }
    }

    github_fixture reads the test data of this module. A program gets the bundle from the GitHub attestations API or from gh attestation download.

    #Policies

    A Policy names the publisher that must have signed the bundle. It is made only from parsed values, each with a smart constructor and a typed IdentityError:

    TypeExampleRules
    Issuerhttps://token.actions.githubusercontent.comAn https URL with a host
    SubjectNamethe certificate SANNot empty, no spaces
    GitHubRepositoryfinos/morphir-rustowner/repo with GitHub's name rules
    GitHubOwnerfinos1 to 39 letters, digits and -
    WorkflowPath.github/workflows/release.ymlA .yml or .yaml file directly in .github/workflows/
    GitRefrefs/tags/v1.0.0refs/ and a name
    GitHubId513894754Decimal digits, no leading zero
    PredicateTypehttps://slsa.dev/provenance/v1An absolute URI

    Policy::github_workflow requires the signer workflow, the same source repository, a GitHub-hosted runner and an in-toto statement of SLSA provenance v1, as gh attestation verify does. So an SBOM attestation that the same workflow made does not pass as provenance; give predicate_type= to accept another type. Add claims to pin more. A deleted and recreated repository keeps its name but gets a new ID, so a trust record should pin the IDs:

    ///|
    test "a policy that pins the repository and owner IDs" {
    let repository = @sigstore.GitHubRepository::parse("finos/morphir-rust")
    let policy = @sigstore.Policy::github_workflow(
    repository,
    workflow=@sigstore.WorkflowPath::parse(
    ".github/workflows/release-provider-snapshot.yml",
    ),
    )
    .repository_id(@sigstore.GitHubId::parse("513894754"))
    .owner_id(@sigstore.GitHubId::parse("35377814"))
    let verdict = @sigstore.verify(
    @sigstore.Bundle::parse(
    github_fixture("morphir-rust-provider-snapshot-0.2.0.sigstore.json"),
    ),
    @sigstore.ArtifactDigest::parse(
    "sha256:03d190b8ef97d354f9aca6854542979c36ce5f77c68a3d80de28ac1a77c432bd",
    ),
    @sigstore.TrustedRoot::public_good(),
    policy,
    now=@sigstore.Instant::from_unix_seconds(1793000000L),
    )
    assert_true(verdict is Verified(_))
    }

    Owner and repository names compare without regard to case, as on GitHub. Workflow paths and refs compare exactly. Give alternatives= to accept one of several publishers; the verdict names the policy that matched.

    #Read a rejection

    A Verdict is Verified(VerifiedBundle) or Rejected(Rejection). A rejection is Invalid(Failure), with one case for each check, or Unsupported(Feature) for a valid bundle that this version cannot check yet. So a program can tell "this bundle is bad" from "update the tool":

    ///|
    test "a policy for another repository rejects the bundle" {
    let verdict = @sigstore.verify(
    @sigstore.Bundle::parse(github_fixture("cli-2.50.0.sigstore.json")),
    @sigstore.ArtifactDigest::parse(
    "sha256:7f9795b3ce99351a1bfc6ea3b09b7363cb1eccca19978a046bcb477839efab82",
    ),
    @sigstore.TrustedRoot::public_good(),
    @sigstore.Policy::github_workflow(
    @sigstore.GitHubRepository::parse("cli/go-gh"),
    workflow=@sigstore.WorkflowPath::parse(".github/workflows/deployment.yml"),
    ),
    now=@sigstore.Instant::from_unix_seconds(1793000000L),
    )
    guard verdict is Rejected(Invalid(Policy([IdentityMismatch(..)]))) else {
    fail("expected an identity mismatch")
    }
    }

    #Scope

    Supported: bundle media types v0.1, v0.2 and v0.3; DSSE envelopes with in-toto statements, and message signatures; Fulcio certificates; Rekor v1 entries of kind dsse and hashedrekord 0.0.1; ECDSA P-256 and P-384. This covers the attestations that actions/attest makes for public repositories.

    Not supported yet, each with an Unsupported reason: Rekor v2 entries, RFC 3161 timestamps (the only time source of attestations from private repositories and of GitHub immutable releases), managed-key bundles, and Ed25519 or RSA keys. A Sigstore TUF client that refreshes the trusted root is a later change; give TrustedRoot::parse a newer root when the public-good keys change.

    #Cryptography

    All cryptography is pure MoonBit, so each target runs the same code with no host crypto. SHA-2 and ECDSA come from moonbitstack/mooncrypt at an exact version. The module's own code reads DER strictly, checks public keys (uncompressed, coordinates below the field prime, on the curve) and runs the Wycheproof ECDSA vectors on every target. A verification makes six signature checks; on an Apple Silicon Mac it takes about 16 ms on native and 41 ms on wasm-gc (mise run bench:sigstore).

    #Test data

    testdata/ holds the sources of the tests, with their licenses: 70 sigstore-conformance cases, the Wycheproof ECDSA vectors, three real GitHub attestations and the pinned public-good root. See testdata/README.md. mise run build:sigstore-assets writes them as MoonBit constants, because wasm tests cannot read files.

    BundleError

    pub suberror BundleError {
    UnsupportedBundleMediaType(String)
    InvalidBundle(field~ : String, rule~ : String)
    } derive(
    Debug
    )

    A bundle text that cannot be read.

    BundleError::message

    fn BundleError::message(self : BundleError) -> String

    Text for people that names the field and the rule.

    DigestError

    pub suberror DigestError {
    InvalidDigest(text~ : String, rule~ : DigestRule)
    } derive(
    Debug
    )

    A text that is not a valid artifact digest.

    DigestError::message

    fn DigestError::message(self : DigestError) -> String

    Text for people that names the input and the rule.

    IdentityError

    pub suberror IdentityError {
    InvalidIdentity(kind~ : IdentityKind, text~ : String, rule~ : String)
    } derive(
    Debug
    )

    A text that is not a valid identity value.

    IdentityError::message

    fn IdentityError::message(self : IdentityError) -> String

    Text for people that names the kind of value, the input and the rule.

    TrustedRootError

    pub suberror TrustedRootError {
    UnsupportedTrustedRootMediaType(String)
    InvalidTrustedRoot(field~ : String, rule~ : String)
    } derive(
    Debug
    )

    A trusted root text that cannot be read.

    TrustedRootError::message

    fn TrustedRootError::message(self : TrustedRootError) -> String

    Text for people that names the field and the rule.

    ArtifactDigest

    pub struct ArtifactDigest {
    // private fields
    } derive(Eq,
    Debug
    )

    The SHA-256 digest of an artifact.

    ArtifactDigest::equal

    ArtifactDigest::not_equal

    fn ArtifactDigest::not_equal(x : ArtifactDigest, y : ArtifactDigest) -> Bool

    ArtifactDigest::of_bytes

    fn ArtifactDigest::of_bytes(artifact : BytesView) -> ArtifactDigest

    The digest of the artifact bytes.

    ArtifactDigest::output

    fn ArtifactDigest::output(self : ArtifactDigest, logger : &Logger) -> Unit

    ArtifactDigest::parse

    fn ArtifactDigest::parse(text : String) -> ArtifactDigest raise DigestError

    Parse a digest such as sha256:03d190…32bd. Hex digits can be in either case.

    ArtifactDigest::to_bytes

    fn ArtifactDigest::to_bytes(self : ArtifactDigest) -> Bytes

    The 32 digest bytes.

    ArtifactDigest::to_string

    fn ArtifactDigest::to_string(self : ArtifactDigest) -> String

    Bundle

    pub struct Bundle {
    // private fields
    }

    A parsed Sigstore bundle. Only Bundle::parse makes it, and it holds the values that verification checks.

    Bundle::parse

    fn Bundle::parse(text : StringView) -> Bundle raise BundleError

    Read a bundle from its protobuf JSON text, with the rules of sigstore-go.

    Bundle::version

    fn Bundle::version(self : Bundle) -> BundleVersion

    The format version of the bundle.

    BundleVersion

    pub enum BundleVersion {
    V0_1
    V0_2
    V0_3
    } derive(Compare, Eq,
    Debug
    )

    The bundle format version.

    BundleVersion::compare

    BundleVersion::equal

    BundleVersion::not_equal

    fn BundleVersion::not_equal(x : BundleVersion, y : BundleVersion) -> Bool

    BundleVersion::op_ge

    fn BundleVersion::op_ge(x : BundleVersion, y : BundleVersion) -> Bool

    BundleVersion::op_gt

    fn BundleVersion::op_gt(x : BundleVersion, y : BundleVersion) -> Bool

    BundleVersion::op_le

    fn BundleVersion::op_le(x : BundleVersion, y : BundleVersion) -> Bool

    BundleVersion::op_lt

    fn BundleVersion::op_lt(x : BundleVersion, y : BundleVersion) -> Bool

    CertificateClaims

    pub struct CertificateClaims {
    issuer : String?
    subject_names : Array[String]
    build_signer_uri : String?
    build_signer_digest : String?
    runner_environment : String?
    source_repository_uri : String?
    source_repository_digest : String?
    source_repository_ref : String?
    source_repository_identifier : String?
    source_repository_owner_uri : String?
    source_repository_owner_identifier : String?
    build_config_uri : String?
    build_config_digest : String?
    build_trigger : String?
    run_invocation_uri : String?
    source_repository_visibility : String?
    } derive(Eq,
    Debug
    )

    The identity claims of a Fulcio certificate. Each value is the text of its extension (1.3.6.1.4.1.57264.1.*), or None when the extension is absent.

    CertificateClaims::equal

    CertificateClaims::not_equal

    fn CertificateClaims::not_equal(x : CertificateClaims, y : CertificateClaims) -> Bool

    CertificateProblem

    pub enum CertificateProblem {
    Unreadable(String)
    NotForCodeSigning
    NoDigitalSignature
    UnknownCriticalExtension(String)
    LeafIsAuthority
    } derive(Eq,
    Debug
    )

    Why the leaf certificate cannot be used.

    CertificateProblem::equal

    CertificateProblem::message

    fn CertificateProblem::message(self : CertificateProblem) -> String

    Text for people that describes the problem.

    CertificateProblem::not_equal

    Claim

    pub enum Claim {
    SourceRepository
    SourceOwner
    RepositoryId
    OwnerId
    SourceRef
    } derive(Eq,
    Debug
    )

    A certificate claim that a policy can require.

    Claim::equal

    fn Claim::equal(Claim, Claim) -> Bool

    Claim::not_equal

    fn Claim::not_equal(x : Claim, y : Claim) -> Bool

    Claim::to_repr

    DigestRule

    pub enum DigestRule {
    MissingAlgorithm
    UnsupportedAlgorithm(String)
    NotHex
    WrongLength(Int)
    } derive(Eq,
    Debug
    )

    The rule of an artifact digest that a text breaks.

    DigestRule::equal

    fn DigestRule::equal(DigestRule, DigestRule) -> Bool

    DigestRule::not_equal

    fn DigestRule::not_equal(x : DigestRule, y : DigestRule) -> Bool

    Failure

    pub enum Failure {
    BundleShape(String)
    TransparencyLog(String)
    TransparencyLogTime(integrated_time~ : Instant, now~ : Instant)
    TransparencyLogBody(String)
    InclusionProof(String)
    Checkpoint(String)
    Certificate(CertificateProblem)
    CertificateValidity(not_before~ : Instant, not_after~ : Instant, time~ : Instant)
    CertificateChain(String)
    CertificateTimestamp(String)
    PayloadType(String)
    ContentSignature
    Statement(String)
    ArtifactDigestMismatch(ArtifactDigest)
    Policy(Array[PolicyMismatch])
    } derive(Eq,
    Debug
    )

    A check of the verification pipeline that failed, with the detail that a user needs.

    Failure::equal

    fn Failure::equal(Failure, Failure) -> Bool

    Failure::not_equal

    fn Failure::not_equal(x : Failure, y : Failure) -> Bool

    Failure::to_repr

    Feature

    pub enum Feature {
    PublicKeyMaterial
    TimestampAuthority
    RekorV2
    EntryKind(kind~ : String, version~ : String)
    KeyType(String)
    DigestAlgorithm(String)
    } derive(Eq,
    Debug
    )

    A valid bundle feature that this verifier does not support yet.

    Feature::equal

    fn Feature::equal(Feature, Feature) -> Bool

    Feature::not_equal

    fn Feature::not_equal(x : Feature, y : Feature) -> Bool

    Feature::to_repr

    GitHubId

    pub struct GitHubId {
    // private fields
    } derive(Eq,
    Debug
    )

    A numeric GitHub repository or account ID, for example 513894754. A deleted and recreated repository keeps its name and gets a new ID.
    impl Show for GitHubId

    GitHubId::equal

    fn GitHubId::equal(GitHubId, GitHubId) -> Bool

    GitHubId::not_equal

    fn GitHubId::not_equal(x : GitHubId, y : GitHubId) -> Bool

    GitHubId::output

    fn GitHubId::output(self : GitHubId, logger : &Logger) -> Unit

    GitHubId::parse

    fn GitHubId::parse(text : String) -> GitHubId raise IdentityError

    Parse an ID: 1 to 20 decimal digits without a leading zero.

    GitHubId::to_repr

    GitHubId::to_string

    fn GitHubId::to_string(self : GitHubId) -> String

    GitHubOwner

    pub struct GitHubOwner {
    // private fields
    } derive(
    Debug
    )

    A GitHub account name, for example finos.
    impl Eq for GitHubOwner
    impl Show for GitHubOwner

    GitHubOwner::equal

    fn GitHubOwner::equal(self : GitHubOwner, other : GitHubOwner) -> Bool

    GitHubOwner::not_equal

    fn GitHubOwner::not_equal(x : GitHubOwner, y : GitHubOwner) -> Bool

    GitHubOwner::output

    fn GitHubOwner::output(self : GitHubOwner, logger : &Logger) -> Unit

    GitHubOwner::parse

    fn GitHubOwner::parse(text : String) -> GitHubOwner raise IdentityError

    Parse a GitHub account name.

    GitHubOwner::to_string

    fn GitHubOwner::to_string(self : GitHubOwner) -> String

    GitHubRepository

    pub struct GitHubRepository {
    // private fields
    } derive(
    Debug
    )

    A GitHub repository, for example finos/morphir-rust.

    GitHubRepository::equal

    fn GitHubRepository::equal(self : GitHubRepository, other : GitHubRepository) -> Bool

    GitHubRepository::not_equal

    fn GitHubRepository::not_equal(x : GitHubRepository, y : GitHubRepository) -> Bool

    GitHubRepository::output

    fn GitHubRepository::output(self : GitHubRepository, logger : &Logger) -> Unit

    GitHubRepository::owner

    The owner of the repository.

    GitHubRepository::parse

    fn GitHubRepository::parse(text : String) -> GitHubRepository raise IdentityError

    Parse a repository in the form owner/repo.

    GitHubRepository::to_string

    fn GitHubRepository::to_string(self : GitHubRepository) -> String

    GitHubRepository::url

    fn GitHubRepository::url(self : GitHubRepository) -> String

    The repository URL, https://github.com/owner/repo.

    GitRef

    pub struct GitRef {
    // private fields
    } derive(Eq,
    Debug
    )

    A fully qualified Git ref, for example refs/tags/v1.0.0.
    impl Show for GitRef

    GitRef::equal

    fn GitRef::equal(GitRef, GitRef) -> Bool

    GitRef::not_equal

    fn GitRef::not_equal(x : GitRef, y : GitRef) -> Bool

    GitRef::output

    fn GitRef::output(self : GitRef, logger : &Logger) -> Unit

    GitRef::parse

    fn GitRef::parse(text : String) -> GitRef raise IdentityError

    Parse a Git ref: refs/ and a name with no spaces and no ...

    GitRef::to_repr

    GitRef::to_string

    fn GitRef::to_string(self : GitRef) -> String

    IdentityKind

    pub enum IdentityKind {
    IssuerUrl
    SubjectName
    Repository
    Owner
    Workflow
    Ref
    NumericId
    Predicate
    } derive(Eq,
    Debug
    )

    The kind of identity value that a text failed to parse as.

    IdentityKind::equal

    IdentityKind::not_equal

    fn IdentityKind::not_equal(x : IdentityKind, y : IdentityKind) -> Bool

    Instant

    pub struct Instant {
    // private fields
    } derive(Compare, Eq,
    Debug
    )

    A point in time, UTC, with nanosecond precision. The caller reads the clock and gives "now" as an Instant; the library never reads a clock.
    impl Show for Instant

    Instant::compare

    fn Instant::compare(Instant, Instant) -> Int

    Instant::equal

    fn Instant::equal(Instant, Instant) -> Bool

    Instant::from_unix_seconds

    fn Instant::from_unix_seconds(seconds : Int64) -> Instant

    The instant seconds after 1970-01-01T00:00:00Z. Every Int64 is valid.

    Instant::not_equal

    fn Instant::not_equal(x : Instant, y : Instant) -> Bool

    Instant::op_ge

    fn Instant::op_ge(x : Instant, y : Instant) -> Bool

    Instant::op_gt

    fn Instant::op_gt(x : Instant, y : Instant) -> Bool

    Instant::op_le

    fn Instant::op_le(x : Instant, y : Instant) -> Bool

    Instant::op_lt

    fn Instant::op_lt(x : Instant, y : Instant) -> Bool

    Instant::output

    fn Instant::output(self : Instant, logger : &Logger) -> Unit

    Instant::to_repr

    Instant::to_string

    fn Instant::to_string(self : Instant) -> String

    Instant::unix_seconds

    fn Instant::unix_seconds(self : Instant) -> Int64

    Whole seconds since 1970-01-01T00:00:00Z, rounded down.

    Issuer

    pub struct Issuer {
    // private fields
    } derive(Eq,
    Debug
    )

    An OIDC issuer URL, for example https://token.actions.githubusercontent.com.
    impl Show for Issuer

    Issuer::equal

    fn Issuer::equal(Issuer, Issuer) -> Bool

    Issuer::github_actions

    fn Issuer::github_actions() -> Issuer

    The GitHub Actions OIDC issuer.

    Issuer::not_equal

    fn Issuer::not_equal(x : Issuer, y : Issuer) -> Bool

    Issuer::output

    fn Issuer::output(self : Issuer, logger : &Logger) -> Unit

    Issuer::parse

    fn Issuer::parse(text : String) -> Issuer raise IdentityError

    Parse an issuer: an https URL with a host and no spaces.

    Issuer::to_repr

    Issuer::to_string

    fn Issuer::to_string(self : Issuer) -> String

    KeyStatus

    pub enum KeyStatus {
    Supported
    Unsupported(String)
    } derive(Eq,
    Debug
    )

    Whether the verifier can use a key of the trusted root.

    KeyStatus::equal

    fn KeyStatus::equal(KeyStatus, KeyStatus) -> Bool

    KeyStatus::not_equal

    fn KeyStatus::not_equal(x : KeyStatus, y : KeyStatus) -> Bool

    Policy

    pub struct Policy {
    // private fields
    }

    A publisher identity that a signing certificate must have. A policy is an immutable value; each method returns a new policy with one more claim.

    Policy::github_workflow

    fn Policy::github_workflow(repository : GitHubRepository, workflow~ : WorkflowPath, git_ref? : GitRef, hosted_runner_only? : Bool, predicate_type? : PredicateType) -> Policy

    The usual policy for a GitHub release: the workflow workflow of repository signed it, from the source of that repository, on a GitHub-hosted runner unless hosted_runner_only is false, and the statement has the predicate type predicate_type (by default SLSA provenance v1, as gh attestation verify requires). So an SBOM attestation of the same workflow does not pass as provenance.

    Policy::hosted_runners_only

    fn Policy::hosted_runners_only(self : Policy) -> Policy

    Also require the runner environment github-hosted (.1.11).

    Policy::owner_id

    fn Policy::owner_id(self : Policy, id : GitHubId) -> Policy

    Also require the source repository owner ID claim (.1.17).

    Policy::predicate_type

    fn Policy::predicate_type(self : Policy, predicate_type : PredicateType) -> Policy

    Also require an in-toto statement with the predicate type predicate_type. A message-signature bundle has no statement, so it does not match.

    Policy::repository_id

    fn Policy::repository_id(self : Policy, id : GitHubId) -> Policy

    Also require the source repository ID claim (.1.15).

    Policy::signer_workflow

    fn Policy::signer_workflow(repository : GitHubRepository, path : WorkflowPath, git_ref? : GitRef, issuer? : Issuer) -> Policy

    A policy that requires the signer workflow path in repository, at git_ref when it is given, else at any ref. It matches the SAN https://github.com/<owner>/<repo>/<path>@<git_ref>.

    Policy::source_owner

    fn Policy::source_owner(self : Policy, owner : GitHubOwner) -> Policy

    Also require the source repository owner claim (.1.16).

    Policy::source_ref

    fn Policy::source_ref(self : Policy, git_ref : GitRef) -> Policy

    Also require the source ref claim (.1.14).

    Policy::source_repository

    fn Policy::source_repository(self : Policy, repository : GitHubRepository) -> Policy

    Also require the source repository claim (.1.12).

    Policy::subject_name

    fn Policy::subject_name(name : SubjectName, issuer? : Issuer) -> Policy

    A policy that requires the exact subject alternative name name.

    PolicyMismatch

    pub enum PolicyMismatch {
    IssuerMismatch(expected~ : String, actual~ : String?)
    IdentityMismatch(expected~ : String, actual~ : Array[String])
    ClaimMismatch(claim~ : Claim, expected~ : String, actual~ : String?)
    RunnerEnvironment(actual~ : String?)
    PredicateTypeMismatch(expected~ : PredicateType, actual~ : PredicateType?)
    } derive(Eq,
    Debug
    )

    Why a certificate does not match one policy.

    PolicyMismatch::equal

    PolicyMismatch::message

    fn PolicyMismatch::message(self : PolicyMismatch) -> String

    Text for people that names the expected and the actual value.

    PolicyMismatch::not_equal

    fn PolicyMismatch::not_equal(x : PolicyMismatch, y : PolicyMismatch) -> Bool

    PredicateType

    pub struct PredicateType {
    // private fields
    } derive(Eq,
    Debug
    )

    The predicate type of an in-toto statement, for example https://slsa.dev/provenance/v1. It tells what the attestation claims.

    PredicateType::equal

    PredicateType::not_equal

    fn PredicateType::not_equal(x : PredicateType, y : PredicateType) -> Bool

    PredicateType::output

    fn PredicateType::output(self : PredicateType, logger : &Logger) -> Unit

    PredicateType::parse

    fn PredicateType::parse(text : String) -> PredicateType raise IdentityError

    Parse a predicate type: an absolute URI (a scheme of ASCII letters, : and a non-empty rest) with no spaces.

    PredicateType::slsa_provenance_v1

    fn PredicateType::slsa_provenance_v1() -> PredicateType

    SLSA provenance v1, the predicate type of actions/attest build provenance.

    PredicateType::to_string

    fn PredicateType::to_string(self : PredicateType) -> String

    Rejection

    pub enum Rejection {
    Unsupported(Feature)
    Invalid(Failure)
    } derive(Eq,
    Debug
    )

    Why a bundle was not verified: a valid feature that is not supported, or a check that failed.

    Rejection::equal

    fn Rejection::equal(Rejection, Rejection) -> Bool

    Rejection::message

    fn Rejection::message(self : Rejection) -> String

    Text for people that names the feature or the check, with its detail.

    Rejection::not_equal

    fn Rejection::not_equal(x : Rejection, y : Rejection) -> Bool

    Statement

    pub struct Statement {
    predicate_type : PredicateType
    subjects : Array[Subject]
    payload : Bytes
    } derive(Eq,
    Debug
    )

    The in-toto statement of a verified DSSE bundle.

    Statement::equal

    fn Statement::equal(Statement, Statement) -> Bool

    Statement::not_equal

    fn Statement::not_equal(x : Statement, y : Statement) -> Bool

    Subject

    pub struct Subject {
    name : String
    sha256 : ArtifactDigest?
    } derive(Eq,
    Debug
    )

    One subject of an in-toto statement.

    Subject::equal

    fn Subject::equal(Subject, Subject) -> Bool

    Subject::not_equal

    fn Subject::not_equal(x : Subject, y : Subject) -> Bool

    Subject::to_repr

    SubjectName

    pub struct SubjectName {
    // private fields
    } derive(Eq,
    Debug
    )

    An exact certificate identity: the URI or email subject alternative name.
    impl Show for SubjectName

    SubjectName::equal

    fn SubjectName::equal(SubjectName, SubjectName) -> Bool

    SubjectName::not_equal

    fn SubjectName::not_equal(x : SubjectName, y : SubjectName) -> Bool

    SubjectName::output

    fn SubjectName::output(self : SubjectName, logger : &Logger) -> Unit

    SubjectName::parse

    fn SubjectName::parse(text : String) -> SubjectName raise IdentityError

    Parse a certificate identity: a non-empty text with no spaces.

    SubjectName::to_string

    fn SubjectName::to_string(self : SubjectName) -> String

    TrustedLogSummary

    pub struct TrustedLogSummary {
    base_url : String
    key : KeyStatus
    }

    A log of the trusted root, for display.

    TrustedRoot

    pub struct TrustedRoot {
    // private fields
    }

    The keys and certificates that verification trusts. Only TrustedRoot::parse and TrustedRoot::public_good make it.

    TrustedRoot::parse

    fn TrustedRoot::parse(text : StringView) -> TrustedRoot raise TrustedRootError

    Read a trusted root from its protobuf JSON text, as sigstore-go reads it.

    TrustedRoot::public_good

    fn TrustedRoot::public_good() -> TrustedRoot

    The pinned Sigstore public-good trusted root (sigstore/root-signing c9bda74, SHA-256 6494e21e…0b66). It needs no I/O.

    TrustedRoot::summary

    The logs and authorities of the root, and whether each log key is usable.

    TrustedRootSummary

    pub struct TrustedRootSummary {
    transparency_logs : Array[TrustedLogSummary]
    certificate_authorities : Array[String]
    certificate_transparency_logs : Array[TrustedLogSummary]
    timestamp_authorities : Array[String]
    }

    What a trusted root holds, for display and tests.

    Verdict

    pub enum Verdict {
    Verified(VerifiedBundle)
    Rejected(Rejection)
    } derive(Eq,
    Debug
    )

    The result of a verification.

    Verdict::equal

    fn Verdict::equal(Verdict, Verdict) -> Bool

    Verdict::not_equal

    fn Verdict::not_equal(x : Verdict, y : Verdict) -> Bool

    Verdict::to_repr

    VerifiedBundle

    pub struct VerifiedBundle {
    statement : Statement?
    policy_index : Int
    claims : CertificateClaims
    log_id : Bytes
    log_index : Int64
    integrated_time : Instant
    } derive(Eq,
    Debug
    )

    The facts of a verified bundle.

    VerifiedBundle::equal

    VerifiedBundle::not_equal

    fn VerifiedBundle::not_equal(x : VerifiedBundle, y : VerifiedBundle) -> Bool

    WorkflowPath

    pub struct WorkflowPath {
    // private fields
    } derive(Eq,
    Debug
    )

    A workflow file in a repository, for example .github/workflows/release.yml.

    WorkflowPath::equal

    WorkflowPath::not_equal

    fn WorkflowPath::not_equal(x : WorkflowPath, y : WorkflowPath) -> Bool

    WorkflowPath::output

    fn WorkflowPath::output(self : WorkflowPath, logger : &Logger) -> Unit

    WorkflowPath::parse

    fn WorkflowPath::parse(text : String) -> WorkflowPath raise IdentityError

    Parse a workflow path: a .yml or .yaml file directly in .github/workflows/.

    WorkflowPath::to_string

    fn WorkflowPath::to_string(self : WorkflowPath) -> String

    public_good_trusted_root_json

    fn public_good_trusted_root_json() -> String

    The pinned public-good trusted_root.json text.

    verify

    fn verify(bundle : Bundle, artifact : ArtifactDigest, root : TrustedRoot, policy : Policy, now~ : Instant, alternatives? : Array[Policy]) -> Verdict

    Verify a Sigstore bundle for an artifact.

    The verdict passes when the bundle was logged in a transparency log of root, its certificate chains to a certificate authority of root at the log's integrated time, its signature covers content that names artifact, and its certificate matches policy or one of alternatives. now only bounds the integrated time. The function does no I/O and reads no clock.

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io