# Public keys ## Chart signing key (needed, not yet set up) `.gitea/workflows/release-chart.yaml` runs `helm package --sign` to produce a `.tgz.prov` file for every chart release, and `charts/aptly/Chart.yaml` is meant to carry an `artifacthub.io/signKey` annotation pointing at the public half of that key (both are currently commented out / referencing a placeholder — see below). **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 it 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: - 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 `pubkeys/chart-signing.asc`, then uncomment the `artifacthub.io/signKey` block in `charts/aptly/Chart.yaml` with the real fingerprint, and uncomment `pubkeys/chart-signing.asc` in `release-chart.yaml`'s release-assets step. ### Verifying a downloaded chart (once the key exists) ```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 ```