SBOM & provenance
Alongside its cosign signature, every image carries two more attestations attached to the same digest: an SPDX software bill of materials, and a SLSA build-provenance statement that records which workflow built it from what. Both are signed keyless through Sigstore and pushed to GHCR as OCI referrers, so you can read and verify them without trusting anything but the transparency log.
See what is attached
Cosign lists every referrer on an image: the signature and the two attestations.
cosign tree ghcr.io/quenchworks/images/redis@sha256:<digest>
# ├── Signatures
# │ └── ...redis:sha256-<digest>.sig
# └── Attestations
# ├── https://spdx.dev/Document/v2.3 (SBOM)
# └── https://slsa.dev/provenance/v1 (build provenance) Get the digest from the catalog page or with crane. The attestations are attached to the multi-arch index by digest, the same one the chart pins.
Verify the build provenance
The provenance attestation answers "where did this come from?". It binds the image digest to the exact GitHub Actions workflow, commit, and runner that produced it, following the SLSA provenance schema. The GitHub CLI checks it against Sigstore and the owner:
gh attestation verify \
oci://ghcr.io/quenchworks/images/redis@sha256:<digest> \
--owner quenchworks A pass means the image was built by a workflow in the quenchworks org and has not been altered since. A non-zero exit means it failed.
Verify and read the SBOM
The SBOM lists every package in the image. Verify the SBOM attestation by predicate type:
gh attestation verify \
oci://ghcr.io/quenchworks/images/redis@sha256:<digest> \
--owner quenchworks \
--predicate-type https://spdx.dev/Document To pull the SPDX document itself out and inspect it, add --format json and read the predicate:
gh attestation verify \
oci://ghcr.io/quenchworks/images/redis@sha256:<digest> \
--owner quenchworks \
--predicate-type https://spdx.dev/Document \
--format json | jq '.[0].verificationResult.statement.predicate' In a script or CI step, always pass --format json: the human-readable banner only prints to a terminal, while the exit code is what you gate on.
What this gives you
- A package inventory for audit and vulnerability triage, tied to the exact digest you run.
- A tamper-evident record of how the image was built, with no key to manage on either side.
- A check you can run yourself, in CI or by hand, rather than a claim you have to take on faith.
Charts are cosign-signed as well; see Verify a signature for the chart and image signature checks, and Pin by digest for getting the digest these commands need.