| name | gpg-signing |
| description | Comprehensive guide to GPG commit signing. Set up, configure, and troubleshoot GPG commit signing. Fix GPG signing errors, configure passphrase caching, verify commit signatures. Use when working with Git commit signing, GPG keys, commit verification, signature verification, GPG configuration, or when encountering GPG signing errors. Covers Windows (Gpg4win), macOS (GPG Suite), Linux (gnupg), and WSL installation and setup. |
| allowed-tools | Read, Bash, Glob, Grep |
Git GPG Signing
Comprehensive guidance for setting up, configuring, and troubleshooting GPG commit signing across all platforms.
Table of Contents
Overview
Git commit signing provides cryptographic proof that commits came from you. This skill helps you:
- Install and configure GPG tools on Windows, macOS, and Linux
- Set up commit signing with proper key management
- Configure passphrase caching for better workflow
- Troubleshoot common GPG signing issues
- Understand security trade-offs and best practices
When to Use This Skill
This skill should be used when:
- Setting up GPG commit signing for the first time
- Configuring GPG tools (Gpg4win, GPG Suite, gnupg)
- Troubleshooting GPG signing errors ("gpg: signing failed", "inappropriate ioctl", etc.)
- Troubleshooting keyboxd daemon startup issues (Windows race condition)
- Determining which GPG installation Git is using
- Understanding Windows daemon startup behavior vs. official design
- Configuring passphrase caching to reduce prompts
- Understanding GPG vs SSH vs S/MIME signing methods
- Adding GPG keys to GitHub/GitLab/Bitbucket
- Resolving "Unverified" commits on GitHub
- Working with
.gnupg/gpg-agent.conf configuration
Quick Start
Basic Setup (Single Personal Key):
gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long
git config --global user.signingkey <KEY_ID>
git config --global commit.gpgsign true
gpg --armor --export <KEY_ID>
Platform-Specific Setup
Windows: Gpg4win Installation
For detailed Windows setup, see references/windows-setup.md.
Quick install:
# Option 1: Download installer
# https://gpg4win.org/thanks-for-download.html
# Option 2: winget
winget install --id GnuPG.Gpg4win -e --source winget
# Configure Git to use Gpg4win (adjust path if installed elsewhere)
git config --global gpg.program "C:/Program Files (x86)/GnuPG/bin/gpg.exe"
macOS: GPG Suite / Homebrew
brew install gnupg
git config --global gpg.program $(which gpg)
Linux: GnuPG
sudo apt update && sudo apt install gnupg
sudo dnf install gnupg2
sudo pacman -S gnupg
WSL: Follow Linux Instructions
WSL users: Follow the Linux setup instructions above (WSL runs Linux). See troubleshooting section for WSL-specific issues if needed.
Key Generation
Personal Development Key (Interactive)
gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long
Recommended algorithm: EdDSA using Curve25519 (Ed25519) - modern, fast, small keys, excellent security
Alternative: RSA 4096-bit (traditional, widely compatible)
Exporting Keys
gpg --armor --export <KEY_ID>
gpg --armor --export-secret-keys <KEY_ID>
Git Configuration
Enable Commit Signing
git config --global user.signingkey <KEY_ID>
git config --global commit.gpgsign true
git config --global tag.gpgSign true
cd /path/to/repo
git config user.signingkey <KEY_ID>
git config commit.gpgsign true
Verify Configuration
git config --global user.signingkey
git commit --allow-empty -m "Test GPG signing"
git log --show-signature -1
Passphrase Caching
GPG agent caches passphrases to reduce how often you're prompted.
Check if config exists:
ls ~/.gnupg/gpg-agent.conf
Create or edit ~/.gnupg/gpg-agent.conf:
# Cache passphrase for 8 hours of inactivity
default-cache-ttl 28800
# Maximum cache time of 24 hours regardless of use
max-cache-ttl 86400
# Allow pinentry to cache the passphrase
allow-preset-passphrase
Apply changes:
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
For comprehensive caching configuration, including security scenarios, testing procedures, and troubleshooting, see references/passphrase-caching.md.
Windows-Specific: Dual GPG Installation Issue
CRITICAL for Windows users: Windows typically has two separate GPG installations (Gpg4win and Git Bash GPG), each with different config file locations:
- Gpg4win:
%APPDATA%\gnupg\gpg-agent.conf (typically C:\Users\<Username>\AppData\Roaming\gnupg\gpg-agent.conf)
- Git Bash GPG:
~/.gnupg/gpg-agent.conf (resolves to C:\Users\<Username>\.gnupg\gpg-agent.conf)
Common problem: Configuring ~/.gnupg/gpg-agent.conf (Git Bash GPG) when Git is configured to use Gpg4win. Result: configuration silently ignored, caching doesn't work.
Verify which GPG Git is using:
git config --global gpg.program
gpgconf --list-dirs homedir
Windows configuration must include pinentry-program:
# Example: %APPDATA%\gnupg\gpg-agent.conf
default-cache-ttl 28800
max-cache-ttl 86400
allow-preset-passphrase
# REQUIRED for Windows:
pinentry-program C:/Program Files (x86)/GnuPG/bin/pinentry-basic.exe
See: Windows Setup Guide - Dual GPG Installations for detailed explanation.
Recommended Cache Durations
| Scenario | default-cache-ttl | max-cache-ttl | Rationale |
|---|
| High Security | 900 (15 min) | 3600 (1 hour) | Prompt frequently, short window |
| Balanced | 3600 (1 hour) | 28800 (8 hours) | Prompt every ~hour, expires by end of day |
| Convenience | 28800 (8 hours) | 86400 (24 hours) | Prompt once per workday, expires daily |
GitHub Integration
Adding GPG Key to GitHub
-
Export public key:
gpg --armor --export <KEY_ID>
-
Add to GitHub:
-
Verify email matches:
- Git email must match GPG key email
- Email must be verified in GitHub account
git config --global user.email
gpg --list-keys <KEY_ID>
Troubleshooting "Unverified" Commits
Possible causes:
- Public key not added to GitHub → Add key at Settings → SSH and GPG keys
- Email mismatch → Ensure Git email = GPG key email = GitHub verified email
- Key expired → Extend expiration or generate new key
- Key revoked → Generate new key (cannot un-revoke)
Troubleshooting
For comprehensive troubleshooting, see references/troubleshooting.md.
"gpg: signing failed: No secret key"
Cause: Git configured to use key ID that doesn't exist in keyring.
Solution:
gpg --list-secret-keys --keyid-format=long
git config --global user.signingkey
git config --global user.signingkey <CORRECT_KEY_ID>
"gpg: signing failed: Inappropriate ioctl for device"
Cause: GPG agent cannot prompt for passphrase (terminal issue).
Solution (Linux/macOS/WSL):
export GPG_TTY=$(tty)
echo 'export GPG_TTY=$(tty)' >> ~/.bashrc
Solution (Windows with Gpg4win):
echo 'pinentry-program "C:/Program Files (x86)/GnuPG/bin/pinentry-basic.exe"' >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent
"error: gpg failed to sign the data"
Debug steps:
echo "test" | gpg --clearsign
gpgconf --list-components
gpg --list-keys --keyid-format=long <KEY_ID>
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
git commit -m "test"
Passphrase Prompt Every Commit (Cache Not Working)
Windows users: This is commonly caused by dual GPG installation issues. See Windows Setup - Passphrase Caching Troubleshooting and Troubleshooting - Windows Caching Issue for detailed diagnosis.
Possible causes:
-
Wrong config file location (Windows):
git config --global gpg.program
gpgconf --list-dirs homedir
-
gpg-agent.conf not loaded:
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
gpgconf --list-options gpg-agent | grep cache-ttl
-
Cache TTL set too low → Increase cache time in ~/.gnupg/gpg-agent.conf
-
Multiple GPG agents running:
pkill gpg-agent
gpgconf --launch gpg-agent
GPG Signing Methods Comparison
| Method | Best For | Setup Complexity | Key Management |
|---|
| GPG | Full-featured, supports expiration/revocation | Medium | Most flexible |
| SSH | Simplest, reuses existing SSH keys | Low | Limited features |
| S/MIME | Enterprise with X.509 certificates | High | Org-managed |
SSH Signing (Alternative)
When to use SSH instead of GPG:
- Simple personal projects
- Already have SSH key setup
- Don't need expiration/revocation features
- Want minimal configuration
Setup:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
Limitations:
- No key expiration support
- No revocation tracking
- Requires Git 2.34+ (2021)
Security Best Practices
For comprehensive security guidance, see references/security-best-practices.md.
Quick recommendations:
- ✅ Use passphrase protection on personal keys (minimum 20 characters)
- ✅ Configure caching to balance security and convenience (4-8 hours)
- ✅ Consider key expiration: No expiration for personal projects, 1-year for enterprise work
- ✅ Backup private key to encrypted vault or password manager's Secure Documents
- ⚠️ Never store unencrypted keys in Git repos, cloud storage, or email
Resources
Reference Documentation
Official Documentation
Related Skills
- git-commit: Use for complete git commit workflow with Conventional Commits format, safety protocols, and attribution requirements
- config: Advanced Git configuration including aliases, credentials, and performance tuning
- gpg-multi-key: Multi-key management for consultants, CI/CD automation, and enterprise teams
Version History
- v1.1.1 (2025-11-25): Progressive disclosure optimization - extracted Test Scenarios to reference file, removed redundant Quick Command Reference section, reduced SKILL.md to under 500 lines
- v1.1.0 (2025-11-22): Enhanced troubleshooting - added keyboxd daemon race condition troubleshooting (T7777/T7829), dynamic GPG detection workflow, Windows startup best practices with official design vs. reality analysis
- v1.0.5 (2025-11-19): Optimization improvements - added table of contents to SKILL.md, extracted Essential Commands Reference to quick-reference.md, reduced line count from 530 to 522
- v1.0.4 (2025-11-17): Progressive disclosure improvement - extracted Security Best Practices to separate reference file
- v1.0.3 (2025-11-17): Validated against official documentation - fixed tag.gpgSign capitalization, updated Last Verified dates
- v1.0.2 (2025-11-12): Enhanced documentation - added TOCs to long references, documented test scenarios
- v1.0.1 (2025-11-13): Added cross-reference to git-commit skill
- v1.0.0 (2025-01-09): Initial release migrated from repository documentation
Last Updated
Date: 2025-11-28
Model: claude-opus-4-5-20251101