# 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 ` | | 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 ```bash # Generate the dedicated RSA-3072 packaging key gpg --batch --gen-key < 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: ```bash 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: ```bash 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: ```bash 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: ```bash make release # builds, signs RPM, clearsigns SHA256SUMS, prints upload steps ``` Under the hood: 1. `nfpm pkg -p rpm` signs the RPM payload via `rpm.signature.key_file` and `rpm.signature.key_id` in `packaging/nfpm.yaml`. 2. `sha256sum` generates the checksum manifest. 3. `gpg --clearsign` produces `SHA256SUMS.asc` with the packaging key. ### Step 3: Delete the private key Immediately after signing: ```bash gpg --delete-secret-keys packaging@bongbetic.com gpg --delete-keys packaging@bongbetic.com ``` Verify the key is gone: ```bash 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: 1. **Generate a new key** using the same procedure as first release. 2. **Publish the new public key** alongside the old one in-repo: ```text packaging/keys/fenris-packaging.asc # new key (primary) packaging/keys/fenris-packaging-previous.asc # old key (one cycle) ``` 3. **Sign the next RPM** with the new key. 4. **Update `fenris.repo`** to list both `gpgkey` URLs (dnf accepts multiple): ```ini 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 ``` 5. **Drop the old key** from the repo after one release cycle. Delete `fenris-packaging-previous.asc` and revert `gpgkey` to 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: ```bash gpg --verify SHA256SUMS.asc SHA256SUMS sha256sum -c SHA256SUMS ```