Backing up signing keys without creating a leak Jump to heading
Most leaked signing keys were not stolen; they were backed up. A dotfiles repository pushed to a public forge with ~/.gnupg inside it. A laptop backup synced to a consumer cloud folder. A key pasted into a chat message to a colleague “just for the migration”. Every copy of a private key is another place it can escape from, so a backup is a deliberate trade: you accept more exposure in exchange for not losing the key. For many signing keys, that trade is not worth making at all. This page helps you decide which keys to back up, and how to do it for the ones that warrant it. It is part of protecting and rotating signing keys.
When to use this approach Jump to heading
- You are setting up signing and wondering whether to back up the key.
- You suspect a signing key already lives in a backup, dotfiles repository or sync folder.
- You maintain a GPG identity that is published and trusted, which cannot be cheaply replaced.
- You hold a release-signing key whose loss would break users’ verification of future releases.
Step 1 — Decide whether the key needs a backup at all Jump to heading
The question is not “would losing it be annoying” but “would replacing it be costly”. A per-device SSH signing key is replaced in five minutes: generate a new one, register it, update the trust file. A GPG primary that others have certified, or a project’s release key, is expensive to replace because every verifier must learn the new one.
Write the decision down. A key that is deliberately not backed up should be documented as such, so that losing it triggers “generate a new one” rather than a frantic search for a backup that never existed.
Step 2 — Find copies that already exist Jump to heading
Before creating a proper backup, find improper ones. Search the places keys typically end up.
# Private key headers in home directory dotfile repositories
grep -rlE 'BEGIN (OPENSSH|PGP) PRIVATE KEY' ~/dotfiles ~/src 2>/dev/null
# Keys tracked in any Git repository you have checked out
for r in $(find ~/src -name .git -type d -prune 2>/dev/null); do
git -C "${r%/.git}" ls-files | grep -E '\.gnupg/|id_.*(_signing)?$|\.asc$' | sed "s|^|${r%/.git}: |"
done
# Cloud sync folders
find ~/Dropbox ~/OneDrive "~/Google Drive" -name 'id_*' -o -name '*.asc' -o -name 'secring*' 2>/dev/null Anything found in a repository that was ever pushed should be treated as leaked: rotate the key, then clean up, following responding to a leaked credential.
Step 3 — Exclude key material from automatic backups Jump to heading
Machine backups are useful for everything except keys. Exclude the key directories so the next restore does not quietly put an old key on a new machine, and so the backup provider never holds it.
# Common exclusions — adapt to your backup tool's syntax
cat >> ~/.backup-exclude <<'EOF'
.gnupg/private-keys-v1.d/
.ssh/id_*
!.ssh/id_*.pub
EOF
# Keep keys out of dotfiles repos for good
printf '.gnupg/\n.ssh/id_*\n!.ssh/*.pub\n' >> ~/dotfiles/.gitignore Step 4 — Back up the keys that deserve it, encrypted and offline Jump to heading
For a key that warrants a backup, export it, encrypt it with a strong passphrase separate from the key’s own, and store two copies on media that is not normally connected.
umask 077
# GPG: full secret export
gpg --armor --export-secret-keys "$FPR" > key.asc
# SSH release key, if you have one
cp ~/.ssh/id_ed25519_release key-ssh
# Encrypt the bundle symmetrically with a separate passphrase
tar cf - key.asc key-ssh | gpg --symmetric --cipher-algo AES256 -o signing-backup-$(date +%F).tar.gpg
shred -u key.asc key-ssh
sha256sum signing-backup-*.tar.gpg > signing-backup.sha256 The separate passphrase matters: if the backup and the key share one, compromising either compromises both. Store the backup passphrase in your organisation’s secrets vault or a sealed envelope, not alongside the media.
⚠️ SAFETY WARNING:
shred -udeletes the plaintext exports permanently. Only run it after confirming the encrypted bundle decrypts:gpg -d signing-backup-*.tar.gpg | tar tf -should list both files. On SSDs and copy-on-write filesystemsshredcannot guarantee overwriting, so prefer creating exports on a RAM-backed directory such as/dev/shm, which never touches disk.
Step 5 — Test the restore once a year Jump to heading
A backup you have never restored is a hypothesis. Once a year — conveniently, when you renew expiry — restore into an empty keyring on an offline machine and sign something.
cd "$(mktemp -d)"
gpg -d /media/offline/signing-backup-*.tar.gpg | tar xf -
GNUPGHOME=$(mktemp -d) sh -c 'gpg --import key.asc && echo test | gpg --clearsign >/dev/null && echo restore ok'
cd / && rm -rf "$OLDPWD" Validation checklist Jump to heading
Frequently Asked Questions Jump to heading
Can a hardware key be backed up? Jump to heading
Keys generated on a hardware token usually cannot be exported, by design. If you need a backup, generate the key off-device, back it up, and then load it onto the token — accepting that it existed in software once. Otherwise keep two tokens enrolled, so losing one does not lose the ability to sign.
Is a password manager a reasonable backup location? Jump to heading
For a personal key, a password manager with strong account security is far better than a dotfiles repository or sync folder. For a release key, prefer offline media under organisational control, because the account security of one person’s password manager becomes the project’s security.
What should I do with old backups of rotated keys? Jump to heading
Destroy them unless you need the old key to sign revocations or historical attestations. An old key in a forgotten backup is still a key someone could use to sign things dated in the past.
Related Jump to heading
- Protecting & Rotating Signing Keys — the parent topic.
- Keeping a GPG Primary Key Offline — the most common key that does warrant a backup.
- Using a Separate Signing Key per Device — the setup that makes backups unnecessary.
- Choosing a Secret Scanner for Git History — catching keys that were committed anyway.