Skip to content
About

Attach an inventory and origin claims

A signature says who made a statement about a digest. To reason about what was built, a verifier also needs structured claims: what packages are present, and what source/build invocation the workflow says produced the artifact. These statements help inspection and policy decisions while retaining the workflow as a trust dependency.

The signing workflow runs Syft against the digest it has just signed. It writes sbom.spdx.json, reports the package count, uploads the file as a GitHub artifact with 90-day retention, and calls cosign attest --predicate sbom.spdx.json --type spdxjson against the same image reference.

This is the SBOM required by the verification contract. Its subject binds the signed inventory to the image digest, and the signer ties it to the approved workflow identity. Those properties do not establish package completeness, accurate dependency relationships, license acceptability, or absence of vulnerabilities. The admission policy requires a valid SPDX attestation but has no package-content conditions.

The separate SBOM and VEX workflow generates a CycloneDX source SBOM from app/ and runs supplementary reachability analysis. It is not the image SPDX attestation. Its depscan step uses both continue-on-error: true and || true; the release chain does not depend on this job. Other failures in that job can still make the job red, so its “non-blocking” label means it is outside the build→sign→verify dependency path, not that every step ignores errors. Reports have 30-day retention.

The signing workflow creates a JSON provenance predicate and attests it using slsaprovenance, which the final consumers expect as https://slsa.dev/provenance/v0.2. Its relevant fields are:

Field Assertion created by this workflow
builder.id https://github.com/actions/runner
buildType https://github.com/Attestations/GitHubActionsWorkflow@v1
invocation.configSource.uri Canonical repository at refs/heads/main
invocation.configSource.digest.sha1 The run’s github.sha
invocation.configSource.entryPoint The reusable signing workflow path derived from job_workflow_ref
materials A repository URI and the same source commit
invocation.parameters Event, Git ref, and caller workflow context

The script requests a GitHub OIDC token with Sigstore audience, decodes the claim payload, and strips repository/ref portions of job_workflow_ref to obtain the entrypoint. This avoids confusing the top-level caller deploy.yml with the reusable workflow that produces the statement. The script-generated predicate is signed by that workflow; it is not a separately audited builder log.

The predicate schema is not a SLSA level. The workflow’s assertions do not prove a hermetic build, independently verified materials, reproducibility, or resistance to a compromised runner. This JSON also does not enumerate every dependency/base image as a source material. A trusted workflow capable of lying can create a well-formed, validly signed false claim.

CI verification compares more of these fields than admission does. It checks the current source commit and matching material in addition to digest, identity, builder, source URI, and entrypoint. Neither consumer explicitly validates the buildType field or every invocation parameter. Read the exact checks instead of interpreting printed provenance as enforced provenance.

Historical records corroborate SPDX/provenance verification for specific artifacts. The website does not use a package count as a security score or claim that attestation presence makes every package safe. Continue to the CI verification handoff to see how these claims become a release-candidate result.