Sign my commits, git!
How to configure git to sign commits with ssh, how to verify them locally, and how to make sure GitHub also verifies the commits with that key.
Git can sign commits with your ssh key instead of using gpg. That’s excellent, because gpg needs extra tooling to be installed on mac. For most things the default configuration you can find on GitHub’s documentation is totally fine.
The short of it is that once you have an ssh key, you need to do the following to get it to work:
$ git config --global gpg.format ssh
$ git config --global user.signingkey ~/.ssh/<MY_KEY>.pub
$ git config --global commit.gpgsign true
This will tell git that your commit signs are going to be ssh format, using the specified ssh public key, and that every commit should be signed automatically.
The assumption here is that you also have your name and email set.
$ git config --global user.name "Jon Doe"
$ git config --global user.email "jondoe@example.org"
The relevant config file so far at ~/.gitconfig
should look like this:
[user]
signingkey = /Users/<user>/.ssh/<MY_KEY>.pub
name = Jon Doe
email = jondoe@example.org
[gpg]
format = ssh
[commit]
gpgsign = true
How do I know it actually signed the commits?
An exercise in confusion
Okay, so you have the above set, you work on some work, add your changes, and commit them. Naturally you want to be sure that your commit is a) signed, and b) signed correctly!
Luckily, there’s a command for that!
$ git log --show-signature
And then that tells you that there’s no signature. At all. In my case it was this:
commit 3edfbd4d8073062582837414325950cfd4ce6942 (HEAD -> main, origin/main)
No signature
Author: Gabor Javorszky <my@email>
Date: Fri Oct 20 00:30:36 2023 +0100
No need to add the scheme to the flydomain method
That No signature does not tell me that it’s signed, but can’t verify the signature, or it’s not been signed at all! This was confusion #1.
To solve this one, the actual command you want to use is this to verify the commits:
$ git verify-commit <sha>
That will give you an error message, which by the way was also part of the output of the git log
from above, but hard to notice. The error is this one:
error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification
The allowed signers file contains the public keys of ssh keys that are allowed to sign commits.
Create it someplace and add your ssh public key you use for the signing key from above:
$ touch ~/.ssh/allowed_signers
$ echo "$(git config --get user.email) namespaces=\"git\" $(cat ~/.ssh/<MY_KEY>.pub)" >> ~/.ssh/allowed_signers
If you then run the verify-commit
command again for your last git sha, you should get a response similar to this:
$ git verify-commit 3edfbd4d
Good "git" signature for <my@email> with ED25519 key SHA256:<sha of public key>
Time to push and celebrate!
GitHub still says unverified
Once you pushed the commit to a branch and look in GitHub, you may still see that it’s unverified, even though you know that it’s signed correctly with the ssh key. There are two more things you need to do to get that green Verified badge on the commit:
- make sure you’ve added the ssh key (the private one) to GitHub to at least the signing key section.
- you also added the email address that you used to push the commit with. The commit may be signed, but if it’s not from an email address that GitHub recognises, then it’s still going to flag it as unverified
To recap
Have the correct configuration. Here’s a sample .gitconfig
file you can edit for yourself:
[user]
signingkey = /Users/<username>/.ssh/<yourkey>.pub
name = Your Name
email = youremail@example.com
[gpg]
format = ssh
[gpg "ssh"]
allowedSignersFile = /Users/<username>/.ssh/allowed_signers
[commit]
gpgsign = true
Make sure the allowed_signers
file exists. You can put this anywhere. Sometimes it’s in ~/.config/git/allowed_signers
, it doesn’t matter. Have your public key’s content in there on a new line.
Make sure your signing ssh key and email are both added to GitHub.
Same documentation elsewhere on the web
In case you want to double check things:
Photo by Signature Pro on Unsplash