Git commit PGP signing

Git signed commits help verify the Git author’s identity using PGP. Optionally, a user or organization can set rules requiring Git PGP signed commits on Git hosting providers such as GitHub and GitLab

PGP public keys can help verify author identity of Git commits, social media, website, etc. Setup GPG on the laptop:

  • Linux: apt install gnupg
  • macOS: brew install gnupg
  • Windows: winget install --id=GnuPG.Gpg4win

Generate a GPG keypair if one doesn’t already exist for yourself.

Export the GPG public and private key and import into GPG:

If one has Keybase, first export Keybase.io PGP key to GPG. If one does NOT have Keybase, use gpg --full-generate-key to generate a GPG keypair.

Verify PGP key:

gpg --list-secret-keys --keyid-format LONG

The first lines will be like:

sec   rsa4096/<public_hex>

The hexadecimal part after the / is a public reference to the GPG keypair.


Add Git provider such as GitHub or GitLab verified email address to the PGP key. To make commits “Verified” with the Git provider, at least one of the Git provider verified email addresses must match:

git config --get user.email

Use the GPG public ID below:

gpg --edit-key <public_hex>

In the interactive GPG session that launches, type

adduid

and enter Name and the Email address–which must exactly match the GitHub verified email address. I also add the @users.noreply.github.com fake email that I always use to avoid spam. Do adduid twice–once for the real GitHub verified email address and again for the github_username@users.noreply.github.com fake email.

Add “trust” from the GPG> prompt:

trust

Since it’s you, perhaps a trust level of 5 is appropriate. type

save

to save changes, which may not show up until exiting and reentering the GPG> prompt.

Configure Git to use the GPG public hex ID like:

git config --global user.signingkey <public_hex>

git config --global commit.gpgsign true

On Windows, even though “gpg” works from Windows Terminal, it’s essential to tell Git the full path to GPG.exe, otherwise Git will fail to sign commits.

git config --global gpg.program "C:\Program Files\GnuPG\bin\gpg.ex"

Find the path with:

where.exe gpg

Add the GPG public key to the Git provider. Copy and paste the output from this command into GPG Key of GitHub or GitLab. This is done only once per human, not once per device.

gpg --armor --export <public_hex>

Usage

GPG can be used to sign Git commits and tags, and can also be disabled per commit.

Verify Git PGP commit sign

Make a git commit after the procedure above, and see the signature notes:

git log --show-signature

it will start with

gpg: Signature made

Temporary disable Git commit sign

If you temporarily lose access to the GPG password, you won’t be able to git commit. A temporary workaround is to set

git config commit.gpgsign false

or simply add the --no-gpg-sign option like:

git commit -am "msg" --no-gpg-sign

If not signing as default, sign only certain commits by

git commit -S

Note that’s a capital “S”.

Troubleshooting

Signing subkey expired

If you get gpg: signing failed: No secret key or gpg: skipped "...": No secret key, the signing subkey may have expired. GPG subkeys (encryption, signing) expire independently from the main key.

Check which subkeys are expired:

gpg --list-secret-keys

Look for subkeys marked expired. To extend them:

gpg --edit-key <public_hex>
key 1
expire
1y
save

The key N selects which subkey to extend (1 for first, 2 for second, etc.). Then export the updated key to GitHub.

Password prompt not working (macOS)

On macOS if entering the password on git commit doesn’t work, try:

brew install pinentry-mac

and add to ~/.zshrc:

export GPG_TTY=$TTY