Automating Git Commit Signing
A few days ago, I wrote about signing your commits so they'll show up on GitHub as verified. After that process is in place, every commit requires the passphrase associated with the signing key to be re-entered. This gets old quickly if you're committing frequently (which you should). Fortunately, there's a way to cache the passphrase to make this much less burdensome. Unfortunately, the cache only lasts 10 minutes. Fortunately, there's a way to change the default.
(For Linux users, you'll need to read up on gpg-agent; I have not done that as I develop primarily on Windows.)
The program to replace git's standard
gpg program on Windows is Gpg4win. Download and install it, making sure to include the Kleopatra utility. This program can also generate commit-signing signatures (see this excellent tutorial) but if you already have some established with the command-line
gpg tool, you'll want to import those so you don't have to generate new ones and replace the ones already up on your GitHub account. And, of course, to import them, they must first be exported, so let's walk through how to do that.
Remember, the signatures are made up of both private and public keys. We previously exported (to the screen) and uploaded (copied/pasted) the public key to GitHub. Now we need to export the private key but instead of just showing on the screen, we need to save it to a file. The process starts the same by first listing the keys we have:
gpg --list-secret-keys --keyid-format=long
In the first line, the hex number after the slash is the key identifier you will use in the next step. In the screenshot above, that identifier is
D792C422260CFA4C. Use that to export the private key:
gpg --export-secret-key -a D792C422260CFA4C > ~/.gnupg/D792C422260CFA4C-private.asc
-a parameter tells
gpg to export the key in ASCII format. We put it in the user's
.gnupg folder as that's out of the way but associated with other key stuff. And we use
.asc for the extension as that's what Gpg4Win will look for by default.
Now switch to Kleopatra and click the Import button and go find that file. It should either import it immediately or ask for a passphrase.
With the signing key now handled by Kleopatra, we need to tell
git to switch to the version of
gpg used by Gpg4Win and Kleopatra:
gpg config --global gpg.program /c/Program\ Files\ \(x86\)/GnuPG/bin/gpg.exe
(Adjust the path in the line above if you need to.)
The next time you commit, the pop-up window that asks for your passphrase will look different because it's part of Gpg4Win instead of the pinentry-qt program that comes with git. And it will be cached for 10 minutes. If you save all your commits for the end of the day and do them at once, that'll be fine for you. But I commit frequently throughout the day or often have interruptions and there are usually large time spans between commits so a cached passphrase time of only 10 minutes is basically useless to me.
To extend this, look in Kleopatra's settings, in the GnuPG System section, then switch to the Private Keys tab. The first section, "Options controlling the security" seem to affect the cache timeout even though it talks about PINs and SSH Keys. I found the documentation to be completely useless and spent hours on different virtual machines trying different settings and finally just set the values high on several of the options (see the screenshot below) and have had no more passphrase prompts for several hours. I work from home on a desktop computer that is not shared and never leaves the house so there's no reason at all I should have to enter that passphrase very often. On a different virtual machine, I set the values to 86400, which is the number of seconds in a day.
I hope these instructions are useful and get you either close to the solution you want or at least sheds light on a new set of tools you can add to your development environment. As I learn more and continue to play with the settings, I'll probably come back and edit this page. If you read this and have updated information, please leave a comment--I'd love the feedback!