Skip to content

Instantly share code, notes, and snippets.

@shawonashraf
Created June 6, 2026 02:28
Show Gist options
  • Select an option

  • Save shawonashraf/86da160596a28043752833ed0a165e71 to your computer and use it in GitHub Desktop.

Select an option

Save shawonashraf/86da160596a28043752833ed0a165e71 to your computer and use it in GitHub Desktop.
git gpg

Git Commit Signing with GPG

A complete guide to generating a GPG key, configuring Git to sign commits, and setting up pinentry-mac so graphical apps like VS Code can sign commits and save your passphrase in the macOS Keychain.


1. Install GPG

Install GnuPG via Homebrew:

brew install gnupg

Verify the installation:

gpg --version

2. Generate a GPG Key

gpg --full-generate-key

When prompted:

  • Key type: (1) RSA and RSA (default)
  • Key size: 4096
  • Expiration: 0 (never) or a duration like 2y
  • Real name: Your name (should match your Git identity)
  • Email: The email associated with your GitHub/GitLab account
  • Comment: Optional — leave blank or add a label
  • Passphrase: Choose a strong one — you'll save it to the Keychain later

3. Find Your Key ID

List your keys to find the key ID:

gpg --list-secret-keys --keyid-format=long

Example output:

sec   rsa4096/3AA5C34371567BD2 2024-01-01 [SC]
      ABCDEF1234567890ABCDEF1234567890ABCDEF12
uid           [ultimate] Your Name <you@example.com>
ssb   rsa2048/4BB6D45382678CE3 2024-01-01 [E]

Your key ID is the part after rsa4096/ on the sec line — in this example: 3AA5C34371567BD2.


4. Configure Git to Sign Commits

Tell Git which key to use and enable signing globally:

git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign true
git config --global tag.gpgsign true

Also make sure your Git identity matches the email on your GPG key:

git config --global user.email "you@example.com"
git config --global user.name "Your Name"

5. Point Git to the GPG Binary

If Git can't find gpg, tell it the path explicitly:

git config --global gpg.program $(which gpg)

On Apple Silicon this is typically /opt/homebrew/bin/gpg.


6. Add Your Public Key to GitHub / GitLab

Export your public key:

gpg --armor --export 3AA5C34371567BD2

Copy the full output (from -----BEGIN PGP PUBLIC KEY BLOCK----- to -----END PGP PUBLIC KEY BLOCK-----), then add it to your account:

  • GitHub: Settings → SSH and GPG keys → New GPG key
  • GitLab: Preferences → GPG Keys → Add new key

7. Test Commit Signing

Make a test commit and verify the signature:

git commit --allow-empty -m "test: verify GPG signing"
git log --show-signature -1

You should see gpg: Good signature from "Your Name <you@example.com>" in the output.


8. Set Up pinentry-mac for GUI Apps (VS Code, Tower, etc.)

By default, GPG tries to show a passphrase prompt in the terminal. Graphical apps don't have a terminal attached, so signing silently fails. pinentry-mac provides a native macOS dialog and can save your passphrase to the Keychain.

8a. Install pinentry-mac

brew install pinentry-mac

8b. Configure GPG Agent to Use It

Find your gpg-agent.conf file (create it if it doesn't exist):

mkdir -p ~/.gnupg

Open or create ~/.gnupg/gpg-agent.conf and add:

pinentry-program /opt/homebrew/bin/pinentry-mac

Note: On Intel Macs, Homebrew installs to /usr/local/bin/pinentry-mac. Adjust the path accordingly. Confirm with which pinentry-mac.

8c. Set Correct Permissions on the ~/.gnupg Directory

GPG is strict about directory permissions and will refuse to run if they are too open:

chmod 700 ~/.gnupg
chmod 600 ~/.gnupg/*.conf 2>/dev/null; true

8d. Reload the GPG Agent

Apply the new configuration:

gpgconf --kill gpg-agent
gpgconf --launch gpg-agent

8e. Connect the GPG Agent to Your Shell

Make sure your shell exports the correct socket path. Add this to your ~/.zshrc (or ~/.bashrc):

export GPG_TTY=$(tty)

Then reload:

source ~/.zshrc

9. Save the Passphrase to the macOS Keychain

Trigger a signing operation from the terminal so the pinentry-mac dialog appears:

echo "test" | gpg --clearsign

In the passphrase dialog that appears:

  1. Enter your GPG key passphrase.
  2. Check "Save in Keychain".
  3. Click OK.

The passphrase is now stored in the macOS Keychain. The GPG agent will use it automatically for all future signing operations — including from VS Code and other GUI apps — without prompting again.


10. Verify the Full Setup in VS Code

  1. Open VS Code and make a change in a Git repository.
  2. Stage the change and commit via the Source Control panel.
  3. The commit should complete without any passphrase prompt.
  4. Run git log --show-signature -1 in the terminal to confirm the commit is signed.

Troubleshooting

error: gpg failed to sign the data Run export GPG_TTY=$(tty) in your terminal and try again. Make sure gpg-agent is running: gpgconf --launch gpg-agent.

Pinentry dialog never appears Confirm pinentry-mac is on the path you specified in gpg-agent.conf: which pinentry-mac. Kill and relaunch the agent after any config change.

Passphrase is still being asked every time The GPG agent caches credentials for a limited time. To extend the cache duration, add these lines to ~/.gnupg/gpg-agent.conf:

default-cache-ttl 86400
max-cache-ttl 604800

Then reload the agent. If you checked "Save in Keychain" and it's still prompting, the Keychain entry may not have been stored — repeat step 9.

Commits show as "Unverified" on GitHub The email on your GPG key must exactly match the email in your GitHub account and in git config user.email. Re-export and re-upload the key if you updated the email.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment