Why sign
Git's author and committer fields are unauthenticated metadata - anyone can claim to be anyone. For projects where commit authorship matters (regulated industries, security-sensitive libraries, attestable supply chains), cryptographic signatures bind a commit to a real key. GitHub, GitLab, and similar then display a verified badge.
Three signing backends
- GPG - traditional, supported everywhere, awkward key management.
- SSH - reuses your SSH key (Git 2.34+), much simpler setup.
- X.509 / S/MIME - for enterprises with PKI infrastructure.
SSH signing (recommended)
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true
Now every commit is signed with your SSH key. To verify, you need an allowed signers file:
echo "[email protected] $(cat ~/.ssh/id_ed25519.pub)" \
>> ~/.config/git/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers
GPG signing
gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long
git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign true
Export the public key and upload it to GitHub or GitLab so they can verify your signatures.
gpg --armor --export 3AA5C34371567BD2
Signing existing commits
# Sign last commit
git commit --amend --no-edit -S
# Sign a range via rebase
git rebase -i <base> --exec 'git commit --amend --no-edit -S'
Verifying signatures
git log --show-signature
git verify-commit HEAD
git verify-tag v1.4.0
Enforcing signatures
Branch protection on GitHub and GitLab can require signed commits before merge. Combined with required reviews, this raises the bar for supply chain attacks - a stolen credential alone is not enough.
Signed tags for releases
git tag -s v1.4.0 -m "Release 1.4.0"
git tag -v v1.4.0
Signed tags are the foundation of release attestation. Tools like cosign and in-toto can build verifiable supply chains atop them.
Key management hygiene
- Use ed25519 (or RSA 4096+) keys.
- Protect with a passphrase and an agent.
- Rotate keys annually; record both old and new in allowed signers.
- Store keys on hardware (YubiKey, smartcard) for high-security contexts.
Common pitfalls
- Signing without uploading the public key to your hosting provider - signatures show as "unverified".
- Using the same key on multiple machines without thinking through revocation.
- Letting
gpg-agentcache passphrases indefinitely.
The case for signing
Signing does not prevent compromise; it makes compromise detectable. The first commit signed by a stolen key looks identical to a legitimate one - until a verifier compares against expected signers. Signing is necessary infrastructure for supply-chain integrity, not a complete solution. Combine it with reviews, two-factor authentication, and audit log review.