diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 2cd8b1d..1ed5a34 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -159,7 +159,6 @@ jobs: gpg --batch --yes --delete-secret-keys "${FINGERPRINT}" gpg --batch --yes --delete-keys "${FINGERPRINT}" fi - rm -f ~/.ssh/id_xbps - name: Determine version id: version @@ -345,3 +344,7 @@ jobs: "https://git.bongbetic.com/api/v1/repos/xavierk/Fenris/releases/${RELEASE_ID}/assets" fi done + + - name: Remove XBPS signing key + if: always() + run: rm -f ~/.ssh/id_xbps diff --git a/docs/install/signing-key-ceremony.md b/docs/install/signing-key-ceremony.md index 42ea669..01e038f 100644 --- a/docs/install/signing-key-ceremony.md +++ b/docs/install/signing-key-ceremony.md @@ -58,6 +58,20 @@ gpg --batch --yes --delete-keys packaging@bongbetic.com The committed `fenris-packaging.asc` must contain the real public key (replace the placeholder comments). +## XBPS signing key + +XBPS uses a separate RSA 3072 key. Its private half is stored as the Gitea +repository Actions secret `XBPS_SIGNING_KEY`. The corresponding public key is +published at +`https://git.bongbetic.com/xavierk/Fenris-xbps/raw/branch/stable/keys/fenris-xbps-signing.pub`, +with fingerprint `SHA256:AvPMRlKMikPg75u0iKr8AUkxlfU/Ad4k/S4o2M9W4/w`. +The secret must match that public key. + +The release workflow writes the key to `~/.ssh/id_xbps` to sign the XBPS +package. A requested XBPS publication also uses the key to sign repository +metadata. A final `always()` cleanup removes the runner copy after publication +and release asset upload, including when an earlier step fails. + ## Per-release signing flow Each tagged release performs: **import → verify → sign → delete** on the @@ -76,14 +90,16 @@ git push origin v 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. +clearsigned checksum manifest, validates both, and publishes the release. The +workflow imports `XBPS_SIGNING_KEY` separately and signs the XBPS package. +XBPS publication is optional and also signs repository metadata; it requires +host acceptance and explicit selection during workflow dispatch. ### Step 3: Verify runner cleanup -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. +The workflow's `always()` cleanup removes the GPG key from the runner's keyring +and deletes `~/.ssh/id_xbps`, including after a failed job. Confirm no signing +key remains on the runner after the release job. The Gitea Actions secret remains the approved signing source. Do not copy it to the runner or repository outside the workflow. diff --git a/docs/spec/release-packaging.md b/docs/spec/release-packaging.md index 89bc8f4..ec9982c 100644 --- a/docs/spec/release-packaging.md +++ b/docs/spec/release-packaging.md @@ -45,6 +45,7 @@ - **deb: unsigned.** apt never verifies payload signatures; trust = instance-signed `InRelease` (signed-by keyring) + TLS + Acquire-By-Hash. Manual-download integrity is covered by SHA256SUMS. - **SHA256SUMS: clearsigned** with the packaging key — the trust anchor for manually downloaded release assets, independent of TLS. - **Packaging key:** single dedicated key, RSA 3072, UID `Fenris Packaging `, 2-year expiry, no master/subkey hierarchy. The private key is stored as the repository Actions secret `GPG_PRIVATE_KEY`. The release workflow imports it on the self-hosted runner, verifies it against the in-repo public key, signs the RPM and SHA256SUMS, then deletes the runner's keyring copy in an `always()` cleanup step. The full ceremony is documented in `docs/install/signing-key-ceremony.md`. +- **XBPS key:** separate RSA 3072 key stored as the repository Actions secret `XBPS_SIGNING_KEY`; its public key and fingerprint are published in `Fenris-xbps`. The release workflow uses it for the XBPS package and, when publication is explicitly requested, the repository index. A final `always()` cleanup deletes its runner copy after publication and release asset upload. - **Public key publication:** in-repo `packaging/keys/fenris-packaging.asc` (raw URL doubles as the `.repo` gpgkey target), release notes, docs page. No keyservers — TOFU-over-TLS. - **Rotation (outline):** new key published alongside old; rpm signed with the new key; `fenris.repo` gpgkey lists both URLs (dnf accepts multiple); old key dropped after one release cycle. Procedure details stay in map fog.