Skip to content
Charlotte Gayton By Charlotte Gayton Apprentice Engineer I
How to sign your git commits

TL;DR The integrity of the software supply chain can be compromised if a trusted person's identity is spoofed and potentially malicious code is committed to a repository. Signing git commits enables you to distinguish between verified and unverified changes made to a GitHub repository by using cryptographic keys to attest identity. This blog post walks you through the steps to enable this feature.

Why sign Git commits?

When pushing commits to GitHub, you have to provide both a username and an email address that represents you when committing to a repository. Whether this is your actual GitHub account or not, GitHub doesn't know the difference. You can easily overwrite these details set up on your local computer using:

$ git config --global user.name "<Name>"
$ git config --global user.email "<Email Address>"

The reason behind being able to do this is so that it's possible to protect repositories on other channels, it doesn't have to carry all the data of the old accounts accounting for the previous commits. For example if someone were to delete an account, what would happen to the commit information.

If anyone can use any email address and any name, then how do you know who is really committing to your repositories? If someone is able to push a change with malicious content to a repository under a name of a regular contributor, the chances are high that the change could be missed and not questioned.

By signing your commits, other contributors can see, using the verification button that it was you committing, and not someone pretending to be you. When you have your key set up in Github, there is a verification button that will attest that it is really you committing. Below are the steps to help you get a GPG key set up with Github.

An example of when there was nearly a massive malware attack was discovered by Stephan Lacy on Twitter, it is written about here which explains how the attacker was using spoofing of real people's Github accounts to commit malicious code to repositories, thousands of repos were hit by this.

To prove that you are the committer on git we can use GNU Privacy Guard (GnuPG). GnupG is a free tool which allows you to encrypt and sign your data using keys. It can be freely used and is distributed under the terms of the GNU General Public License. GnuPG is an implementation of the OpenPGP standard which is an email encryption standard. You can use GnuPG to create a GPG keys. GPG keys are used to verify that the origin of data or communication is genuine and then creates a digital signature. They create a key pair, a public key and a private key, that can be used with Github for the encryption and signing commits.

In GitHub under Settings then SSH and GPG keys you'll see a setting called 'Vigilant mode' which flags unsigned commits as unverified. This means you can clearly see who is making verified commits and who isn't. If your whole team sign their commits, then a commit that isn't signed can be easily spotted amongst them and red flags could be raised.

There are a few different methods to sign keys. The first, by using GPG keys, the oldest and most commonly used method. There are tools currently being developed to make this an easier process, without the need for GPG or SSH keys, like the project gitsign: a feature of the project sigstore. Whilst this method reduces the need to have keys to sign commits, it is not yet recognised by GitHub as a trusted verification, so commits won't show as verified.

Recently, Git released a new feature allowing you to sign your commits using your SSH key, which has shown to be popular as more people have SSH keys than GPG keys. There were many problems when setting up GPG keys and getting them to run inside an IDE such as Visual Studio Code. It is possible, however it is much easier to use GPG keys as they are much simpler to set up and use.

Listed below is the manual method to setting up your own GPG keys. Here is a tool to guide you through the process that will make creating and setting up GPG keys much quicker.

Using GPG Keys - Helper tool method

You can download the tool from GitHub repository Endjin.GitSignCommits here. To run the file, clone the repository locally and open up a PowerShell terminal.

Then run the following command:

./gitsigning.sh

The script will then take you through each command. Where you need to input information there will be a prompt and if specific values are needed, these will be specified in green.

Using GPG Keys - Manually installing

Step 1: Installing GPG

Firstly, you have to install GPG if it is not installed already (gpg --version):

  • If you have Git BASH then it should already be installed
  • Head to GnuPG to install

Step 2: Check for existing keys

Important note: Create your keys inside Git bash, otherwise there could be trouble with the PATHs to your keys when running the command outside Git Bash.

Use the command below to check to see if you have any existing keys:

$ gpg --list-secret-keys --keyid-format=long

If you have existing keys and you want to use one to sign commits then display the public key using the command below and then you can skip to part 5: (Note: The long key at the end is an example one that you need to sub out for your own)

$ gpg --armor --export HZTX5CQ0Y3WCAI7V

If you don't have any keys run the command below:

$ gpg --full-generate-key
  • Select 1 for the first option
  • For key size enter 4096
  • For how long the key should last should be 0
  • And then verify by entering y

Then you need to add your:

  • Name
  • Email address (the one that you have registered to sign into GitHub)
  • A comment (optional)
  • Enter o to confirm

It will then ask you for a passphrase to protect the key. Make sure to remember it! It will ask you for this every time you commit.

Step 3: Seeing the keys

Now that the keys are created we can see them using:

$ gpg --list-secret-keys --keyid-format=long

And the output will look like this:

$ gpg --list-secret-keys --keyid-format=long
/Users/hubot/.gnupg/secring.gpg
------------------------------------
sec   4096R/HZTX5CQ0Y3WCAI7V 2016-06-13 [expires: 2017-03-10]
uid                          Test 
ssb   4096R/KATQK38JUIHHBH29 2016-06-13

Step 4: Exporting the keys

Then using your GPG Key ID (which in the example above is HZTX5CQ0Y3WCAI7V) paste it into this line:

$ gpg --armor --export HZTX5CQ0Y3WCAI7V 

Or you could save it to a file and read it from there instead:

$ gpg --export --armor HZTX5CQ0Y3WCAI7V > ./gpg-key.pub

You can back up your secret keys:

$ gpg --export-secret-keys --armor NIDC7OOPDJ84JIYDMS7QYK8VPJPJNKMWVFS5N1E0 > ./gpg-key.asc

Step 5: Linking to GitHub

Now we need to link it to Github. To do this we need to use the result of the of the armor command. Copy your GPG key, beginning with -----BEGIN PGP PUBLIC KEY BLOCK----- and ending with -----END PGP PUBLIC KEY BLOCK-----

Go to settings in Github and then SSH and GPG Keys and create a new GPG Key. Insert the GPG key, including the lines that show the beginning and the end of the key block.

Now we need to tell Git about the GPG signing key. Using your own GPG key ID instead of the example one, run the line below

$ git config --global user.signingkey HZTX5CQ0Y3WCAI7V

Step 6: Enabling Git sign

To enable Git signing:

git config --global commit.gpgsign true

Step 7: Signing a commit

To sign a commit, you git commit as usual but it should show up with the window to enter in your passphrase. It also should work if committing using the buttons within an IDE (for example VS Code).

Troubleshooting

If you run into a problem that looks something like this:

gpg: skipped "HZTX5CQ0Y3WCAI7V": No secret key
gpg: signing failed: No secret key
error: gpg failed to sign the data
fatal: failed to write commit object

If this is the case, you may need to recreate your key in Git Bash, as it can't find the path to your key.

You can check if GPG is in your PATH by going to environment variables and checking if it's in your system variables path. If not then add C:\Program Files\GnuPG as it may not be able to find your GPG program.

If you aren't going to be developing in a dev container you can just point the .config file in your user files point straight to the gpg folder, e.g:

git config --global gpg.program "/c/Program Files (x86)/GnuPG/bin/gpg.exe"

Charlotte Gayton

Apprentice Engineer I

Charlotte Gayton

Charlotte is seconded to endjin for her Industrial Placement year, as part of her BEng in Computer Science at the University of York. She was part of the summer 2021 internship cohort, and worked on creating a synthetic customer data generation tool to create statistically accurate "fake" data which could be used to create large volumes of realistic data for testing scenarios for endjin's customers.

During her year-long placement at endjin, Charlotte is going to focus on the adoption and roll out of the OpenChain specification (ISO 5230) across endjin's open source projects.