Keys to the Commit Castle

Sign your git commits when your Yubikey is installed in your machine.

Keys to the Commit Castle
Photo by Marvin Meyer / Unsplash

Cryptographically signing your git commits prevents another person from making commits to a repository in your name. I have a couple of examples where someone has committed code in my name (never maliciously), and it makes me uncomfortable. So, I've decided to sign all of my commits to git using a private/public keypair. I use a Yubikey for this, which is a piece of hardware that allows you, with a PIN, to perform signing, authentication, and encryption operations without being able to read private keys from the device (thus preventing someone from stealing your private keys).

Setting up your Yubikey is outside the scope of this post, but DrDuh has a great guide on github on how to set up a brand new Yubikey and start using it. What this post is about is signing git commits, conditionally, depending on whether your Yubikey is installed in your machine. Consider the following: You've set up a Yubikey with a set of signing, encryption, and authentication keys. You've also removed those private keys from your hard drive to prevent disclousure, as is recommended in DrDuh's guide. Let's suppose you have a computer at work and a laptop at home. Suppose you want to be able to sign your commits on each of your computers. This is a pretty easy thing to accomplish, assuming you have the configuration set up. All you have to do is move your Yubikey from one computer to another, right?

Well, now let's say you left your Yubikey at work over the weekend (hopefully in a locked drawer and not physically in your machine where anyone could walk off with it). But, you want to work on work at home on your laptop. You go to commit your changes, and it asks you to insert your Yubikey. The following is a small script that checks to see if your Yubikey is present on the current machine, and if so, will sign your commits by aliasing git commit to git commit -S. If the key is not present, then it will simply use git commit. This is useful in a situation where you want to sign most of your commits, but it's ok if you don't sign some commits.

What this script does is check for the signing key's identifier. If it finds it, it will respond with the word true. If the signing key is not found, then it will respond with the word false. Take this script and place it into some location on your machine. Make it executable using chmod a+x <script path>.

Now, we're going to use a bash function to alias git. Since git uses the subcommand pattern, we can't just use alias in the same way we would if we wanted to add a flag to an ls command, for instance. Take the following and place it at the end of your .bashrc or .zshrc initialization file:

Use source to read the file into your current shell: source ~/.bashrc, and voila! You now will be able to conditionally sign commits. Don't forget to add the ID of your signing key to your global gitconfig using:

git config --global user.signingkey $KEYID

If you don't have the key id anymore, you can retrieve it using:

gpg --list-secret-keys --keyid-format=0xshort

You're looking for the line that says something like:

sec#  rsa4096/0xABCDEF01 2023-06-20 [C]

This 0xABCDEF01 is your key id.

Happy coding!