# Public keys ## Chart signing key `.gitea/workflows/release-chart.yaml` runs `helm package --sign` to produce a `.tgz.prov` file for every chart release, and `charts/aptly/Chart.yaml` carries an `artifacthub.io/signKey` annotation pointing at `chart-signing.asc` in this directory (fingerprint `FC35C0FAA26605C4C21C7BBFBF43884145E5AA94`). The matching private key is stored as the `GPG_PRIVATE_KEY`/`GPG_PASSPHRASE`/`GPG_KEY_ID` secrets in this repo's Gitea settings. **This key must NOT be Ed25519/EdDSA.** Helm's chart signing is built on the deprecated `golang.org/x/crypto/openpgp` library, which cannot read Ed25519 keys at all — signing fails with `Error: private key not found` (or, depending on gpg version, `openpgp: unsupported feature: public key type: 22`). This is a long-standing, unresolved upstream limitation (helm/helm#11634, #31180, #31181), not a configuration mistake — confirmed by reproducing it locally against a throwaway Ed25519 test key before writing this note. Use **RSA** (4096-bit, no expiry is fine for a CI signing key) or a classic ECC curve helm's openpgp fork supports; RSA is the safest choice since it's unambiguously supported. The org's existing "Morlana CI Signing Key" (used by e.g. `bookstack-chart`) is Ed25519 and was tried here first — it does not work for this purpose. It may still be perfectly valid for other things (signing an actual apt repository via `aptly.gpg.signingKey`, which is a completely different code path that does support Ed25519 — see [docs/packaging.md](../docs/packaging.md#gpg) — just not for `helm package --sign`. This repo therefore needs its own, separate, RSA key dedicated to chart-package signing. ### Generating a replacement (e.g. on rotation) Run this yourself (locally, not in CI) so the private key material never has to pass through anything but your own machine and the Gitea secrets store: ```bash gpg --full-generate-key # RSA and RSA (default) # 4096 bit # key does not expire (or a long expiry — a CI signing key you'd have to rotate # on a schedule is more operational overhead than it's worth here) # Name: Aptly Chart Signing Key # Email: something you control, e.g. contact+development@morlana.net gpg --list-secret-keys --with-colons | awk -F: '$1=="sec"{print $5}' # -> the key ID gpg --armor --export > pubkeys/chart-signing.asc gpg --armor --export-secret-keys # -> paste as GPG_PRIVATE_KEY ``` Then, in the repo's Gitea settings, update: - Secret **`GPG_PRIVATE_KEY`** — the armored output of the last command above - Secret **`GPG_PASSPHRASE`** — whatever passphrase you set (empty string if none) - Secret **`GPG_KEY_ID`** — the key ID or fingerprint from `gpg --list-secret-keys` Commit the new `pubkeys/chart-signing.asc` over the old one, and update the fingerprint in the `artifacthub.io/signKey` annotation in `charts/aptly/Chart.yaml`. ### Verifying a downloaded chart ```bash gpg --import pubkeys/chart-signing.asc gpg --export > /tmp/pubring.gpg # legacy binary format — helm can't read pubring.kbx helm verify aptly-.tgz --keyring /tmp/pubring.gpg ```