Every commit pushed to a shared repository carries an implicit claim about authorship, but without cryptographic verification, anyone can forge another developer’s identity in the commit log. Git commit signing solves this by attaching a cryptographic signature to each commit, proving that the code originated from a trusted key holder.
In this guide, we compare three approaches to Git commit signing — the traditional GPG/PGP method, the modern SSH-based signing built into Git 2.34+, and Sigstore cosign for keyless, cloud-native signing — helping you choose the right approach for your team and self-hosted infrastructure.
Why Sign Git Commits
Unsigned commits create several risks in collaborative development:
- Identity forgery: Any developer can commit with any name and email address, making it impossible to verify who actually wrote the code
- Supply chain attacks: Malicious actors can inject code under the guise of a trusted maintainer, as demonstrated by the 2024 xz Utils backdoor incident
- Compliance requirements: Industries like healthcare, finance, and government increasingly require cryptographic proof of code provenance
- Merge integrity: Signed commits prevent tampering during the merge process, ensuring the code you review is exactly what gets deployed
For teams running self-hosted Git platforms like Gitea, Forgejo, or GitLab, local signing verification provides an additional layer of trust that doesn’t depend on third-party services.
GPG/PGP Commit Signing
GPG (GNU Privacy Guard) is the traditional and most widely supported method for signing Git commits. It uses OpenPGP keys to create detached signatures that Git embeds in each commit object.
How It Works
When you sign a commit with GPG, Git creates a cryptographic hash of the commit content and signs it with your private key. The signature is stored alongside the commit, and platforms like GitHub, GitLab, and Gitea can verify it using your public key.
Setup
| |
For automated signing on CI/CD runners:
| |
Docker Compose: Self-Hosted GPG Key Server
| |
Pros and Cons
| Feature | Assessment |
|---|---|
| Compatibility | Universal — supported by all Git platforms since 2013 |
| Key management | Manual — you manage key generation, distribution, and revocation |
| Key expiration | Configurable — keys can expire and be rotated |
| CI/CD integration | Complex — requires secure key injection into pipelines |
| Learning curve | Moderate — GPG concepts (web of trust, subkeys) can be confusing |
SSH Commit Signing
Starting with Git 2.34 (Q4 2021), Git can use SSH keys to sign commits. This eliminates the need for GPG entirely, leveraging the SSH keys most developers already have.
How It Works
Git uses your SSH private key to sign commit content via the ssh-keygen -Y sign mechanism. The signature format is compatible with SSH’s existing ssh-keygen -Y verify tool, making verification straightforward.
Setup
| |
Docker Compose: SSH Signing Key Management Service
| |
Pros and Cons
| Feature | Assessment |
|---|---|
| Compatibility | Requires Git 2.34+ — widely available but not universal |
| Key management | Familiar — SSH keys are already managed by most teams |
| Key rotation | Simple — replace the key file and update allowed_signers |
| CI/CD integration | Easy — SSH keys are natively supported by most CI systems |
| Learning curve | Low — if you already use SSH, there’s little new to learn |
Sigstore Cosign for Commit Signing
Sigstore cosign brings keyless signing to Git commits, using OpenID Connect (OIDC) identity tokens tied to short-lived certificates. This approach eliminates key management entirely.
How It Works
When you sign a commit with cosign, it authenticates you through an OIDC provider (Google, GitHub, Microsoft), obtains a short-lived certificate from Fulcio (Sigstore’s certificate authority), and uses it to sign the commit. Verification happens through Rekor, Sigstore’s transparency log, which provides an immutable record of all signatures.
Setup
| |
Docker Compose: Self-Hosted Sigstore Fulcio and Rekor
| |
Pros and Cons
| Feature | Assessment |
|---|---|
| Compatibility | Requires cosign — not natively supported by Git yet |
| Key management | Zero — keys are ephemeral, identity comes from OIDC |
| Key rotation | Automatic — certificates expire in minutes |
| CI/CD integration | Excellent — native support in GitHub Actions, GitLab CI |
| Learning curve | Moderate — OIDC concepts and Sigstore ecosystem require understanding |
Comparison Table
| Feature | GPG/PGP | SSH Signing | Sigstore Cosign |
|---|---|---|---|
| Git version required | 1.7.9+ | 2.34+ | Any (external tool) |
| Key management | Manual (GPG keyring) | Manual (SSH files) | Automatic (OIDC) |
| Key expiration | Configurable | Manual rotation | Minutes (ephemeral) |
| Platform support | GitHub, GitLab, Gitea, Forgejo | GitHub, GitLab, Forgejo | Limited (via cosign) |
| CI/CD friendliness | Moderate (key injection) | High (SSH native) | Excellent (OIDC native) |
| Self-hosted friendly | Yes | Yes | Partial (need Fulcio/Rekor) |
| Transparency log | No | No | Yes (Rekor) |
| Learning curve | Moderate | Low | Moderate-High |
Choosing the Right Signing Method
For individual developers or small teams, SSH signing offers the best balance of simplicity and security. You likely already have SSH keys, and Git’s native support means no additional tooling.
For enterprise environments with compliance requirements, GPG remains the gold standard. It has the broadest platform support and integrates with existing PKI infrastructure through X.509 certificate signing.
For CI/CD pipelines and automated workflows, Sigstore cosign’s keyless approach eliminates the risk of long-lived signing keys being compromised in your build infrastructure. The transparency log also provides an audit trail that GPG and SSH cannot match.
Many organizations adopt a hybrid approach: SSH signing for developer commits, cosign for CI/CD pipeline commits, and GPG for release tags that require long-term verifiability.
FAQ
Do I need to sign every commit?
For high-security projects, yes — enabling commit.gpgsign true ensures every commit is signed. For lower-security projects, you can sign selectively with git commit -S or sign merge commits only with merge.gpgsign true.
Can I use an existing SSH key for commit signing?
Yes, but it’s recommended to create a dedicated signing key. Reusing your authentication key means any compromise of your signing key also compromises your server access. Generate a separate key with ssh-keygen -t ed25519 -C "commits@yourdomain.com".
How does Sigstore cosign work offline?
Cosign requires internet access for the OIDC authentication flow. For air-gapped environments, you can use cosign sign with a local key (COSIGN_KEY environment variable) instead of the OIDC flow, though this sacrifices the keyless benefit.
Will signed commits slow down Git operations?
Negligibly. GPG signing adds approximately 50-200ms per commit, SSH signing adds 10-50ms, and cosign adds 1-3 seconds (due to OIDC authentication). For most workflows, this overhead is imperceptible.
Can I backdate a signed commit?
Yes — git commit --date="2024-01-01T00:00:00" -S will create a signed commit with a custom date. However, the signature covers the commit content including the date, so any post-signing modification will invalidate the signature.
How do I migrate from GPG to SSH signing?
Set gpg.format ssh in your Git config, point user.signingkey to your SSH public key file, and create an allowed_signers file. Existing GPG-signed commits remain valid — the signature format is stored per-commit, not globally configured.
What happens if I lose my signing key?
For GPG: generate a new key, update your Git config, and revoke the old key on keyservers. For SSH: generate a new key and update allowed_signers. For cosign: nothing — keys are ephemeral and regenerated per-signing session.
Why Self-Host Your Commit Signing Infrastructure?
Running your own Git signing verification infrastructure gives you complete control over key management, identity verification, and audit trails. When you self-host platforms like Gitea or Forgejo with integrated signature verification, you eliminate dependency on third-party services for validating commit authenticity.
For organizations handling sensitive intellectual property, self-hosted signing verification ensures that commit signatures never leave your infrastructure. Combined with internal GPG keyservers or Vault-based SSH key management, you maintain a complete chain of custody from code creation through deployment.
For teams already running self-hosted CI/CD, integrating commit signing into your pipeline means automated verification before code reaches production. This is especially valuable when combined with supply chain security tools and Git platform security practices.
For organizations managing complex deployment pipelines, Git hooks management can enforce signing policies automatically, ensuring no unsigned commit reaches your main branch.