Home DevOps Signed Commits — The Fake Commit That Almost Deployed Malware
Intermediate 3 min · July 07, 2026
Signed Commits with GPG: Verify Your Identity in Git

Signed Commits — The Fake Commit That Almost Deployed Malware

A malicious actor pushed a commit impersonating a trusted maintainer.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Production
production tested
July 07, 2026
last updated
214
articles · all by Naren
Before you start⏱ 20 min
  • Solid grasp of devops fundamentals
  • Comfortable reading and writing code examples independently
  • Basic understanding of production deployment concepts
 ● Production Incident
Quick Answer

1. Generate a GPG key: gpg --full-generate-key. 2. Add it to GitHub: gpg --armor --export → Settings → SSH and GPG keys. 3. Configure Git: git config --global user.signingkey and git config --global commit.gpgsign true.

✦ Definition~90s read
What is Signed Commits with GPG?

Signed commits use GPG (GNU Privacy Guard) to cryptographically verify that a commit was created by you, not by someone impersonating you. GitHub/GitLab display a 'Verified' badge on signed commits.

Signed commits are like a wax seal on a letter.
Plain-English First

Signed commits are like a wax seal on a letter. Anyone can write 'From: Albert Einstein' on an envelope. But a wax seal with Einstein's signet ring can only be created by someone with that ring. GPG signing stamps each commit with your unique digital seal. GitHub checks the seal and shows 'Verified' if it matches your account. No seal = anyone could have written that commit.

⚙ Browser compatibility
Latest versions — ✓ supported
ChromeFirefoxSafariEdge

Git commits have an author field that can be set to ANY name and email. git config user.name 'Linus Torvalds' && git config user.email 'torvalds@linux.com' — there's no authentication. This is a feature (Git is trust-based) but also a vulnerability. A malicious actor with push access can impersonate anyone. GPG signing solves this by attaching a cryptographic signature that GitHub/GitLab verifies against your public key. This guide covers setup, the incident where unsigned commits almost deployed malware, and how to enforce signing in your CI/CD pipeline.

Setting Up GPG-Signed Commits

Step 1: Generate a GPG key. Use gpg --full-generate-key. Choose RSA (4096 bits) or Ed25519. Use your REAL email — the one associated with your GitHub account.

Step 2: Export the public key: gpg --armor --export <key-id>. Add it to GitHub: Settings → SSH and GPG keys → New GPG key.

Step 3: Configure Git: git config --global user.signingkey <key-id> and git config --global commit.gpgsign true. Now every commit is auto-signed.

Step 4: Verify: git log --show-signature -1 shows the signature status. On GitHub, a 'Verified' badge appears next to the commit.

01_gpg_setup.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Generate a GPG key (interactive)
gpg --full-generate-key

# List your keys and copy the key ID
gpg --list-secret-keys --keyid-format LONG

# Export the public key to add to GitHub
gpg --armor --export <KEY-ID>

# Configure Git to use this key
git config --global user.signingkey <KEY-ID>

# Auto-sign all commits
git config --global commit.gpgsign true

# Sign a specific commit
git commit -S -m 'feat: add payment module'

# Verify signature on latest commit
git log --show-signature -1

# List signed and unsigned commits
git log --format='%h %G? %s'
Output
pub ed25519 2025-01-15 [SC]
ABCDEF1234567890ABCDEF1234567890ABCDEF12
uid [ultimate] Your Name <your@email.com>
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
[main a1b2c3d] feat: add payment module
Good "G" signature from "Your Name <your@email.com>"
a1b2c3d G feat: add payment module
b2c3d4e N fix: typo (UNSIGNED)
Use the Same Email as Your GitHub Account
GPG signature verification matches the committer email against the GPG key email. If your git config uses a different email, GitHub shows 'Unverified' even with a valid signature. Run git config --global user.email to check and match it to your GitHub email.
Production Insight
In CI/CD, enforce signed commits with a pre-receive hook on the server: check git log --format='%G?' and reject if any commit shows 'N' (no signature) or 'B' (bad signature). GitHub branch protection rules can require signed commits for specific branches without server-side hooks. For GitLab, use push rules. SSO-managed keys (via GitHub's org-level GPG enforcement) simplify key management for teams.
Key Takeaway
GPG signing cryptographically verifies commit authorship. Setup: generate a key, add to GitHub, configure Git. Enforce via branch protection rules. The author field alone is unverified — signing is the only identity guarantee.
● Production incidentPOST-MORTEMseverity: high

Impersonated Commit Almost Deployed Malicious Code

Symptom
A contributor with push access to a popular open-source library changed their local git config to impersonate the project lead. They pushed a commit that appeared to be from the lead maintainer. The malicious commit injected a crypto-miner into the build. GPG signing would have blocked it.
Assumption
The CI system checked 'author' field matching the committer — but the author field is self-reported. There was no cryptographic verification.
Root cause
1. Attacker had push access to the repository. 2. Attacker ran git config user.name 'Lead Maintainer' && git config user.email 'lead@project.com'. 3. Attacker created a commit that introduced malicious code. 4. The commit appeared in git log as authored by the lead maintainer. 5. Code review missed the malicious code (it was buried in a large diff). 6. The commit was merged and triggered a CI build. 7. Only a team member noticing the odd commit time prevented the deploy.
Fix
1. Reverted the malicious commit. 2. Rotated all commit access tokens and SSH keys. 3. Implemented GPG signing requirement: GitHub branch protection rule 'Require signed commits'. 4. Created a pre-receive hook that rejects unsigned commits: git log --format='%G?' -1 | grep -q 'G' 5. Added a CI check: git log --format='%G?' --all | grep -v 'G' | wc -l must be 0.
Key lesson
  • Git author/committer fields are self-reported and can be faked.
  • GPG signing is the ONLY way to cryptographically verify identity.
  • Enable signed commit requirements in branch protection rules.
  • Add CI checks that reject unsigned commits.
Production debug guideUse this when production is on fire3 entries
Symptom · 01
I want to start signing commits
Fix
Generate a GPG key, add to GitHub, set commit.gpgsign true
Symptom · 02
I want to sign all past commits
Fix
Use git rebase --exec 'git commit --amend --no-edit -S' to retroactively sign (rewrites history)
Symptom · 03
I need to enforce signing for my team
Fix
Use GitHub branch protection 'Require signed commits' or a pre-receive hook

Key takeaways

1
Git author/committer fields are self-reported and can be impersonated
2
GPG signing provides cryptographic identity verification
3
Use commit.gpgsign true to auto-sign every commit
4
Enforce signed commits via branch protection rules or pre-receive hooks
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 07, 2026
last updated
214
articles · all by Naren
🔥

That's Git. Mark it forged?

3 min read · try the examples if you haven't

Previous
Git Merge Strategies: Recursive, Ours, Theirs and Octopus
32 / 47 · Git
Next
Git LFS: Large File Storage for Git Repositories