This guide provides a comprehensive tutorial on how to set up a YubiKey to sign your Git commits on GitHub using GPG (GnuPG). This ensures that commits attributed to you were indeed made by you, adding a layer of trust and security. A signature will require a physical touch on your YubiKey.
Windows: Download and install Gpg4win from the official website: gpg4win.org. This package includes GnuPG, the Kleopatra key manager, and other useful tools.
brew install gnupg yubikey-personalization
You may also want pinentry-mac, a tool for entering PINs in a native macOS dialog:
brew install pinentry-mac
# Configure gpg-agent to use it
echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
sudo apt update
sudo apt install gnupg2 pcscd scdaemon
For maximum security, we will generate the GPG keys directly on the YubiKey itself. This means the private keys never touch your computer’s hard drive.
Insert your YubiKey.
gpg --card-edit
# In the gpg/card> prompt:
admin
factory-reset
# Confirm the reset. It will wipe the OpenPGP applet.
quit
12345612345678Run gpg --card-edit again to enter the card management prompt.
gpg --card-edit
# In the gpg/card> prompt:
admin
passwd
# Select option 1 to change the User PIN.
# Enter the default PIN (123456), then your new PIN.
# Select option 3 to change the Admin PIN.
# Enter the default Admin PIN (12345678), then your new Admin PIN.
# A good PIN is at least 8 characters. The Admin PIN should be longer/more complex.
quit
gpg --card-edit one more time.
gpg --card-edit
# In the gpg/card> prompt:
admin
generate
# It will ask if you want to make an off-card backup of the encryption key.
# For maximum security, say No (n).
# It will prompt for key expiry. Choose a reasonable value (e.g., 2y for 2 years) or never.
# Enter your Real Name, Email Address, and an optional Comment.
# Confirm the details are correct by typing 'O' for Okay.
# You will be prompted for your Admin PIN, then your User PIN.
quit
GnuPG has now generated three keys (Signature, Encryption, Authentication) directly on your YubiKey.
This policy requires you to physically touch your YubiKey for every signature, preventing malware from signing commits without your presence.
gpg --card-status. Look for the “Signature key” line. The long string of characters is the Key-ID.
Signature key ....: E4A1 C325 45E6 4A9C 1E80 0C5B 2E3E F53B 5882 732D
In this example, the Key-ID is E4A1C32545E64A9C1E800C5B2E3EF53B5882732D.
gpg --edit-key YOUR_KEY_ID
# In the gpg> prompt:
toggle
key 1
# You should now see an asterisk (*) next to the signature key.
keytocard
# Select option 1 (Signature key).
# Enter your User PIN.
save
The touch policy is now set for the signature key.
gpg --list-secret-keys --keyid-format=long
The output will show your key. The ID is the part after sec> rsa4096/.
sec> rsa4096/AABBCCDD11223344 2025-07-14 [SC]
Now export the public key for that ID in the correct format.
gpg --armor --export AABBCCDD11223344
Copy the entire output, including the -----BEGIN PGP PUBLIC KEY BLOCK----- and -----END PGP PUBLIC KEY BLOCK----- lines.
git config --global user.signingkey AABBCCDD11223344
git config --global commit.gpgsign true
git config --global gpg.program $(which gpg)
Now, when you run git commit, you will be prompted for your YubiKey PIN, and the key will start flashing. Touch it to create the signature. When you push to GitHub, your commits will have a “Verified” badge.