Skip to main content

How to verify your commits on GitHub

Updated 5 min readMarkdown

Git doesn't check who you are. The author name and email on a commit are whatever is in your config, so anyone can make a commit that claims to be from you:

git -c user.name="Your Name" -c user.email="you@example.com" commit -m "totally legit"

Push that to GitHub and it will show up with your avatar next to it. Nothing about the commit proves you wrote it.

Signing fixes that. You sign each commit with a key only you hold, GitHub checks the signature against the public key on your account, and the commit gets a green Verified badge. It takes about ten minutes to set up, and after that you don't have to think about it.

Why bother

For a personal project it can feel like ceremony. A few reasons it isn't:

  • Supply chain. A lot of attacks on open source come down to "someone pushed code that looked like it came from a trusted maintainer." Signed commits, together with branch protection that requires them, make that harder.
  • Some repositories require it. Many organizations turn on "Require signed commits" for protected branches. If your commits aren't signed, you can't merge.
  • Vigilant mode. Once you sign everything, you can turn on vigilant mode. GitHub then marks any commit that claims to be you but isn't signed as Unverified, so impersonation stands out instead of blending in.

1. Create a GPG key

On macOS, install GnuPG and a pinentry program first (pinentry is the dialog that asks for your passphrase):

brew install gnupg pinentry-mac

Then generate the key:

gpg --full-generate-key

The defaults in recent GnuPG versions (ECC, ed25519) are fine. Two things matter:

  • The email has to be one you've verified on GitHub. If you use the noreply address (12345+user@users.noreply.github.com), put that one in the key.
  • Use a passphrase. The key lives on your disk. Without a passphrase, anyone who gets a copy of ~/.gnupg can sign as you.

2. Find your key ID

gpg --list-secret-keys --keyid-format=long
sec   ed25519/3AA5C34371567BD2 2026-11-04 [SC]
      ...
uid                 [ultimate] Your Name <you@example.com>

The key ID is the part after the slash: 3AA5C34371567BD2.

3. Add the public key to GitHub

Export the public key:

gpg --armor --export 3AA5C34371567BD2

Copy the whole output, including the -----BEGIN PGP PUBLIC KEY BLOCK----- and -----END PGP PUBLIC KEY BLOCK----- lines. Paste it in GitHub → Settings → SSH and GPG keys → New GPG key.

4. Tell Git to sign everything

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

With commit.gpgsign on you don't need -S on every commit; Git signs them all.

GPG also needs to know which terminal to ask for the passphrase on. Add this to your ~/.zshrc (or ~/.bashrc):

export GPG_TTY=$(tty)

Without it, you'll probably see this the first time you commit:

error: gpg failed to sign the data
fatal: failed to write commit object

5. Stop typing your passphrase on every commit

gpg-agent caches your passphrase after you type it once. The default timeout is short (10 minutes), so you can raise it in ~/.gnupg/gpg-agent.conf:

default-cache-ttl 3600
max-cache-ttl 86400
pinentry-program /opt/homebrew/bin/pinentry-mac
  • default-cache-ttl is how many seconds the passphrase stays cached after you last used it (here, one hour).
  • max-cache-ttl is the hard limit, however often you use it (here, one day).
  • pinentry-program makes macOS show a native dialog instead of asking in the terminal. On Intel Macs, the path is /usr/local/bin/pinentry-mac.

Restart the agent so it reads the new config:

gpgconf --kill gpg-agent

6. Check that it works

Make a commit and look at the signature:

git commit --allow-empty -m "test signing"
git log --show-signature -1
gpg: Signature made Wed Nov  4 11:40:12 2026 CET
gpg:                using EDDSA key 3AA5C34371567BD2
gpg: Good signature from "Your Name <you@example.com>" [ultimate]

Push it, and the commit on GitHub shows the Verified badge.

The shortcut: sign with your SSH key

Since Git 2.34, you can sign with the SSH key you already use to push, with no GPG involved:

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true

Then add the same public key on GitHub again, but this time choose Signing Key as the key type (an Authentication key can't verify signatures).

It's less setup, and if your SSH key is already in a hardware key or a password manager like 1Password, you get that for free. GPG is still the more common choice for signing tags and release artifacts, and it's what most guides assume, which is why I covered it first.

Wrapping up

Ten minutes of setup, and every commit you push from now on can be traced back to a key only you hold. If you maintain anything other people depend on, turn on vigilant mode too, and think about requiring signed commits on your main branch. It's one of the cheapest supply chain controls there is.

About the author

  • I'm from Brazil and I've been working professionally with technology since 2009. I love to learn, and my current professional interests are:

    Infrastructure Security Platforms Cloud Coding and automation (always my number #1 <3)

No comments yet. Be the first to comment.