3.1 KiB
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 — 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:
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 <key-id> > pubkeys/chart-signing.asc
gpg --armor --export-secret-keys <key-id> # -> 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 fromgpg --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
gpg --import pubkeys/chart-signing.asc
gpg --export > /tmp/pubring.gpg # legacy binary format — helm can't read pubring.kbx
helm verify aptly-<version>.tgz --keyring /tmp/pubring.gpg