Use your GPG key to sign your GitHub commits
Notes on how to create a GPG key and link it to your GitHub account for verified commits. (Win10 with Git Bash, Ubuntu with WSL)
When you link a GPG key to your GitHub account and use it to sign your commits, the commits are marked as “Verified” on the GitHub site.
The GitHub docs on Commit Signature Verification explain the ‘how to do it’ pretty good.
I got mine all set up by going step-by-step through those docs, with a little bit of GPT questioning on the side for details on how to get it working with my particular dev/programming setup.
But why though
“Using GPG, SSH, or S/MIME, you can sign tags and commits locally. These tags or commits are marked as verified on GitHub so other people can be confident that the changes come from a trusted source.”
About Commit Signature Verification (github.com)
That’s basically the main reason to do it.
For me, the main reason is to have that Verified mark showing by my commits, so no one can say I ain’t bona fide verified.
If you have a reason to do it, then maybe these notes will be of some small assistance. (Although it should be noted that these notes are based on how I got it working with my particular setup.)
My particular dev/programming setup
I use Windows 10, the “last ever Windows”™.
For some of my dev/programming work I use Git Bash as the terminal app to do stuff with Git.
Some of the other work is done in whichever terminal app it is that comes with Ubuntu, which I run in Windows via WSL.
Most of the commits are done in one of those terminals. I sometimes use the terminal in VS Code, too.
Here come the notes …
In the notes
1. Do you already have GPG / GPG keys
Ref: “Checking for existing GPG keys”
Run this command in your terminal to find out if you have GPG installed.
gpg --version
If you have GPG installed you’ll get something like this.
If you’re using Git Bash or a Linux then GPG is probably already installed. If it’s not installed then visit the GnuPG download page and see what’s available for your OS.
Run this command in your terminal to find out if you have already created any GPG keys.
gpg --list-secret-keys --keyid-format=long
If you have keys you’ll see a list of them.
2. Make a GPG key to use with GitHub
Ref: Checking for Existing GPG Keys
Make sure the email address associated with your GitHub account is verified. You’ll be using that email address when you create the key.
Run this command in your terminal to make a GPG key.
gpg --full-generate-key
You’ll enter some options. Here’s what I used.
What kind of key: | RSA and RSA (default) |
---|---|
What keysize | 4096 |
How long the key should be valid: | 2y (i.e. 2 years, you could do 2m for 2 months) |
Real name: | [you choose] |
Email address: | [your verified GitHub email] |
Comment: | GitHub GPG key |
Passphrase: | [make up a passphrase, don’t make it too crazy (more about that later)] |
Did it work?
Run this command in your terminal to check for the key.
gpg --list-secret-keys --keyid-format=long
3. Add the GPG key to your GitHub account
Ref: Adding a GPG Key to Your GitHub Account
Keep the terminal open. While logged in to your GitHub account, open this page: https://github.com/settings/keys
Click “New GPG Key”, and give it a name (e.g. HHH GitHub key).
Switch back into the terminal, and run these commands to print the key to the screen so you can copy it to GitHub.
List the keys
gpg --list-secret-keys --keyid-format=long
You should see something like this:
Copy the Key ID. In the screenshot above, the blue highlights the Key ID.
Export the key to copy-paste into GitHub. Using the example Key ID, it’s like this.
gpg --armor --export 3AA5C34371567BD2
The key will be printed to the screen. Highlight and copy the GPG key, beginning with —–BEGIN PGP PUBLIC KEY BLOCK—– and ending with —–END PGP PUBLIC KEY BLOCK—–.
Switch back to GitHub, and paste the key into the text box labelled Key.
Click Add GPG Key.
Now you have a GPG key linked to your GitHub account.
4. Tell your Git install about the key
Ref: Telling Git About Your Signing Key
The next step is using that key to sign your commits.
If you have previously configured Git to use a different key format when signing with --gpg-sign, unset this configuration so the default format of openpgp will be used.
git config --global --unset gpg.format
Run this command in your terminal to tell Git about your signing key. (Use your actual key, of course; this is the example key from before)
git config --global user.signingkey 3AA5C34371567BD2
Now when you commit, you should use git commit -S -m "Commit message".
The -S flag means “Sign the commit”.
You’ll be asked to enter the passphrase for your key every time you commit. If you forget the -S, the commit won’t be signed.
Annoying.
Set Git to sign commits by default by running this command.
git config --global commit.gpgsign true
Now you don’t need to include the -S flag. You’ll still be asked to enter the GPG passphrase every time you commit. (This is why I mentioned that you shouldn’t make your passphrase too crazy.)
Unless?
5. Use gpg-agent to cache your passphrase
Set up gpg-agent to cache your passphrase and you won’t need to enter the passphrase every time you make a commit—just for the first commit in your session.
Check if you have gpg-agent?
Run this command to check if you have gpg-agent installed
gpg-agent -v
If you have gpg-agent installed you’ll get something like this.
(It’s part of GnuPG, it should already be installed.)
Set the cache time
The cache time can be set in the gpg-agent.conf
file.
Use this command to get to your home folder to find the gpg-agent config files.
cd ~/
Look for the .gnupg folder
ls -a | grep gnu
The -a flag means show hidden files/folders, the | sends the list to grep to filter for files/folder names that have “gnu” in them.
You should see .gnupg in the folder list.
Now look for the gpg-agent.conf
file.
ls -a .gnupg
If you can’t see gpg-agent.conf
in that list, create it.
touch .gnupg/gpg-agent.conf
Now edit it.
nano .gnupg/gpg-agent.conf
Add these lines to gpg-agent.conf
# Cache the passphrase for 4 hours
default-cache-ttl 14400
I choose 4 hours (…14400 seconds…) because that should be long enough to cover a reasonable coding session.
Done!
Next time you push a commit, it should show up on GitHub as Verified.
6. Extra: use the GPG key on another device
Say you sometimes work on your desktop, sometimes on your laptop, and you want to use this GPG key on both computers.
Here’s how I got my GPG key into my WSL install. If you’re trying to get yours on to a different computer, you’d export the key and copy it into whichever file sharing method works for you e.g. Syncthing, Dropbox, the old USB stick that lives somewhere on your desk …
Basic steps
- Export the key
- Copy the key to the other device
- Import the key to the key store on that other device
Preps in Ubuntu/WSL
Start it up, get to the home directory, check if GPG is installed. (Same as before)
cd ~/
gpg --version
Type explorer.exe to open the Ubuntu/WSL home directory location in Windows Explorer.
(Call this window #1)
Preps in Git Bash on the Windows side
Open Git Bash, get to the home directory.
cd ~/
Export the GPG key.
gpg --export-secret-keys --armor 3AA5C34371567BD2 > mygpgkey_private.asc
(Use the Key ID that matches your own key instead of 3AA5C34371567BD2)
Type explorer.exe to open the Git Bash home directory in Windows Explorer.
(Call this window #2)
Copy-paste the mygpgkey_private.asc
file from window #2 into window #1.
Import the key
In the Ubuntu terminal, run this command in the home directory to import the key.
gpg --import ./mygpgkey_private.asc
Then tell Git to use that key to sign commits, the same as before.
git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign true
Then – also same as before – set up gpg-agent to cache your passphrase.
TL;DR version
Make a key and export it as text to copy-paste into GitHub.
gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long
gpg --armor --export [key id goes here]
Tell Git about your GPG key and configure it to sign commits by default.
git config --global user.signingkey [key id goes here]
git config --global commit.gpgsign true