Verifying a release
Every koryph release ships more than binaries: a checksum manifest, a keyless cosign signature over that manifest, a SLSA provenance attestation, and a per-archive SPDX software bill of materials (SBOM). Together they let you prove — without trusting anything but GitHub's OIDC issuer and the public Rekor transparency log — that a download came from this repository's release workflow and matches exactly what it built.
This chapter walks through consuming those assets after downloading a release. For how they're produced, see Releasing & versioning.
What's on the release page
For each tagged release (e.g. v0.5.0) the
Releases page carries:
| Asset | What it is |
|---|---|
koryph_<version>_<os>_<arch>.tar.gz |
A platform binary archive (darwin/linux × amd64/arm64). |
<archive>.sbom.spdx.json |
A per-archive SPDX 2.3 software bill of materials, one per platform tarball. |
checksums.txt |
SHA-256 of every archive and SBOM in the release. |
checksums.txt.sigstore.json |
A cosign keyless (Sigstore) signature bundle over checksums.txt — certificate + signature combined. |
checksums.txt.intoto.jsonl |
A SLSA v0.2 provenance attestation (DSSE envelope) for checksums.txt, produced by the SLSA generic generator. |
Only checksums.txt is directly signed and attested. Because it lists the
SHA-256 of every other asset, verifying it and then checking a downloaded
file's hash against its line in the manifest transitively authenticates
that file too — you don't need a separate signature per archive.
1. Integrity: does the download match the manifest?
Download checksums.txt alongside whichever archive(s) you need, then
check the archive's hash against its line in the manifest:
# macOS / BSD
shasum -a 256 -c --ignore-missing checksums.txt
# Linux (GNU coreutils)
sha256sum -c --ignore-missing checksums.txt
Expected output (one OK line per file you actually downloaded — anything
else you didn't fetch is skipped by --ignore-missing):
koryph_0.5.0_darwin_arm64.tar.gz: OK
If this fails, stop — do not run the archive. Either the download was corrupted in transit, or the file does not match what the release actually published.
2. Authenticity: was this manifest produced by koryph's release workflow?
checksums.txt is signed keylessly with cosign:
the signing identity is a short-lived certificate binding the exact GitHub
Actions workflow file and ref that ran, issued by Sigstore's Fulcio CA and
recorded in the public Rekor log. There is no long-lived private key to
leak, steal, or rotate.
Verify with cosign verify-blob, pinning both the OIDC issuer and the
workflow identity that must have produced the signature:
cosign verify-blob \
--bundle checksums.txt.sigstore.json \
--certificate-identity-regexp '^https://github\.com/koryph/koryph/\.github/workflows/release-please\.yml@refs/heads/main$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txt
Expected output:
Verified OK
The --certificate-identity-regexp above is anchored to the exact
workflow file (.github/workflows/release-please.yml) and ref
(refs/heads/main) that GitHub's OIDC token attests to for this repo's
release pipeline — not just the repository name — so a signature minted by
some other workflow in this repo (or a fork) will not pass. Passing
verification proves checksums.txt was produced by that workflow run, and
the integrity check in step 1 extends that trust to every archive whose
hash it lists.
3. Provenance: was it built the way it claims to be?
For stronger, non-forgeable assurance than a signature alone, verify the
SLSA provenance attestation with
slsa-verifier:
go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@v2.7.1
# or download a prebuilt binary from its releases page
slsa-verifier verify-artifact checksums.txt \
--provenance-path checksums.txt.intoto.jsonl \
--source-uri github.com/koryph/koryph \
--source-branch main
Expected output:
Verified build using builder "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@refs/tags/v2.1.0" at commit <sha>
Verifying artifact checksums.txt: PASSED
PASSED: SLSA verification passed
Use --source-branch main, not --source-tag. koryph's release
pipeline runs as a single workflow triggered by a push to main (see
Releasing & versioning
for why), and the provenance's build invocation records that trigger —
refs/heads/main — not the release tag it eventually pushes. Passing
--source-tag v0.5.0 fails with invalid ref because the attestation
never claims a tag ref; --source-branch main, or omitting the ref check
entirely (--source-uri alone), matches what was actually attested.
A PASSED result proves checksums.txt (and, via the checksum chain in
step 1, every archive it lists) was built by this repository's GitHub
Actions workflow at the recorded commit — Build Level 3 provenance, not
just a signature.
4. Consuming the SBOMs
Each platform archive carries a companion SPDX 2.3 SBOM,
<archive>.sbom.spdx.json, generated by syft
during the same build that produced the archive. It enumerates every Go
module compiled into that binary, with checksums, package URLs (purl), and
CPE identifiers for vulnerability matching.
List every package and version:
jq -r '.packages[] | "\(.name) \(.versionInfo)"' koryph_0.5.0_linux_amd64.tar.gz.sbom.spdx.json
Check declared licenses (koryph's own Go-module SBOMs mostly read
NOASSERTION — syft did not find embedded license metadata for those
modules — so treat this as a starting point for your own license review,
not a final answer):
jq -r '.packages[] | "\(.name): \(.licenseDeclared)"' koryph_0.5.0_linux_amd64.tar.gz.sbom.spdx.json
Feed the SBOM to a vulnerability scanner instead of re-deriving the dependency list yourself. For example, with grype:
grype sbom:koryph_0.5.0_linux_amd64.tar.gz.sbom.spdx.json
or osv-scanner:
osv-scanner --sbom koryph_0.5.0_linux_amd64.tar.gz.sbom.spdx.json
Neither tool is required to use koryph — they're independent, optional scanners that happen to consume the SPDX format koryph already publishes.
Putting it together
A minimal end-to-end check for one platform archive:
tag=v0.5.0
archive=koryph_0.5.0_darwin_arm64.tar.gz
gh release download "$tag" --repo koryph/koryph \
-p "$archive" -p "$archive.sbom.spdx.json" \
-p checksums.txt -p checksums.txt.sigstore.json -p checksums.txt.intoto.jsonl
shasum -a 256 -c --ignore-missing checksums.txt
cosign verify-blob \
--bundle checksums.txt.sigstore.json \
--certificate-identity-regexp '^https://github\.com/koryph/koryph/\.github/workflows/release-please\.yml@refs/heads/main$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txt
A downloaded archive that passes all three (checksum, signature, and optionally SLSA provenance) is verifiably the binary koryph's own release workflow built and published for that tag.