Karya Semi
HomeBlogSearchCategoriesAboutContact
Karya Semi

Less noise. More notes.

HomeBlogAboutContactPrivacy PolicyDisclaimer

© 2026 Karya Semi. All rights reserved.

XGitHubLinkedIn
  1. Home
  2. /Categories
  3. /Software Engineering

The Developer's Trap: Why Git Signed Commits Don't Guarantee Codebase Security

Mandating Git commit signing is a trending compliance requirement. But relying on the green badge creates a false sense of security that leaves repositories vulnerable.

Dian Rijal Asyrof/July 15, 2026/5 min read
Illustration for The Developer's Trap: Why Git Signed Commits Don't Guarantee Codebase Security

The green "Verified" badge on GitHub feels like a warm security blanket. In an era where supply chain attacks make weekly headlines, seeing that small badge next to your commits provides a sense of safety. Development teams around the world are rushing to mandate GPG, SSH, or S/MIME signing for all commits. Compliance frameworks like SOC 2 and ISO 27001 increasingly point to commit signing as a checkbox for codebase integrity.

But this badge is misleading. It creates a false sense of security that actually leaves teams more vulnerable to sophisticated attacks. Git commit signing is a cryptographic proof of origin, not a guarantee of safety.

To build secure software, developers must understand the gap between cryptographic identity and code integrity. Here is why relying on Git signed commits is a dangerous trap, and how you should actually protect your codebase.

What Signed Commits Actually Prove

To understand the vulnerability, you must understand what happens when you sign a commit. When you run git commit -S, Git uses your private key to sign a specific payload. This payload includes the commit message, the author name, the committer name, the timestamps, and the SHA-1 or SHA-256 hash of the tree object (which represents the files in that commit).

The signature proves two things. First, it proves that the commit metadata was signed by someone with access to the private key associated with the public key on file. Second, it proves that the commit metadata has not been altered since it was signed.

That is it. The signature does not prove who actually wrote the code. It does not prove that the code is safe, clean, or free of backdoors. If an attacker gains access to your local machine, they can write malicious code and sign it with your active keys. To Git and GitHub, that commit is perfectly verified.

The Local Machine Compromise

The most common way malicious code gets signed is through local environment compromise. Developers often treat their workstations as secure enclaves, but they are highly exposed. They run untrusted npm packages, install browser extensions, and execute debug scripts with elevated permissions.

If a developer's workstation is compromised by malware or a malicious dependency, the attacker does not need to steal the private key. GPG and SSH keys are often configured with agents that cache the decrypted key in memory for hours. The malware can wait for the agent to be unlocked, then silently inject files and trigger a signed commit using the cached key.

In this scenario, the cryptographic signature is perfectly valid. The signature belongs to the legitimate developer. The green badge appears on the remote repository. Yet, the code is malicious. The signature did not prevent the attack; it only authenticated the compromised machine.

The Fallacy of Identity-Based Trust

The underlying mistake is equating identity with trustworthiness. In security architecture, this is known as the confused deputy problem. The system trusts the developer's identity, so it executes actions on the developer's behalf without verifying if the actions themselves are safe.

Commit signing assumes that if the author is known, the code is trusted. But even without malware, human developers make mistakes, introduce vulnerabilities, or can be socially engineered into committing malicious code. If a developer unknowingly merges a backdoor disguised as a library update, the signed commit still gets a green badge.

Relying on commit signatures to block malicious commits is like trusting a visitor because they showed a driver's license at the gate. The license proves who they are, but it does not check what is inside their backpack. Codebase integrity requires inspecting the cargo, not just verifying the driver.

The Verification Gap on Code Hosting Platforms

Code hosting platforms like GitHub and GitLab verify signatures against public keys uploaded to user profiles. When a commit arrives, the platform checks the signature, matches it to a user, and displays the "Verified" badge.

However, this verification is local to the platform's visual interface. The actual Git repository on your local machine does not enforce this by default. If you clone a repository, Git does not automatically warn you if some commits are unsigned or signed with untrusted keys unless you run explicit validation commands.

Furthermore, platform badges can be spoofed or bypassed in subtle ways. For example, if a platform allows fallback email matching or has bugs in its key-association logic, attackers can exploit these gaps to make unsigned commits appear verified. Relying entirely on a third-party web interface to display security state is a structural vulnerability.

Practical Defense-in-Depth for Git Repositories

If commit signing is not enough, how do you protect your codebase? The answer is to implement multiple layers of validation that do not rely solely on the author's identity.

First, implement strict branch protection rules. Require pull requests for all changes, and enforce mandatory reviews by at least two independent developers. A cryptographic signature cannot replace human eyes. Reviewers should look for unexpected file changes, hidden dependencies, and unusual commit patterns.

Second, move the security validation to the CI/CD pipeline. The pipeline should run automated security scans, dependency audits, static analysis, and unit tests on every commit before it reaches production. Treat the repository as untrusted until the automated pipeline verifies the code safety.

Cryptographic Signing in the CI/CD Pipeline

