gpg
Git commit signing and Troubleshooting GPG Key Issues
Using GPG (GNU Privacy Guard) to sign Git commits is a powerful way to secure your code and verify authenticity. In this post, I’ll walk you through everything — from getting started with Git commit signing to troubleshooting common issues.
You’ll learn what tools to install, how to set up GPG both globally and locally, how to create and store your GPG key, and how to determine which key to use when you have several keys or codes generated.
Getting Started with Git Commit Signing
Before diving into troubleshooting, let’s cover the basics of getting started with Git commit signing.
What You Need to Install
GnuPG (GPG):
- Linux: Install using your package manager (e.g.,
sudo apt-get install gnupg2
on Ubuntu). - macOS: Install via Homebrew using
brew install gnupg
. - Windows: Use Gpg4win.
Git:
- Ensure you have Git installed. Download it from git-scm.com or use your OS’s package manager.
Pinentry Program:
- This is used to securely prompt for your GPG passphrase. It is usually installed along with GPG, but you can install alternatives if needed.
Global vs. Local GPG Signing Setup
Global Setup:
- This configures your signing key and behavior for all repositories on your system.
Example commands:
git config --global user.signingkey <YOUR_KEY_ID>
git config --global commit.gpgsign true
git config --global gpg.program $(which gpg)
Local Setup:
You can override global settings on a per-repository basis. For example, if you want a repository not to use commit signing:
git config --local commit.gpgsign false
Or to use a different key:
git config --local user.signingkey <OTHER_KEY_ID>
Creating a GPG Key
If you don’t already have a GPG key, generate one with the following command:
gpg --full-generate-key
Follow these prompts:
- Key Type: Choose RSA and RSA (default)
- Key Size: 4096 bits is recommended for better security.
- Key Validity: You can set an expiry (or 0 for no expiry).
- User Information: Enter your name and email address (e.g.,
priyansh@datazip.io
). - Passphrase: Choose a strong passphrase.
After the key is generated, list your secret keys to see the key details:
gpg --list-secret-keys --keyid-format LONG
You might see output like:
sec rsa3072/87881962111D533F5 2025-03-13 [SC] [expires: 2030-03-12]
4EC4B70E9759F7XXXXXB807D87881962C5D533F5
uid [ultimate] priyansh_dz (comoany gpg) <priyansh@datazip.io>
ssb rsa3072/C0AF93AD79D30030 2025-03-13 [E] [expires: 2030-03-12]
Which Key to Use?
- Primary vs. Subkeys: In the listing above, the
sec
line represents your primary secret key. It often has capabilities like[SC]
(Sign and Certify). - Choosing the Right Key: When configuring Git, use the long key ID after the slash (here,
87881962C5D533F5
). This is the key that Git will use for signing commits. - Storage Location: All your keys are stored in your home directory under
~/.gnupg
. This folder contains the keyrings (pubring.kbx
for public keys and the secret keys file) along with configuration files.
Storing Your GPG Keys Securely
Backup: Always create a backup of your GPG keys. You can export your private key with:
gpg --export-secret-keys --armor <YOUR_KEY_ID> > my-private-key.asc
And your public key with:
gpg --armor --export <YOUR_KEY_ID> > my-public-key.asc
Safe Storage: Store these backup files in a secure location (preferably encrypted and offline). This is critical for recovering your key if your system fails.
Troubleshooting Common GPG Issues
After setting up your GPG key, you might encounter issues like “waiting for lock” or “gpg failed to sign the data.” Here’s how to address them.
The Problem: GPG Keyring Locks and Timeouts
When running:
gpg --list-secret-keys --keyid-format LONG priyansh@datazip.io
you might see errors such as:
gpg: Note: database_open 134217901 waiting for lock (held by 67445) ...
gpg: keydb_search failed: Operation timed out
These messages indicate that another process is holding a lock on your key database.
Step-by-Step Troubleshooting
1. Identify and Kill Stale GPG Processes
Check for running GPG processes:
ps aux | grep gpg
If you see a process (for example, gpg-agent
), kill it:
kill -9 <PID>
Or, to kill all GPG-related processes:
pkill -9 gpg-agent
pkill -9 gpg
2. Remove Lock Files
Check and remove any lingering lock files:
rm -rf ~/.gnupg/*.lock
3. Reset the GPG Environment
If issues persist, back up and reset your GPG directory:
mv ~/.gnupg ~/.gnupg_backup
mkdir ~/.gnupg
chmod 700 ~/.gnupg
Restart the GPG agent:
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
4. Verify Your Key Listing
Run the key listing command again:
gpg --list-secret-keys --keyid-format LONG
You should now see your key without any errors.
5. Fixing “gpg failed to sign the data” Error
If you encounter the error during commit signing:
Set the Correct TTY:
export GPG_TTY=$(tty)
echo "export GPG_TTY=$(tty)" >> ~/.zshrc # Or ~/.bashrc if using bash
source ~/.zshrc
Restart the Agent: As described above, kill and restart the agent.
Ensure Git Uses the Correct GPG Binary:
git config --global gpg.program $(which gpg)
Enabling Git Commit Signing
Once your GPG environment is working, configure Git to sign your commits.
Global Configuration
Set your GPG key and enable signing for all commits:
git config --global user.signingkey 87881962C5D533F5 # Replace with your key ID
git config --global commit.gpgsign true
git config --global gpg.program $(which gpg)
Local Configuration
If you need different settings for a particular repository:
git config --local user.signingkey <OTHER_KEY_ID>
git config --local commit.gpgsign true # Or false, if you don’t want to sign for that repo
Testing Your Setup
Create a test commit to verify signing:
git commit -S -m "Test commit with GPG"
If prompted, enter your GPG passphrase. You can also manually verify signing by attempting to clear-sign a message:
echo "test" | gpg --clearsign
Exporting Your Public GPG Key for GitHub
Once your local commits are signed, you can link your public key to GitHub for verification.
1. Export Your Public Key
Run:
gpg --armor --export 87881962C5D533F5 // 87881962C5D533F5 is your key ID
This outputs a block that starts with:
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----
2. Add the Key to GitHub
- Log in to GitHub: Go to Settings → SSH and GPG keys.
- Add New GPG Key: Click New GPG key, paste the entire block, and save.
3. Verify on GitHub
Push a signed commit to your repository and confirm on GitHub that it’s marked as “Verified.”
Final Thoughts
Using GPG for commit signing not only secures your commits but also adds a layer of authenticity to your code history. The journey — from installing the necessary tools, creating and storing your GPG keys, configuring Git globally and locally, to troubleshooting common issues — can be intricate. However, with the steps outlined in this guide, you should be well-equipped to enable and troubleshoot Git commit signing effectively.
Feel free to leave comments or questions if you encounter any issues or need further clarification. Happy coding and secure committing!