Implement the signing and consumer-repo trust infrastructure: - Makefile: add generate-test-key, sign-rpm, checksums, clearsign targets; make release now automates the full build→sign→checksum→clearsign flow - Key ceremony: document the import→sign→delete lifecycle, key rotation outline, and private-key-in-password-manager policy - Public key: update placeholder with raw URL, algorithm, and ceremony ref - Consumer docs: README now covers apt signed-by keyring flow, dnf repo file setup, signature verification commands, and migration runbook link - Release spec: updated to reference ceremony doc and rpmsign workflow - Tests: 36 structural signing tests (nfpm config, Makefile targets, repo file, key publication, ceremony doc, consumer docs, spec refs) plus throwaway-key RPM signature and clearsign mechanics; no network or real key required Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
4.0 KiB
Signing key ceremony
The Fenris packaging key signs RPM payloads and clearsigns SHA256SUMS manifests. This document describes the key's lifecycle: creation, per-release use, rotation, and destruction.
Key specification
| Property | Value |
|---|---|
| Algorithm | RSA 3072 |
| UID | Fenris Packaging <packaging@bongbetic.com> |
| Expiry | 2 years from creation |
| Hierarchy | Single key — no master/subkey split (single maintainer, manual builds) |
| Private key storage | Password manager only |
| Public key storage | packaging/keys/fenris-packaging.asc in-repo, release notes, docs |
| Keyservers | Never — TOFU-over-TLS via raw URL |
First release: key creation
# Generate the dedicated RSA-3072 packaging key
gpg --batch --gen-key <<EOF
%no-protection
Key-Type: RSA
Key-Length: 3072
Name-Real: Fenris Packaging
Name-Email: packaging@bongbetic.com
Expire-Date: 2y
%commit
EOF
# Export the public half — this file is committed to the repo
gpg --armor --export packaging@bongbetic.com > packaging/keys/fenris-packaging.asc
# Print the fingerprint for docs and release notes
gpg --fingerprint packaging@bongbetic.com
Save the private key to the password manager immediately:
gpg --armor --export-secret-keys packaging@bongbetic.com
Then delete the private key from the local keyring — it must never persist on any build host:
gpg --delete-secret-keys packaging@bongbetic.com
gpg --delete-keys packaging@bongbetic.com
The committed fenris-packaging.asc must contain the real public key (replace
the placeholder comments).
Per-release signing flow
Each release performs: import → sign → delete. The private key is never stored on disk longer than the release takes.
Step 1: Import the private key
Retrieve the private key from the password manager and import it:
gpg --import /tmp/packaging-key-private.asc
rm /f /tmp/packaging-key-private.asc # Shred if possible
Step 2: Build and sign packages
The Makefile target make release handles signing automatically when the
key is in the keyring:
make release # builds, signs RPM, clearsigns SHA256SUMS, prints upload steps
Under the hood:
nfpm pkg -p rpmsigns the RPM payload viarpm.signature.key_fileandrpm.signature.key_idinpackaging/nfpm.yaml.sha256sumgenerates the checksum manifest.gpg --clearsignproducesSHA256SUMS.ascwith the packaging key.
Step 3: Delete the private key
Immediately after signing:
gpg --delete-secret-keys packaging@bongbetic.com
gpg --delete-keys packaging@bongbetic.com
Verify the key is gone:
gpg --list-keys packaging@bongbetic.com
# Should produce: gpg: keyblock resource ...: No such file or directory
The entire import → sign → delete cycle should take minutes. The private key must never be left in any keyring between releases.
Key rotation (outline)
When the key approaches expiry, or if it is compromised:
- Generate a new key using the same procedure as first release.
- Publish the new public key alongside the old one in-repo:
packaging/keys/fenris-packaging.asc # new key (primary) packaging/keys/fenris-packaging-previous.asc # old key (one cycle) - Sign the next RPM with the new key.
- Update
fenris.repoto list bothgpgkeyURLs (dnf accepts multiple):gpgkey=https://git.bongbetic.com/xavierk/Fenris/raw/branch/main/packaging/keys/fenris-packaging.asc https://git.bongbetic.com/xavierk/Fenris/raw/branch/main/packaging/keys/fenris-packaging-previous.asc - Drop the old key from the repo after one release cycle. Delete
fenris-packaging-previous.ascand revertgpgkeyto the single URL.
Verification
Consumers verify the RPM payload signature via dnf (gpgcheck=1 in
fenris.repo points at the published public key). The SHA256SUMS manifest
verification is manual for downloaded assets:
gpg --verify SHA256SUMS.asc SHA256SUMS
sha256sum -c SHA256SUMS