Want to see that sweet :heavy_check_mark: Verified status on your GitHub commit history? This guide walks through how to setup and configure everything needed on a Windows system!
Install GnuPG (GPG)
I’m a big fan of leveraging Chocolatey for package management on Windows. It makes things really easy to find and install software, and keep things up to date.
If you dont have Chocolatey already installed, head over to https://chocolatey.org/install and follow the instructions.
Install GnuPG with Chocolatey by opening an elevated PowerShell prompt and running the following:
choco install gnupg
If you prefer to install GnuPG manually you can download it here: https://www.gnupg.org/download/index.html
Generate a GPG key pair
Run the following command to start the wizard to generate your first GPG key:
When prompted for GPG options provide the following:
|Please select what kind of key you want:||GitHub supported GPG key algorithms|
|What keysize do you want:||GitHub minimum is |
|Please specify how long the key should be valid:||No requirements from GitHub|
|Real name:||your name|
|Email address:||your email address||Must match your verified email address with GitHub|
You will be prompted for a passphrase to secure your key. Generate a nice secure password with something like LastPass to use.
You can confirm your key was generated by running:
Configure git to use your signing key
We’ll need to provide git with the id of the GPG key to use for signing commits. The output from
gpg --list-keys will contain the id.
Configure git to sign all commits using this id:
git config --global user.signingkey 50DB2A62E89EE4CFC5B4B9AE241F81E6BE8BABEB
On Windows I’ve found that I also need to provide git with the filesystem path to the gpg executable. Without this option I’ve received messages from git such as
gpg: signing failed: No secret key. Configure git with this option (you may need to adjust your filesystem path to gpg.exe):
git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
Add your public key to GitHub
We need to provide GitHub with the public key of the PGP key pair we generated. Run the following command to export the public key:
gpg --armor --export 50DB2A62E89EE4CFC5B4B9AE241F81E6BE8BABEB
Copy all of the text including the
BEGIN PGP PUBLIC KEY and
END PGP PUBLIC KEY lines.
On GitHub navigate to your account
SSH and GPG keys. Click
New GPG Key, paste your public key text in the text box, and click
Add GPG key. You should now see the key stored in your GitHub account.
You should be all setup to sign commits now. When using
git from a shell you need to add the
-S option to indicate the commit should be signed with gpg:
git commit -S -m "this commit is signed"
Git can also be configured to automatically sign all commits. With this option configured your commits from VSCode will also be signed.
git config --global commit.gpgsign true
Test out making a new commit and push to a GitHub repo, goto
commits and you should see the wonderful, green Verified badge!
Reduce GPG passphrase prompts
The passphrase you provided when generating your gpg is used to lock and unlock access to your private key when git attempts to sign a commit. The first time you instruct git to sign a commit you should be greeted by a passphrase prompt similar to this screenshot:
When you installed GnuPG, it also installed and runs a service named
gpg-agent.exe that is responsible for caching this passphrase so you’re not prompted for it on every single commit. The default TTL for a cached passphrase however is 10 minutes. This is quite short for me, I’m not making commits every 10 minutes so it just ended up feeling like I was prompted for this passphrase every time.
gpg-agent.exe contains some configuration options so we can adjust this behavior.
List all of
gpg-agent.exe current configuration options using the following:
gpgconf --list-options gpg-agent
The options we need to configure are
max-cache-ttl. Both of these are configured with the number of seconds to cache the passphrase. The screenshot below shows the default values for both configuration options;
default-cache-ttl set to
max-cache-ttl set to
gpg-agent.exe reads its configuration from a file named
gpg-agent.conf. This file needs to be in
%APPDATA%\gnupg. By default this file does not exist, you will need to create it. You can use the PowerShell oneliner below to create the file and configure both options to
86400 (24 hours).
Set-Content -Path $ENV:APPDATA\gnupg\gpg-agent.conf -Value "default-cache-ttl 86400$([System.Environment]::NewLine)max-cache-ttl 86400"
Run the following to restart
gpg-agent.exe, and then verify the configuration options again:
gpgconf --kill gpg-agent gpgconf --list-options gpg-agent
You should see
86400 as the configured value for both
NOTE: There is a good bit of guidance that states the
gpg-agent.conf file needs to be in
%USERPROFILE%\.gnupg, however this would never work for me. If you have trouble getting
gpg-agent.exe to pick up the configuration changes try changing the file path and restarting the agent again.