Infrastructure worth keeping — and kept patched.

Verify a FosterStack Cache release yourself

You should not have to take our word for what you run. Signed at every stage, verified together at release. These steps check the image signatures, the signed file lists, the digest, how the release was built and its parts list, using only cosign, gh, jq and sha256sum. They are for v0.3.0 and later. For v0.2.x, see the image verification guide.

You need no account to pull the images or to run cosign. Downloading release files with gh needs gh auth login; you can also download them from the release page in a browser.

Set the version

VER=$(curl -fsSL https://api.github.com/repos/fosterstack/cache/releases/latest \
        | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p')
echo "$VER"
IDENT="https://github.com/fosterstack/cache/.github/workflows"
ISSUER=https://token.actions.githubusercontent.com

There are two images, production and -fips. Run step 1 for each.

1. The signature and who signed it

cosign verify ghcr.io/fosterstack/cache:${VER} \
  --certificate-identity "${IDENT}/stage-promote.yml@refs/tags/v${VER}" \
  --certificate-oidc-issuer "$ISSUER"
cosign verify ghcr.io/fosterstack/cache:${VER}-fips \
  --certificate-identity "${IDENT}/stage-promote.yml@refs/tags/v${VER}" \
  --certificate-oidc-issuer "$ISSUER"

This shows that the release stage of our public pipeline, at this release tag, signed these exact images. The signing certificate lasts minutes and is recorded in Rekor, the public transparency log. There is no signing key to steal.

2. The file lists are ours, and your files match them

gh release download v${VER} --repo fosterstack/cache \
  -p checksums.txt -p checksums.txt.bundle \
  -p release-files.sha256 -p release-files.sha256.bundle \
  -p release-manifest.json -p "fscache_${VER}_linux_amd64.tar.gz"
for f in checksums.txt release-files.sha256; do
  cosign verify-blob "$f" --bundle "$f.bundle" \
    --certificate-identity "${IDENT}/stage-promote.yml@refs/tags/v${VER}" \
    --certificate-oidc-issuer "$ISSUER"
done
sha256sum -c <(grep "fscache_${VER}_linux_amd64.tar.gz" checksums.txt)
sha256sum -c <(grep release-manifest.json release-files.sha256)

Do the signature check first. Without it, a list only proves that your files match a file anyone could have written. The archives are covered by the signed checksums.txt, and the manifest by the signed release-files.sha256.

3. The digest is the one in the release

jq -r '.images[] | "\(.variant) \(.digest)"' release-manifest.json

Every statement names an image by digest, never by tag. The digest you pulled should be in this list.

4. How it was built

gh release download v${VER} --repo fosterstack/cache \
  -p provenance.json -p provenance.bundle.json
cosign verify-blob-attestation --bundle provenance.bundle.json \
  --type https://slsa.dev/provenance/v1 --check-claims=false \
  --certificate-identity "${IDENT}/stage-sign.yml@refs/tags/v${VER}" \
  --certificate-oidc-issuer "$ISSUER"
jq -r '.dsseEnvelope.payload | @base64d | fromjson | .subject[] | .name + " sha256:" + .digest.sha256' provenance.bundle.json

The SLSA provenance is signed by a separate job with its own identity, stage-sign.yml. It receives only the list of digests the build made and runs no code from the build. The second command lists each item it names, with its digest.

5. The parts list and what it was assembled from

gh release download v${VER} --repo fosterstack/cache \
  -p production.sbom.json -p production.sbom.json.bundle \
  -p production.full.lock.json -p production.full.lock.json.bundle
for f in production.sbom.json production.full.lock.json; do
  cosign verify-blob "$f" --bundle "$f.bundle" \
    --certificate-identity "${IDENT}/stage-promote.yml@refs/tags/v${VER}" \
    --certificate-oidc-issuer "$ISSUER"
done

The SBOM lists what is in the image. The lock file lists every package the image was assembled from, by checksum. Repeat with fips.sbom.json and fips.full.lock.json for the -fips image.

What this proves

Each stage of the release also writes a record that anyone with the Witness tool can check. Those records are extra evidence outside the steps above, and are attached to the release.

Related: how releases are built and signed, how the pipeline maps to NIST and SLSA and scan the image yourself.

Moving off the free Build Cache Node? See what the end of life means and the migration guide.