Sign software and releases
These steps use gpg and sqv, which exist today. The release key, its keyring package and the guide’s drill are planned in ritueel (ADR 0006); no release is signed until the roots are adopted and drilled. Try everything on a test key first.
A release signature lets a user check that the file they downloaded is the one you published. It only means something if the user knows which key to trust and the key’s custody is sound. This page covers signing, publishing and verifying.
What you start with
Section titled “What you start with”- A release signing subkey held in a store (a card, or a cloud key service), bound by a master key that stays offline (the OpenPGP chain).
- The release files, built reproducibly if you can.
- A place to publish: your site, your repository’s releases, a package repository.
- Make a checksum file.
sha256sum *.tar.gz > SHA256SUMS. - Sign each file, or the checksum file, with a detached signature.
gpg --armor --detach-sign --local-user <fingerprint>! SHA256SUMSwritesSHA256SUMS.asc. Signing the checksum file covers every file in it with one touch. - Check your own signature with
gpg --verify SHA256SUMS.asc SHA256SUMSand withsqv, as a user would.
A detached signature sits beside the file and does not change it, so the same file can be fetched with or without verification.
Publish the public key and its fingerprint
Section titled “Publish the public key and its fingerprint”The signature is worthless if users get the key from the same place an attacker could change. Publish in more than one place:
- the fingerprint, in full (40 hexadecimal characters), on your project’s own site over HTTPS, in the release notes, and in the repository;
- the public key, as a file next to the release, and in a keyring package that a package manager installs (keyring package);
- for mail-based identities, a Web Key Directory entry.
Also publish the revocation, if there ever is one, in the same places. Say in the instructions that users should check the fingerprint, and show how.
Verify a download
Section titled “Verify a download”Give your users these steps:
- Get the key from the keyring package, or import it, and check that its fingerprint is the one on the project’s site:
gpg --fingerprint <fingerprint>. - Check the signature. The safest is
sqv --keyring release-keyring.pgp SHA256SUMS.asc SHA256SUMS. Withgpg, rungpg --status-fd 1 --verify SHA256SUMS.asc SHA256SUMSand accept the result only if it containsGOODSIGandVALIDSIGwith your fingerprint and does not containREVKEYSIGorEXPKEYSIG. - Check the file against the checksum.
sha256sum -c SHA256SUMS --ignore-missing.
Never treat the exit status of gpg --verify as the decision. Measured on 2026-11-01, gpg reports a good signature for a revoked key, and gpgv and apt ignore revocations. See OpenPGP release keys.
How others publish it
Section titled “How others publish it”- The Linux kernel signs each release and tells users to find the signer’s key through the Web Key Directory:
gpg2 --locate-keys user@kernel.org. - Tor tells users to import its key with
gpg --auto-key-locate nodefault,wkd --locate-keys torbrowser@torproject.org, and check withgpgv --keyring ./tor.keyring file.asc file. - Smaller tools often use minisign or signify, with a short public key printed on the site. They are simpler, and no package manager reads them.
Read from the projects’ pages on 2026-11-01. Publish version 4 certificates, as GitHub, GitLab, apt and rpm consumers need (the OpenPGP chain).
Where the key lives
Section titled “Where the key lives”A release key that sits in a file on a build server can be copied. Prefer a subkey held in a card or a cloud key service, so that signing is a call that CI makes with its own identity and audit trail, and the private key cannot be taken. The key is replaced, not copied, when custody changes (Rotate). Compare the options in Where a key lives.
How you know it worked
Section titled “How you know it worked”- A clean machine that has only the keyring package and the site’s fingerprint verifies the release.
- A modified file fails the checksum, and a modified signature fails the check.
- After a revocation drill, a machine with the new keyring refuses the revoked key.