Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Signing and Verifying Git Commits on the Command Line and GitHub

blog/cards/signing-and-verifying-git-commits-on-the-command-line-and-github.jpg

We'll go over signing commits and tags with a GPG key along with sending and receiving GPG public keys to a Keyserver for verification.

Quick Jump: Going Over Everything | Cheatsheet

There’s really no downside to signing your git commits and once you have a GPG key pair created you can auto-sign your commits and tags with a few git config options.

Going Over Everything

Did you get a gpg failed to sign the data error while following along?

If you follow along you might encounter a “gpg failed to sign the data” error at 1:34 in the video if your configured git email and gpg key email are not the same. This will be addressed at 5:44 in the video when we explicitly configure git’s signing key.

It happened to work for me on video because in my case (and probably yours too), both email address values are the same. At the time of recording the video I wasn’t aware git’s signing key defaults to your configured git email.

Timestamps

  • 0:46 – Creating a dummy git repo to work with
  • 1:30 – Creating a signed git commit and verifying it
  • 2:09 – Why it’s worth it to sign your commits
  • 3:07 – Creating lightweight, annotated and signed git tags
  • 5:15 – Auto-signing your commits and tags with a few .gitconfig options
  • 7:05 – Auto-signing tags requires git 2.23+ or newer
  • 7:45 – Demonstrating auto-signing for commits and tags
  • 8:41 – Adding your GPG public key to your GitHub account to get verified
  • 10:44 – Verifying git commits from others on the command line
  • 11:40 – Searching a GPG Keyserver for a specific user’s key
  • 12:50 – Importing another user’s public GPG key straight from a Keyserver
  • 14:24 – Deleting another user’s public GPG key from your keyring
  • 15:10 – Sending your public GPG key to a Keyserver
  • 16:21 – Importing another user’s GPG public key without a Keyserver
  • 17:31 – Only merging in branches that have commits with verified signatures
  • 19:26 – Recap and a quick tooltip for verifying signatures on GitHub directly

Cheatsheet

Here’s a reference to the commands run on video:

Unsigned commit
git commit -m "Unsigned commit"
git log
Signed commit
# If your git and gpg key email addresses are different this will fail until
# you configure your git signingkey (covered on video).
git commit -S -m "Signed commit"
git log --show-signature
Unsigned tag
git tag lightweight-tag
git show lightweight-tag

git tag -am "" unsigned-annotated-tag
git show unsigned-annotated-tag
Signed tag
git tag -sm "" signed-tag
git show signed-tag
Overriding the auto-sign config options
git commit --no-gpg-sign -m "Unsigned commit"
git tag --no-sign unsigned-lightweight-tag
Importing another user’s public GPG key from a Keyserver

As of mid 2021 the default gpg key server was taken offline, there’s a few we can choose as an alternative based on https://en.wikipedia.org/wiki/Key_server_(cryptographic). I’ve been using keyserver.ubuntu.com as my new default. It’s updated pretty quickly and is unlikely to go away.

We can either put --keyserver keyserver.ubuntu.com in every command that accesses the key server or we can modify our ~/.gnupg/gpg.conf by searching for the uncommented keyserver hkp://keys.gnupg.net line and replacing it with keyserver hkp://keyserver.ubuntu.com.

I’ve gone with the config approach and recommend doing the same. This way all of the commands below will continue to work without modifying them and you don’t need to remember to use a custom server every time you use gpg.

Changing the config file is effective immediately. You don’t need to restart the agent.

gpg --search-keys nick.janetakis@gmail.com
gpg --recv-keys D2AD01A3FC57C925

# Removing the key afterwards if you want to.
gpg --delete-keys nick.janetakis@gmail.com
Send your public GPG key to a Keyserver
gpg --list-keys --keyid-format LONG <your GPG email address>
gpg --send-keys <your public GPG key id from above>

This is useful to do if you want to exchange keys with someone and you should do this every time you change your key, such as updating its expiration date.

Importing another user’s public GPG key from a file
# Have them run this to export their public GPG key and send it to you.
gpg --export --armor --out theirname.gpg.pub <their GPG email address>

# Now you can import it like this.
gpg --import theirname.gpg.pub
Verifying signatures when merging a branch with git
# It's expected that you already modified your .gitconfig to auto-sign commits.
git checkout -b feaure-something
touch somefile && git add -A && git commit -m "Hello world"
git checkout master
git merge --verify-signatures feature-something

On GitHub you can also go-to a repo’s settings -> branches -> branch protection rules and add a rule to require signed commits on 1 or more branches. This way you can enforce this at the pull request level on GitHub.

Keep in mind if you do the above on GitHub then you may have less contributors because there is a barrier to entry to create a GPG key pair. Lots of larger projects do this. Personally I don’t impose this requirements on most of my open source projects, but I do sign all of my commits in either case.

Are you going to be signing your git commits? Let me know below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments