Verifying a download
Check a Sealr release archive with SHA256SUMS and its SLSA build-provenance attestation, and understand exactly what each check proves.
You are about to install a binary that will sit between your agents and production. Check it before you run it.
Every release publishes three kinds of file:
- the archives,
sealr-<version>-<target>.tar.gz/.zip SHA256SUMS, one line per archive- a build-provenance attestation per archive, stored in GitHub's attestation store rather than as a downloadable file
The two checks answer different questions. The checksum answers did I get the bytes intact. The attestation answers where did these bytes come from. Run both; neither substitutes for the other.
Checksums
Download SHA256SUMS from the same release as the archive.
VERSION=0.1.0
curl -fsSLO "https://github.com/sealr-labs/sealr/releases/download/v${VERSION}/SHA256SUMS"
sha256sum --ignore-missing -c SHA256SUMSsealr-0.1.0-x86_64-unknown-linux-gnu.tar.gz: OKSHA256SUMS lists every platform's archive. Without --ignore-missing, sha256sum reports
a failure for each file you did not download, and the useful line gets lost in the noise.
What a checksum proves
It proves the bytes are intact. The file you have is byte-identical to the file whose
hash went into SHA256SUMS. This catches a truncated download, a corrupted disk, a proxy
that rewrote the response, a CDN serving a stale object.
It does not prove where the file came from. SHA256SUMS is published alongside the
archives, unsigned. Anyone able to replace an archive on the release page could replace the
checksum file in the same motion, and both would agree. A checksum is an integrity check
against accident and against attackers who can touch the transport but not the release.
For origin, you need the attestation.
Build provenance
Provenance attestation requires a public repository, or a plan that includes GitHub's
attestation store. While the Sealr repository is private and on a plan without it, releases
ship the archives and SHA256SUMS but no attestation, and the command below will report
that none was found. That is the current state, not a verification failure — check the
release page for which artefacts a given version actually carries.
Where it is published, each release archive carries a SLSA build-provenance attestation, generated by the release workflow and signed through Sigstore with a short-lived certificate bound to that workflow's OIDC identity. Verify it with the GitHub CLI:
gh attestation verify sealr-0.1.0-x86_64-unknown-linux-gnu.tar.gz -R sealr-labs/sealrLoaded digest sha256:… for file://sealr-0.1.0-x86_64-unknown-linux-gnu.tar.gz
Loaded 1 attestation from GitHub API
✓ Verification succeeded!This needs gh 2.49 or newer, authenticated with gh auth login — the attestations are
fetched from GitHub's API even for a public repository.
Tighten the check by naming the workflow that is allowed to have produced the file. Without it, any attestation from the repository satisfies verification; with it, only the release workflow does:
gh attestation verify sealr-0.1.0-x86_64-unknown-linux-gnu.tar.gz \
-R sealr-labs/sealr \
--signer-workflow sealr-labs/sealr/.github/workflows/release.ymlFor a build environment with no egress at verification time, fetch the attestation ahead of time and verify against the local copy:
gh attestation download sealr-0.1.0-x86_64-unknown-linux-gnu.tar.gz -R sealr-labs/sealr
gh attestation verify sealr-0.1.0-x86_64-unknown-linux-gnu.tar.gz \
-R sealr-labs/sealr --bundle sha256:<digest>.jsonlTest that path in your actual environment before depending on it: gh may still reach out
for Sigstore trust material even when the attestation itself is local.
What provenance proves
It proves origin and build path. The file with this digest was produced by the release
workflow in sealr-labs/sealr, running on GitHub-hosted runners, from a specific commit.
The signing certificate is issued per-run against the workflow's OIDC identity and the
attestation is recorded in a public transparency log. Somebody who builds a modified sealr
on their own machine cannot produce an attestation that passes this check — they would have
to compromise the repository or GitHub's issuer, and the transparency log would carry the
evidence.
It does not prove the software is good. Provenance says the artifact came from that source through that pipeline. It says nothing about whether the source is correct, whether it has vulnerabilities, or whether a change with push access to the repository was well-intentioned. A malicious commit, built by the official workflow, produces a perfectly valid attestation.
It is not code signing. The binaries are not signed with an Apple Developer ID and not notarised, and not Authenticode-signed on Windows. Provenance verification does not change what Gatekeeper or SmartScreen do — see the platform notes on the installation page.
It does not cover anything you did not verify. The attestation binds to the archive's digest. If you verify the tarball and then extract it somewhere writable by another process, the check no longer says anything about the binary you eventually run.
sealr version prints a line pointing at cosign for release verification. That text is
ahead of the pipeline: releases today carry SHA256SUMS and the SLSA build-provenance
attestation described here, not detached cosign signature files. Use the two checks on
this page.
If a check fails
Do not install the file.
- Checksum mismatch. Almost always an incomplete or corrupted download. Delete the archive and download it again, ideally over a different network. A second mismatch on a clean download is not a transport problem — stop and report it.
- Provenance verification failure. Confirm the archive name and repository are right,
and that
ghis authenticated. If it still fails on a freshly downloaded file, treat the artifact as untrusted and open an issue on the repository. Do not fall back to "the checksum was fine" — a matching checksum against an unsigned checksum file is exactly what a substituted release would show.
In CI
Pin the version, verify both ways, and fail the job if either check fails. This is the whole install step for a GitHub Actions runner:
- name: Install sealr
env:
SEALR_VERSION: 0.1.0
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
asset="sealr-${SEALR_VERSION}-x86_64-unknown-linux-gnu.tar.gz"
gh release download "v${SEALR_VERSION}" -R sealr-labs/sealr -p "$asset" -p SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMS
gh attestation verify "$asset" -R sealr-labs/sealr \
--signer-workflow sealr-labs/sealr/.github/workflows/release.yml
tar xzf "$asset"
sudo install -m 0755 sealr-*/sealr sealr-*/sealr-verify /usr/local/bin/
sealr --versionset -euo pipefail matters here: without it a failed verification is a non-zero exit code
that the shell steps straight past, and the pipeline installs an unverified binary while
reporting success. More pipeline shapes are in CI.
Not the same thing as verifying evidence
This page is about trusting the tool. Verifying the output of the tool — a .seal
evidence bundle, checked offline with sealr-verify, without trusting Sealr or the person
who handed you the bundle — is a separate operation with separate guarantees. See
verifying evidence.