Skip to content

Instantly share code, notes, and snippets.

@nicolasrouanne
Last active June 2, 2021 19:25
Show Gist options
  • Save nicolasrouanne/78352e08b89be27a526d51fb00a8ac6e to your computer and use it in GitHub Desktop.
Save nicolasrouanne/78352e08b89be27a526d51fb00a8ac6e to your computer and use it in GitHub Desktop.
Set up GPG commit signing for Github

Signing Commits

Signing commits is a way to authenticate your commits, since anybody can pretend using your email when pushing to a repository (as long as one has access to it)

Initial set up

Create or import a GPG Key

Create a GPG Key

First you need to create a GPG Key Pair. Follow Github guide explaining each step: Generating a new GPG Key

Do not forget to add the passphrase to your favorite password manager (1Password for instance 🔒👌)

Add it to Github

Let GitHub know the GPG key you just created is your identity. Copy and upload the public GPG key to your Github account.

Import a GPG Key

If you already have a GPG Key you're using to sign commits, it might be simpler to keep using the same instead of recreating one. For instance if you're using a new development computer (and your old one hasn't been compromised), you can export your GPG keys from the old computer and import them into the new one.

# export the keys from the old machine
gpg --export ${ID} > public.key
gpg --export-secret-key ${ID} > private.key

# import the keys on the new machine
gpg --import public.key
gpg --import private.key

# check that the keys have been correctly imported
gpg --list-secret-keys --keyid-format LONG

Setting trust for your imported keys

Since you imported a key, GPG has no idea wether it should trust the key you just imported. So trust level is unknown. If you're the one that created the key, and you know it's trustworthy, you can change the trust level.

# after import trust level is set to `unknown`
gpg --list-secret-keys --keyid-format LONG                          
/Users/nicolasrouanne/.gnupg/pubring.kbx
----------------------------------------
sec   rsa4096/EFB02CA2C65936A9 2019-02-26 [SC]
      3F4A82CA73C97C1465EC3B39EFB02CA2C65936A9
uid                 [ unknown] Nicolas Rouanne <nico.rouanne@gmail.com>
ssb   rsa4096/860C5F4335643962 2019-02-26 [E]

Use gpg --edit-key key to change the trust level

gpg --edit-key EFB02CA2C65936A9 
> trust
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu
5
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

sec  rsa4096/EFB02CA2C65936A9
     created: 2019-02-26  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa4096/860C5F4335643962
     created: 2019-02-26  expires: never       usage: E   
[ultimate] (1). Nicolas Rouanne <nico.rouanne@gmail.com>

The trust level is now set to ultimate (which should only be used for your own keys).

Tell Git

Git on your local development machine needs to know about your GPG identity. Follow the steps in Telling Git about your GPG key

List GPG keys for which you have both public and private keys (private key is required for signing commits)

gpg --list-secret-keys --keyid-format LONG
/Users/nicolasrouanne/.gnupg/pubring.kbx
----------------------------------------
sec   rsa4096/EFB02CA2C65936A9 2019-02-26 [SC]
      3F4A82CA73C97C1465EC3B39EFB02CA2C65936A9
uid                 [ultimate] Nicolas Rouanne <nico.rouanne@gmail.com>
ssb   rsa4096/860C5F4335643962 2019-02-26 [E]

Set your GPG signing key by adding it to your Git config

git config --global user.signingkey EFB02CA2C65936A9

Add the GPG key to your .zshrc file

echo 'export GPG_TTY=$(tty)' >> ~/.zshrc

Test

You should now be able to sign commits. Test that out by creating your first signed commit:

# make some change
$ touch example.txt
# add them to the staged area
$ git add .
# create your first **signed** commit
$ git commit -S -m your commit message

You should see a successfully signed commit 🎉

git log --show-signature
commit 20e07b44bb28d7bbf23f6e248235e10891099e85
gpg: Signature made Wed  2 Jun 14:16:04 2021 CEST
gpg:                using RSA key 3F4A82CA73C97C1465EC3B39EFB02CA2C65936A9
gpg: Good signature from "Nicolas Rouanne <nico.rouanne@gmail.com>" [ultimate]
Author: Nicolas Rouanne <nico.rouanne@gmail.com>
Date:   Wed Jun 2 14:16:02 2021 +0200

Going further

Saving your GPG passphrase

Each time you commit Git is going to ask for your GPG passphrase. This can quickly become annoying

I'm using ohmyzsh, so this can be done using gpg-agent and keychain plugins.

plugins=(... gpg-agent keychain)

Then you need to install pinentry-mac otherwise you'll be prompted for your passphrase each time the cache from the gpg-agent expires. See detailed instructions or follow these quick steps:

# install `pinentry-mac`
brew install pinentry-mac

# add the path to pinentry in `gpg-agent`
echo 'pinentry-program /opt/homebrew/bin/pinentry-mac' >> ~/.gnupg/gpg-agent.conf

Now git commit -S will ask your password and you can save it to MacOS keychain.

Signing commits in VS Code

You need to set up the git.enableCommitSigning config value in settings.json:

"git.enableCommitSigning": true

This can be done more easily by typing "gpg" in the settings interface

Screenshot 2021-06-02 at 15 14 21

It basically tells VS Code to add the -S flag when comitting. Then it relies on gpg-agent and keychain, the same way the terminal does.

Litterature

Make sure you followed all the previous steps, otherwise, here is some literature:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment