Release Signing¶
A checksum alone binds a release to nothing: it lives in the same
packaging/aur/PKGBUILD that release automation owns, so anyone who can change
the artifact can change the checksum beside it. TrustSight therefore signs the
release tarball with a key that is not available to CI, and pins that key
in the PKGBUILD so makepkg and yay verify it on every user's machine.
The key¶
The release tarball is signed with the maintainer's pinned commit-signing GPG key. It is the same key that signs commits touching critical paths, and its private half exists only on the maintainer's machine.
| Purpose | Algorithm | Fingerprint |
|---|---|---|
| Commit and release signing | RSA 4096 (GPG) | F759D6D49B0A395AB922414A5CC3B4C50D37E793 |
The public half is committed at scripts/commit_signing_key.asc, published on
keys.openpgp.org,
and pinned in .SRCINFO
as validpgpkeys. This is a different key from the ed25519 baseline
distribution key in baseline keys: that one
signs the baseline-* channel assets and its private half is the
BASELINE_SIGNING_KEY Actions secret, while this one signs the software
release tarball and never enters CI.
What is signed¶
Each software release carries a detached signature over the deterministic source tarball:
trustsight-<version>.tar.gz.sig: made withgpg --detach-sign --local-user F759D6D4…!, over the exact bytes oftrustsight-<version>.tar.gz. The trailing!forces the primary key: the committed public key carries the primary and its encryption subkey, not the separate Ed25519 signing subkey, so a signature by that subkey would not verify against it.
The tarball is deterministic (scripts/build_release_tarball.py), so the
signature is known before the tag exists and ships in the same commit as the
version. packaging/aur/PKGBUILD declares the .sig as a source, pins the key
in validpgpkeys, and records the signature's real sha256, never SKIP.
Verifying a release¶
makepkg and yay verify the signature automatically when the key is in the
local keyring. Fetch it once:
Then either let makepkg verify it as part of a build, or check it by hand:
CI proves the same thing without the private key. publishing.yml and
release-pkgbuild.yml import the committed public key and verify the
signature; pkgbuild.yml verifies it on a tagged tree and checks checksums
only on an untagged pre-release tree, where the deterministic tarball has
moved since the signature was made. scripts/verify_release.py refuses to pass
a release whose .sig does not verify against the pinned fingerprint. CI can
verify a signature it cannot produce, which is the point.
Rotation¶
Rotation means cutting a release that pins a new key, with no in-band revocation:
- Generate a new keypair. Replace its public half in
scripts/commit_signing_key.asc, thevalidpgpkeysfingerprint inpackaging/aur/PKGBUILD, and this page's fingerprint row, in one commit.scripts/commit_signing_key.ascis a critical path, so the commit must be signed by the old key (or a new key already trusted by the policy). - Publish the new public key to keys.openpgp.org.
- Sign the next release's tarball with the new key.
An unsigned or wrong-key release is not a warning: makepkg refuses to build it, and the release workflows fail before publishing.