Signing your releases
Whoever controls your release page can swap a binary, and a checksum hosted beside it proves nothing. Sixteen posts on fixing that, in the order they make sense.
Start here
The problem, and what the rest of this is for.
-
Sign your own binaries with go-tool-baseWhoever controls your release page can swap a binary, and a checksum hosted beside it proves nothing. A seven-part guide to signing releases.
Orienteering
-
Nobody's coming to clean your supply chainSigned but poisoned packages show a signature proves who sent something, not what is in it. Nobody is coming to clean this up for you.
Soapbox
The tutorial, in order
Seven parts, laptop to production. Each one leaves you with something that works.
-
Sign your own binaries with go-tool-base, part 1: sign and verify on your laptopThe laptop-only quick start: make a signing key, mint the public key you publish, sign a file, and verify it with both gtb and plain gpg.
Orienteering
-
Sign your own binaries with go-tool-base, part 2: a signing key in AWS KMSStand up a production signing key in AWS KMS with Terraform, so the private half is generated inside KMS and can never be exported.
Orienteering
-
Sign your own binaries with go-tool-base, part 3: keyless CI signing with OIDCLet CI sign with a KMS key without storing any AWS credentials, using OIDC federation. Covers both the GitLab and the GitHub path.
Orienteering
-
Sign your own binaries with go-tool-base, part 4: mint and publish your public keyMint an OpenPGP public key from a KMS-held private key you cannot hold, and publish it somewhere the release platform cannot reach.
Orienteering
-
Sign your own binaries with go-tool-base, part 5: embed the key and require verificationEmbed the trust anchor in your binary and require signature verification on update, without bricking anyone already running an old build.
Orienteering
-
Sign your own binaries with go-tool-base, part 6: sign every release with GoReleaserMake a tagged release sign itself: record the KMS key and regenerate GoReleaser config with a signs block that calls gtb sign directly.
Orienteering
-
Sign your own binaries with go-tool-base, part 7: rotation and break-glassRotate a release signing key and recover from a bad one without locking users out. Why asymmetric KMS keys have no auto-rotate button.
Orienteering
How it works
The design decisions underneath, and the problems that forced them.
-
A signature the platform can't forgeA checksum proves the bytes match the manifest, but says nothing about who wrote the manifest. Why self-update needs a signature instead.
Pioneering
-
A signing key that never leaves KMSGenerate an asymmetric RSA-4096 signing key inside AWS KMS with no export path, then sign releases by calling kms:Sign instead of holding the key.
Pioneering
-
The gpg command that hung (so I built signing into the tool)A gpg call that hung and never returned, and why release signing ended up built into the Go tool itself rather than shelled out to the gpg binary.
Pioneering
-
The framework doesn't know where your signing key livesWhere a signing key lives is the most provider-specific decision in the whole business, so the framework deliberately refuses to have an opinion.
Pioneering
The arguments
Why any of this is worth the effort.
-
Bought, not stolenThe philosophical end of the signing series: a stolen key and a bought one produce the same signature, and trust has to survive both.
Soapbox
-
Release trust without the frameworkTwo new public modules extracting the OpenPGP signing and verification model, so you can use it without adopting the whole framework.
First Light
-
One key, or two?Launching sigillum, a standalone artefact signing and verification CLI, and the Rust signing problem that made it necessary.
First Light