I wanted to sign my commits for some time and tried it a year ago and it didn’t really work.

… until 23rd of August 2022 when GitHub announced that they will show verified flag for SSH signed commits

Today I re-tried - following a GitHub guide over several articles they have and have succeeded.

The steps

TL;DR;

I started with their article about “Signing commits”, which led me to “Telling Git about your SSH key”, but then I had to follow the link at the top of the section to “Generating a new SSH key and adding it to the ssh-agent”, which led me to follow “Adding a new SSH key to your GitHub account” to add a new SSH signing key to my account. Finally I went back to the first article where I created a temporary repository, where I signed a few commits and confirmed the GitHub was showing the Verified flag.

Now the steps I took…

1. First thing was to create a new Ed25519 signature:

ssh-keygen -t ed25519 -C "your_email@your_domain.com.au"

At the prompts that followed I picked the default file name and location since I had no old Ed25519 key pairs, then put in a pass phrase I wanted, since I was going to include it in my macOS keychain.

The ssh-keygen command has generated two new files: ~/.ssh/id_ed25519 and ~/.ssh/id_ed25519.pub - a private and public key pair.

2. Configuring SSH to load keys into the ssh-agent when communicating with GitHub

ASIDE: The ssh-agent manages your SSH keys and remembers your pass phrase.

Since the main purpose of signing my commits with an SSH key was to have a verified flag on GitHub - I had to add a GitHub-related config to my SSH config file at ~/.ssh/config.

Host *.github.com
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519

ASIDE: if you don’t have the ~/.ssh/config file - create it (I believe it should have 0644 permissions, but I think the ssh agent ensures it does automatically).

I use UseKeychain yes, because I’m going to store the password in my keychain.

3. Adding the SSH key to ssh-agent

Since I wanted to add my pass phrase to my macOS keychain I did:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

ASIDE: If you get an error when you run ssh-add you’ll have to start the ssh-agent, which is trivially done via the command: eval "$(ssh-agent -s)"

4. Adding my public key to GitHub

Now I had to add the .pub file to my GitHub account:

pbcopy < ~/.ssh/id_ed25519.pub

ASIDE: pbcopy is a built-in macOS utility that simply copies the contents of an input into the OS pasteboard (aka clipboard).

I opened github.com in a web browser and visited my account’s settings, where under SSH and GPG keys I’ve added the new public signing key with a descriptive name of my choosing.

5. Telling git about the SSH key

Finally I had to tell git to use the new key to sign my commits.

Apparently there is an important decision at this time - whether to sign all your commits to all repositories OR just particular repository (or several).

I chose to go global, but if you do want to do it for a particular repo - cd into it and use --local instead of my --global below.

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub

Since I want to sign all my commits and didn’t want to always type git commit -S ... I added the oddly named config commit.gpgSign:

git config --global commit.gpgSign true

Verifying SSH signed commits

I found that git verify-commit HEAD produced an error:

error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification

Then git log --show-signature produced a No signature line.

Turns out that in comparisson to GPG - the SSH keys have no “web of trust”, thus we have to take care of that ourselves!

Following the gude at Danilo’s blog I created a file for holding allowed signers:

mkdir -p ~/.config/git/
touch ~/.config/git/allowed_signers
chmod 0644 ~/.config/git/allowed_signers

Then I listed the currently active ssh keys in the ssh-agent:

> ssh-add -L
ssh-ed25519 AAAAC3NzaC1...<snip>

Then I added the ed25519 key to that file, but prepending it with my email:

aviolito@gmail.com ssh-ed25519 AAAAC3NzaC1...<snip>

Finally I configured the gpg.ssh.allowedSignersFile config to:

git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers

Now when I do run git verify-commit HEAD I get:

Good "git" signature with ED25519 key SHA256:1ZPNqvANfoJDEaLhELklI64awpfADJ/+dMXNXBiqWtA

(git log --show-signature shows the same for every commit it lists).


(this commit is my first signed one)