Yesterday Git version 2.34.0 was released. An interesting part of the release notes is support for signing commits and tags not with a PGP key, but with an SSH key.
In addition to GnuPG, ssh public crypto can be used for object and push-cert signing. Note that this feature cannot be used with ssh-keygen from OpenSSH 8.7, whose support for it is broken. Avoid using it unless you update to OpenSSH 8.8.
The ability for signing arbitrary data with SSH was added in 2019 with OpenSSH 8.0. However, as noted in the release announcement above, you should use at least OpenSSH 8.8 for this feature to work without issues.
Signing Git Commits with SSH
SSH signatures in Git use the same mechanism as PGP signatures, thus you
can keep using the
-S flag for commits and the
-s flag for tags.
However, you need to change the signature format.
To switch the signature format to SSH (either for your current repo or globally):
git config [--global] gpg.format ssh
Additionally, you need to tell Git which SSH key to use for signing. Simply use
your public key as the configuration value for
git config [--global] user.signingKey 'ssh-ed25519 AAAAC3(...)qiXsb user@host'
Now you can create signed commits:
git commit -S -m 'Create a signed commit'
If you want to force all future commits and tags to be signed:
git config [--global] commit.gpgsign true
git config [--global] tag.gpgsign true
Verifying Commit Signatures with SSH
To show and validate signatures, pass
git log or
When looking at the resulting commit information, you might notice an error message:
error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification
The reason why this signature cannot be verified is because Git does not know which SSH keys to trust. In contrast to PGP, there is no "web of trust" where keys can be signed. Instead, you manage a list of trusted keys on your computer, the "allowed signers file" which works very similar to the "authorized keys file" used by SSH.
First, create a file somewhere on your computer (I'd recommend
~/.config/git/allowed_signers). Then, add an entry for your own signing key,
so that your own commits will be trusted by Git. In its simplest form, every
line starts with an e-mail address (the e-mail used to create the commit)
followed a public key. For example, for my own key:
email@example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE5bRSsXZ5HnUkMMEWS5/jxEQaqbLb+i6xjMyC6qiXsb danilo@jabba
(If you want to know more about the format of this file, check out the "ALLOWED
SIGNERS" section in
man 1 ssh-keygen. There are more options you can use, for
example key expiration.)
Next, tell Git about this file.
git config [--global] gpg.ssh.allowedSignersFile "$HOME/.config/git/allowed_signers"
Now Git/SSH know whom to trust, and can verify the signature: