Signing commits in github

My company asked us to start signing our commits. Let’s see how we can do that.

Github put together a page to explain the different steps.

On my local machine

Create a GPG key

The first step is to add a GPG key to you github account. You can check if you already have one by going to Settings > SSH and GPG keys. If the field for GPG is empty, then you need to create one. To do so, you need gnupg. On Mac OSX, you can simply install the command line by typing brew install gpg.

When this is installed, you can create a GPG key by typing gpg --full-generate-key. You’ll be prompted with a series of questions, and after that you get a key.

Exporting your key to github

Now you need to export your public key. To do, find the info of your key, by typing

gpg --list-secret-keys --keyid-format LONG

On the row sec, you’ll see rsa4096 if you chose 4,096 bits RSA key, and after that is your key ID. You can next export that key by typing

gpg --armor --export <key_ID> > .gpg/public.key

This will save your public key to a file .gpg/public.key. You can share that file with whoever needs it.

In the case of github, you’ll copy the content of that file into the box provided when you want to add a new GPG key.

Sign your commits

Now that this is done, you add your GPG key to your local git config by doing git config --global user.signingkey <key_ID>. You can then sign your commit by adding the -S argument when doing git commit….. Well, that is if we didn’t break anything. Turns out that homebrew upgraded in the process of installing gpg, and it broke all my symlinks for python3. It actually installed 3.9, which as unversioned symlinks placed in a different folder. So I had to fix all that, and re-install our library.

Now that this works, I still had a few things to do before being able to sign my commits. The first, mandatory step is to create the following environment variable export GPG_TTY=$(tty). Otherwise, you will never get a prompt for the gpg passphrase and your signed commit will fail. Once this is done, you can sign your commit with the argument -S, then enter your GPG passphrase. You can check that a commit was signed by doing

git verify-commit <commit_hash>

If you want to automate all that, just enter the following 2 lines:

git config gpg.program gpg
git config commit.gpgsign true

and you can commit the same way you were doing before (without the -S argument).

Save passphrase of the GPG key

Now I still had to enter my passphrase when signing commits. Which can quickly become annoying. So I followed the steps highlighted here. At a high level, you need to brew install pinentry-mac, then create 2 files, ~/.gnupg/gpg-agent.conf in which you add

# Connects gpg-agent to the OSX keychain via the brew-installed$
# pinentry program from GPGtools. This is the OSX 'magic sauce',$
# allowing the gpg key's passphrase to be stored in the login$
# keychain, enabling automatic key signing.$
pinentry-program /usr/local/bin/pinentry-mac

then ~/.gnupg/gpg.conf where you add

use-agent

On a remote server

Obvioulsy, you don’t need to re-create the key. You can simply modify the global .gitconfig file to add user.name, user.email, user.signingkey.

Then, you also need to add your private key to gpg on the remote server. To do that, you first need to export your private key from your local machine,

gpg --armor --export-secret-keys <key_ID> > ~/.gpg/private.key

Then on the remote server, you add that private key by doing

gpg --import ~/.../private.key

You will be prompted for your GPG passphrase, and that’s it. You can check that you added the GPG key successfully doing

gpg --list-secret-keys --keyid-format LONG

After that, you can sign your commits with the -S option

git commit -S

Note that I didn’t have to set up the environment variable GPG_TTY (even though that environment variable was not defined).

You can automate the signing of commits the way you would do locally.

It looks like we could use pinentry on a unix server. But I haven’t tried yet.

References

This post is pretty good.

[ github  ]