Verifying releases
Every release is built from a tagged commit by GitHub Actions; nobody builds or uploads release binaries by hand. Each release publishes:
| Artifact | What it’s for |
|---|---|
dotsync_<version>_<os>_<arch>.tar.gz |
the binary, with LICENSE, README.md and CHANGELOG.md. <os> is darwin or linux, <arch> is amd64 or arm64 |
dotsync_<version>_<arch>.deb |
the Debian/Ubuntu package, also served by the APT repository |
checksums.txt |
the SHA-256 of every archive and package |
<archive or package>.sbom.json |
a software bill of materials for each archive and package |
dotsync_<version>.intoto.jsonl |
the signed SLSA build provenance for every archive and package, also stored with GitHub. It ties each file to the workflow run, commit and repository that built it |
The provenance is signed through Sigstore with the release workflow’s own short-lived identity. There’s no long-lived signing key that could leak.
Verify the provenance
Section titled “Verify the provenance”This is the check that matters: it proves the file was built by this repository’s release workflow, from a commit in this repository.
-
Install the GitHub CLI, version 2.49 or newer, and log in with
gh auth login. -
Verify the archive you downloaded:
Terminal window gh attestation verify dotsync_0.5.0_darwin_arm64.tar.gz --repo pungoyal/dotsyncIt ends with
✓ Verification succeeded!, and exits with status0.
To see exactly which workflow run and commit built it:
gh attestation verify dotsync_0.5.0_darwin_arm64.tar.gz --repo pungoyal/dotsync --format json \ | jq '.[0].verificationResult.signature.certificate | {sourceRepositoryRef, sourceRepositoryDigest, runInvocationURI}'Against the attached bundle
Section titled “Against the attached bundle”The same signed provenance is attached to every release, so you can verify against the file instead of fetching it from GitHub’s attestation API:
gh attestation verify dotsync_0.5.0_darwin_arm64.tar.gz \ --bundle dotsync_0.5.0.intoto.jsonl --repo pungoyal/dotsyncVerify the checksum
Section titled “Verify the checksum”curl -fsSLO https://github.com/pungoyal/dotsync/releases/download/v0.5.0/checksums.txtshasum -a 256 --check --ignore-missing checksums.txt # macOSsha256sum --check --ignore-missing checksums.txt # LinuxA checksum only proves the download wasn’t corrupted on the way. Someone who can replace the archive can replace checksums.txt too; only the provenance proves where the file came from.
Homebrew and apt
Section titled “Homebrew and apt”Both install the files described above, so everything on this page applies to them too:
- The Homebrew formula is generated by the release workflow from
checksums.txt, and Homebrew refuses a download whose SHA-256 doesn’t match. It’s published to pungoyal/homebrew-tap, whose history shows every change. - The APT repository is rebuilt from the latest release’s
.debfiles after their checksums and provenance are verified. Its index is signed with the repository key, and apt refuses a package whose hash doesn’t match the signed index. To check a package against the release yourself, rungh attestation verifyon the.debfrom the release page.
Reproduce a build
Section titled “Reproduce a build”Release binaries are built by GoReleaser with CGO_ENABLED=0 and -trimpath, stripped, and with the version, commit and commit date set at link time; file timestamps come from the commit, not the build machine. Building the tagged commit the same way, with the same Go version, reproduces the binary. go version -m dotsync shows the Go version and build settings of any binary.