GPG Signing Guide¶
All release tags and release commits must be GPG-signed. This document covers setup for maintainers and verification for consumers.
Maintainer Setup¶
1. Generate a GPG key (if you don’t have one)¶
gpg --full-generate-key
# Select: RSA and RSA, 4096 bits, no expiry (or set one and rotate)
# Use the email associated with your GitHub account
2. Configure Git to use your key¶
# List keys to find your key ID
gpg --list-secret-keys --keyid-format long
# Configure git
git config --global user.signingkey <KEY_ID>
git config --global commit.gpgsign true
git config --global tag.gpgSign true
3. Upload your public key to GitHub¶
# Export your public key
gpg --armor --export <KEY_ID>
Paste the output at: GitHub > Settings > SSH and GPG keys > New GPG key
4. (Optional) Publish to a keyserver¶
gpg --keyserver keys.openpgp.org --send-keys <KEY_ID>
Signing a Release Tag¶
git tag -s v0.1.0 -m "Release v0.1.0"
git push origin v0.1.0
The -s flag creates a signed tag. Git will prompt for your GPG passphrase.
Key Rotation¶
When rotating keys:
Generate a new key.
Sign the new key with the old key:
gpg --sign-key <NEW_KEY_ID>.Update GitHub with the new public key.
Announce the rotation in the CHANGELOG for the next release.
Revoke the old key after a transition period:
gpg --gen-revoke <OLD_KEY_ID>.
Troubleshooting¶
“gpg: signing failed: No secret key” – Ensure
user.signingkeymatches a key ingpg --list-secret-keys.“gpg: signing failed: Inappropriate ioctl for device” – Set
export GPG_TTY=$(tty)in your shell profile.macOS pinentry issues – Install
pinentry-mac:brew install pinentry-macand set it in~/.gnupg/gpg-agent.conf.