docs: align signing ceremony with Gitea workflow
This commit is contained in:
@@ -12,7 +12,7 @@ and destruction.
|
||||
| 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 |
|
||||
| Private key storage | Gitea repository Actions secret `GPG_PRIVATE_KEY` |
|
||||
| Public key storage | `packaging/keys/fenris-packaging.asc` in-repo, release notes, docs |
|
||||
| Keyservers | Never — TOFU-over-TLS via raw URL |
|
||||
|
||||
@@ -37,18 +37,22 @@ gpg --armor --export packaging@bongbetic.com > packaging/keys/fenris-packaging.a
|
||||
gpg --fingerprint packaging@bongbetic.com
|
||||
```
|
||||
|
||||
Save the **private key** to the password manager immediately:
|
||||
Provision the **private key** as the repository Actions secret `GPG_PRIVATE_KEY`.
|
||||
Run the export on the trusted key-generation machine, then enter its output in
|
||||
the Gitea repository's Actions secret settings. Do not save it in the checkout,
|
||||
logs, or a runner directory. The release workflow checks its fingerprint
|
||||
against the committed public key before signing.
|
||||
|
||||
```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:
|
||||
After provisioning the secret, delete the private key from the key-generation
|
||||
keyring:
|
||||
|
||||
```bash
|
||||
gpg --delete-secret-keys packaging@bongbetic.com
|
||||
gpg --delete-keys packaging@bongbetic.com
|
||||
gpg --batch --yes --delete-secret-keys packaging@bongbetic.com
|
||||
gpg --batch --yes --delete-keys packaging@bongbetic.com
|
||||
```
|
||||
|
||||
The committed `fenris-packaging.asc` must contain the real public key (replace
|
||||
@@ -56,52 +60,33 @@ 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.
|
||||
Each tagged release performs: **import → verify → sign → delete** on the
|
||||
repository-scoped Gitea Actions runner. The Gitea secret remains configured;
|
||||
the runner's keyring copy is removed after the job.
|
||||
|
||||
### Step 1: Import the private key
|
||||
### Step 1: Push the release tag
|
||||
|
||||
Retrieve the private key from the password manager and import it:
|
||||
After updating the version and dated changelog section, push the matching tag:
|
||||
|
||||
```bash
|
||||
gpg --import /tmp/packaging-key-private.asc
|
||||
rm /f /tmp/packaging-key-private.asc # Shred if possible
|
||||
git push origin v<version>
|
||||
```
|
||||
|
||||
### Step 2: Build and sign packages
|
||||
### Step 2: Build, verify, and sign packages
|
||||
|
||||
The Makefile target `make release` handles signing automatically when the
|
||||
key is in the keyring:
|
||||
The release workflow imports `GPG_PRIVATE_KEY`, checks it against
|
||||
`packaging/keys/fenris-packaging.asc`, builds packages, signs the RPM and
|
||||
clearsigned checksum manifest, validates both, and publishes the release.
|
||||
XBPS publication is separate and requires its signing key and host acceptance.
|
||||
|
||||
```bash
|
||||
make release # builds, signs RPM, clearsigns SHA256SUMS, prints upload steps
|
||||
```
|
||||
### Step 3: Verify runner cleanup
|
||||
|
||||
Under the hood:
|
||||
The workflow's `always()` cleanup removes the imported key from the runner's
|
||||
keyring, including after a failed job. Confirm no packaging secret key remains
|
||||
on the runner after the release job.
|
||||
|
||||
1. `rpmsign --addsign` signs the RPM payload with the packaging key
|
||||
(invoked by `make sign-rpm`).
|
||||
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.
|
||||
The Gitea Actions secret remains the approved signing source. Do not copy it to
|
||||
the runner or repository outside the workflow.
|
||||
|
||||
## Key rotation (outline)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user