SSH Signing

Signing Commits with an SSH Key Instead

Since Git 2.34 1,932 , gpg.format ssh signs with ssh-keygen -Y sign and the SSH key you already use to push, with no keyring to manage (OpenSSH 8.8 23,707 or later). BookNest's repository has used it for tags since Signed Tags. Sam now signs every commit, and commits the list of trusted keys so every clone verifies against the same one:

Signing every commit with SSH and storing the allowed signers in the repositoryShell
echo "sam@example.com $(cat ~/.ssh/id_ed25519.pub)" > .allowed_signers
git config set gpg.ssh.allowedSignersFile .allowed_signers
git config set commit.gpgSign true
git add .allowed_signers && git commit -qm "Trust Sam's SSH signing key"
git cat-file -p HEAD
Output
→ lint-staged could not find any staged files matching configured tasks.
tree 216c965113136b29838f9aaab32f0e54c332267b
parent 69a974b1ca33b5dbe762c0880f976a566ba45c72
author Sam Rivera <sam@example.com> 1790332500 +0800
committer Sam Rivera <sam@example.com> 1790332500 +0800
gpgsig -----BEGIN SSH SIGNATURE-----
 U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgPJTN9njcSnkeAKyMFFJRenXFHN
...
 -----END SSH SIGNATURE-----
Trust Sam's SSH signing key

Whatever the format, the signature is a gpgsig header inside the commit object (16). Git signs the commit's text without that header, then inserts it, so the hash covers the signature too. An Ed25519 SSH signature carries no timestamp and is deterministic: the same commit always gets the same hash.

How Git signs a commit and checks the signature
How Git signs a commit and checks the signature

.allowed_signers holds one line per key: email addresses, options, then the public key. A relative gpg.ssh.allowedSignersFile is resolved from the top of the working tree, as Git's documentation suggests for repositories that require signed commits.