open atlas
↑ Back to track
Git, from zero to senior GIT · 09 · 04

Signing commits and trust

Anyone can set any author name and email on a commit, so the author field proves nothing. Signing a commit or tag with a GPG or SSH key proves who made it. git commit -S and git log --show-signature verify authorship; the host shows a Verified badge once your key is registered.

GIT Senior ◷ 16 min
Level
FoundationsJuniorMiddleSenior

The author on a commit is just two strings you set yourself. Run git config user.name "Linus Torvalds" and user.email to match, commit, and the history now reads as if Linus wrote your code. Git does nothing to stop you — the author field is a label, not proof. On a public project, anyone can forge a commit that appears to come from a trusted maintainer, and a reviewer skimming git log would never notice.

By the end of this lesson you will be able to cryptographically sign your commits and tags so their authorship is verifiable, configure signing to happen automatically, and explain why the “Verified” badge is the difference between a claimed author and a proven one.

Goal

After this lesson you can sign commits and tags with a GPG or SSH key, configure Git to sign automatically, verify signatures locally with git log --show-signature, and explain what the host’s Verified badge does and does not guarantee.

1

The author and committer fields are unauthenticated — signing is the only real proof of who made a commit. When you commit, Git records Author: Name <email> from your local config, with zero verification that the name or email is yours. This is by design — Git is distributed and trusts no central identity provider. The fix is a cryptographic signature: you sign the commit with a private key only you hold, and anyone with your matching public key can verify the commit was made by that key and has not been altered. Identity stops being a claim and becomes a proof.

2

You can sign with GPG or, more simply, with an SSH key you already have. Git supports both formats. SSH signing is newer and easier because most developers already have an SSH key for pushing. Configure it once:

# Use SSH-key signing and point Git at your public key
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub

For GPG instead, set gpg.format back to its default and user.signingkey to your GPG key ID. Either way, user.signingkey tells Git which key to sign with; the corresponding public key is what others (and the host) use to verify.

3

Sign individual commits and tags with -S / -s, or turn signing on for everything. The explicit flags sign one object at a time:

git commit -S -m "Add rate limiter"   # sign this commit
git tag -s v2.1.0 -m "Release 2.1.0"  # sign an annotated tag

Typing -S every time is easy to forget, so configure automatic signing:

git config --global commit.gpgsign true   # sign every commit
git config --global tag.gpgsign true      # sign every tag

Signed tags matter especially for releases: a signed v2.1.0 tag proves the exact commit you blessed as a release came from you, which is the anchor of a trustworthy supply chain.

4

Verify signatures locally, and let the host show a Verified badge to everyone else. On your machine you can check any commit or tag:

git log --show-signature        # show signature status per commit
git verify-commit <sha>         # verify one commit's signature
git verify-tag v2.1.0           # verify a tag's signature

For collaborators who are not running these commands, GitHub and GitLab do the verification server-side: once you upload your public signing key to your account, the host marks your signed commits with a green Verified badge and flags anything signed by an unknown or mismatched key. The badge is the team-visible, at-a-glance version of verify-commit.

Why this works

Why does this matter beyond vanity? Two real threats. First, impersonation: in an open-source project, a malicious contributor can craft a commit that appears authored by a core maintainer, slipping a backdoor past reviewers who trust that name. Required signing means an unsigned or wrongly-signed commit is rejected, so a forged author cannot masquerade as a trusted one. Second, supply-chain trust: downstream consumers of your release want proof that the tagged artifact really came from your team and was not swapped at some hop. A signed tag is that proof. Signing converts “the log says Alice wrote this” into “Alice’s key signed this,” which is what audits, protected branches, and reproducible releases actually rely on.

Worked example

An impersonated commit, caught by signing.

A popular library enforces signed commits on main via a branch rule. An attacker opens a pull request and, to look trustworthy, sets user.name and user.email to exactly match a well-known maintainer. In a naive project this might sail through — git log would show the maintainer’s name on a commit that adds a subtle dependency swap.

But the branch rule requires a valid signature. The attacker cannot produce one: signing needs the maintainer’s private key, which they do not have. Their commit shows up unsigned (or signed by their own unknown key), so the host displays it as Unverified, the required-signature rule blocks the merge, and reviewers immediately see the mismatch between the claimed author and the missing/foreign signature. Meanwhile the real maintainer has commit.gpgsign true set, so every legitimate commit carries the green Verified badge by default — the contrast makes the forgery obvious. The author field lied; the signature could not. Identity held because it was proven, not claimed.

Common mistake

A common stumble: you set commit.gpgsign true but never registered the public key with GitHub/GitLab, so your commits are genuinely signed yet show as Unverified to everyone — the host cannot match the signature to a known key. Signing locally and registering the key are two separate steps; do both. The mirror-image trap is a “Verified” badge that says less than people think: it only proves the commit was signed by a key the host has on file for some account — it does not vouch for the code’s quality or that the change is safe. Verified means authentic origin, not good code.

Check yourself
Quiz

Why is signing a commit meaningfully stronger evidence of authorship than the commit's author name and email?

Recap

A commit’s author name and email are unauthenticated text anyone can set, so they prove nothing — the only real evidence of authorship is a cryptographic signature. Sign with a GPG key or, more simply, an SSH key (gpg.format ssh, user.signingkey), one object at a time with git commit -S / git tag -s, or automatically via commit.gpgsign true. Verify locally with git log --show-signature and git verify-commit; once you register your public key, GitHub and GitLab show a Verified badge so the whole team sees proven authorship at a glance. Signing defends against impersonation and underpins supply-chain trust, especially via signed release tags — but remember the badge proves origin, not code quality. Next you will assemble a calm disaster-recovery toolkit for when a repo has a very bad day.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.