Instead of signing code at the developer's workstation, sign the build artifacts at the end of the CI/CD pipeline. This is known as binary signing or build attestation. Tools like Cosign and Sigstore allow you to cryptographically sign container images and binaries once they pass all automated tests.

This approach shifts the trust anchor from individual developers to the verified build process. A signed build artifact proves that the code went through the required scanning, testing, and approval steps. It guarantees that nobody bypassed the pipeline to push code directly to production.

Here is a simple example of how you might verify commit signatures programmatically in a TypeScript helper script to ensure only verified commits are processed.

import { execSync } from "child_process";
 
interface CommitVerification {
  commitHash: string;
  isSigned: boolean;
  signerName?: string;
  keyFingerprint?: string;
  isValid: boolean;
}
 
export function verifyCommit(hash: string): CommitVerification {
  try {
    const output = execSync(
      `git show -s --format="%G?|%GS|%GF" ${hash}`,
      { encoding: "utf8" }
    ).trim();
 
    const [status, signer, fingerprint] = output.split("|");
 
    const isSigned = status !== "N";
    const isValid = status === "G";
 
    return {
      commitHash: hash,
      isSigned,
      signerName: signer || undefined,
      keyFingerprint: fingerprint || undefined,
      isValid,
    };
  } catch (error) {
    return {
      commitHash: hash,
      isSigned: false,
      isValid: false,
    };
  }
}

Using this verification function, you can block deployment pipelines if the latest commit hash fails verification. While this checks the cryptographic signature, it should be the starting point of your validation process, not the entirety of it. Combining this signature check with automated static analysis and code review gates is the only way to establish true trust.

FAQ

Yes, commit signing prevents basic commit spoofing. Without signing, anyone can configure their local Git client to use your name and email address, making it look like you authored a commit. Signed commits prevent this because the attacker cannot generate a valid signature without your private key.

No. Commit signing is still useful for preventing author identity spoofing. However, you should not treat it as a complete security solution. Use it to establish identity, but rely on branch protection, code reviews, and automated CI/CD security scanning to verify code safety.

The best alternative is build attestation and binary signing (using tools like Sigstore). Instead of signing individual commits, sign the final compiled artifacts or container images inside a secure CI/CD pipeline after all security checks and tests have successfully passed.

Attackers bypass them by compromising the developer's local machine. Once inside the system, they can use the developer's unlocked keys (often cached in memory by agents) to sign malicious code. The signature remains cryptographically valid even though the code is malicious.

DR

Dian Rijal Asyrof

Writes about useful AI tools, programming practice, and the craft of building reliable software.

Previous articleGLM 5.2 vs GPT-4o-mini: The Inference Cost WarNext articleEU Pushes Chat Control Back Through the Fast Track. Here's Why Encryption Is in Trouble Again.
GitSecuritySoftware EngineeringBest Practices
On this page↓
  1. What Signed Commits Actually Prove
  2. The Local Machine Compromise
  3. The Fallacy of Identity-Based Trust
  4. The Verification Gap on Code Hosting Platforms
  5. Practical Defense-in-Depth for Git Repositories
  6. Cryptographic Signing in the CI/CD Pipeline
  7. FAQ
  8. Does commit signing prevent commit spoofing?
  9. Should we stop using commit signing entirely?
  10. What is the best alternative to commit signing?
  11. How do attackers bypass verified commit signatures?

On this page

  1. What Signed Commits Actually Prove
  2. The Local Machine Compromise
  3. The Fallacy of Identity-Based Trust
  4. The Verification Gap on Code Hosting Platforms
  5. Practical Defense-in-Depth for Git Repositories
  6. Cryptographic Signing in the CI/CD Pipeline
  7. FAQ
  8. Does commit signing prevent commit spoofing?
  9. Should we stop using commit signing entirely?
  10. What is the best alternative to commit signing?
  11. How do attackers bypass verified commit signatures?

See also

Illustration for GitHub's Advisory Database Hit 1,560 CVEs in May. Here's Why That Matters.
Software Engineering/Jun 30, 2026

GitHub's Advisory Database Hit 1,560 CVEs in May. Here's Why That Matters.

GitHub's Advisory Database processed 5x its normal volume in May. Private vulnerability reports jumped from 550 to 3,000 per week. Here's the impact and how teams should respond.

3 min read
Software EngineeringSecurity
Illustration for 7 Git Mistakes Every Developer Keeps Making
Programming/Jun 28, 2026

7 Git Mistakes Every Developer Keeps Making

After two years of using Git and watching developers struggle with it, these are the mistakes I see most often and how to avoid them.

4 min read
GitVersion Control
Illustration for The Definitive Guide to Test-Driven Development for Modern TypeScript Projects
Software Engineering/Jun 28, 2026

The Definitive Guide to Test-Driven Development for Modern TypeScript Projects

Master Test-Driven Development (TDD) in TypeScript. Learn the Red-Green-Refactor cycle, practical patterns, and build robust, maintainable code with confidence.

5 min read
TDDTypeScript