The Three Paths to Signing a Commit

There are three credible ways to sign a Git commit in 2026. Each makes a different architectural bet about where identity comes from, where keys live, and what happens when things go wrong.

This post walks through the actual mechanics of each — not the marketing, but the steps, the dependencies, and the failure modes. If you're choosing a signing strategy for your team or project, this is the comparison we wish existed when we started building.

Path 1: GPG

GPG commit signing has been available since Git 1.7.9 (2012), with Git 2.0 (2014) adding the commit.gpgsign option to sign all commits by default. It's the oldest and most widely supported path.

The setup ceremony

7 steps
Generate KeyInteractive prompt
Find Key IDlist-secret-keys
Signing Keygit config
Enable Signgpgsign true
Export Key--armor --export
Upload KeyGitHub / GitLab
KeyserverOptional

That's 7 steps, at least one interactive prompt, and a 4096-bit RSA key that will live on your machine until you forget about it.

The signing flow

Developer
Git
GPG Agent
git commit -S -m "fix"
sign payload
decrypt private key (passphrase prompt or cached)
return signature
commit stored (signature in header)

The verification flow

Verifier
Git
GPG Keyring
git verify-commit <SHA>
lookup public key
key found? verify signature, check trust level
GOOD / WARNING / BAD / "no public key"

What breaks

Key management is manual and permanent. A GPG key generated in 2020 is still valid in 2026 unless you explicitly revoke it. Most developers never set an expiry. If the key is compromised, the attacker can sign commits as you indefinitely.

No key rotation without losing identity. Rotate your GPG key and — unless the old public key is still in the verifier's keyring — your old commits show "unknown key" or "untrusted." Even if you keep the old key around for verification, there's no cryptographic mechanism to say "this new key is the successor to that old key." The key IS the identity. Change the key, lose the identity chain.

The web of trust never worked. GPG's trust model requires key signing parties and manual trust assignments. In practice, nobody does this. GitHub bypasses it entirely by checking "does this key belong to a GitHub account?" — which is just centralized identity with extra steps.

Cross-device is painful. Using the same GPG key on your laptop and your workstation means either copying the private key between machines (bad) or setting up GPG agent forwarding (fragile). CI runners need a separate key entirely, usually injected as a secret with no rotation policy.

The actual numbers

Setup steps7
Key ceremonyinteractive, 2-5 minutes
Keys to manage per device1 (or copy between devices)
Key rotationbreaks old commit verification
Verification dependenciesGPG keyring + manual trust
Offline verificationyes (if you have the public key)
Post-quantum migration pathgenerate new key, lose old identity

Path 2: Sigstore (Gitsign)

Sigstore's Gitsign appeared in 2022. It eliminates key management by using ephemeral keys tied to OIDC identity.

The setup ceremony

4 steps
Installbrew install gitsign
Set Programgpg.x509.program
Set Formatgpg.format x509
Enable Signgpgsign true

Setup is simpler — 4 config commands, no key generation. But the signing flow introduces new dependencies.

The signing flow

Developer
Gitsign
Fulcio
OIDC
Rekor
git commit
generate ephemeral keypair
request certificate
verify OIDC token (browser opens)
token valid
short-lived certificate
sign commit with ephemeral key
record in transparency log
discard key
commit stored

Five participants in the signing flow. One of them opens your browser.

The verification flow

Verifier
Git
Rekor
Fulcio Root
git verify-commit <SHA>
lookup entry in Rekor
entry + certificate
verify cert chain to root
valid
verify signature with cert key
GOOD

What breaks

Network required for signing. Every commit triggers an OIDC flow, a Fulcio certificate request, and a Rekor log entry. If any of these services are down, you can't sign. If you're on a plane, you can't sign.

Identity is borrowed. You are who your OIDC provider says you are. Your signing identity is alice@company.com as attested by Google. If Google's infrastructure has a bad day, or if your IT admin removes your account, your signing identity disappears.

No key rotation — because there are no keys. This is presented as a feature, and for many use cases it genuinely is. But it also means there's no concept of "identity continuity." Each signing event is independent. There's no cryptographic chain connecting your commit from January to your commit from March. They're linked only by the email address your OIDC provider vouches for.

Verification usually depends on infrastructure. Gitsign embeds the Rekor inclusion proof and Fulcio certificate directly in the commit signature payload, so offline verification works if the verifier has the Fulcio root CA cached. In practice, many verification paths still fall back to querying Rekor, but the offline story is better than it first appears.

The CI story is the strong case. Sigstore shines in CI/CD where OIDC tokens are already available (GitHub Actions OIDC, Google Cloud Workload Identity). No secrets to manage, no keys to rotate. For automated workflows that are always online, the dependency on Fulcio and Rekor is a non-issue.

The actual numbers

Setup steps4
Key ceremonynone (ephemeral)
Keys to manage per device0
Key rotationN/A (no persistent keys)
Verification dependenciesFulcio root cert (Rekor bundle embedded in signature)
Offline verificationyes (if Fulcio root cached; Rekor bundle is embedded)
Post-quantum migration pathredesign log format, re-sign or drop history

Path 3: Auths

Auths uses KERI Key Event Logs for self-sovereign identity stored in Git refs.

The setup ceremony

1 command
auths initKeys + config + keychain

One command. Non-interactive by default. The key goes into your OS keychain (macOS Keychain, Linux Secret Service, Windows Credential Manager). Git signing is configured automatically.

The signing flow

Developer
Git
OS Keychain
git commit -m "fix"
sign payload
unlock key (biometric or cached session)
signature
commit stored

Three participants. No network calls. No browser redirects. No external services.

The verification flow

Verifier
Git
Auths Verifier
auths verify <SHA>
read KEL from refs/did/keri/
replay log: inception → rotations → pre-rotation → current key
verify commit signature against derived key
GOOD (+ full key history chain)

No network calls. No certificate authority to contact. No transparency log to query. The verifier replays the key event log — a purely mathematical operation — and checks the commit signature against the derived current key.

What breaks

No ecosystem integration yet. Sigstore is in npm, PyPI, Homebrew, and Kubernetes. Auths is new. The verification widget works in browsers (WASM), and there's a GitHub Action, but the ecosystem gap is real.

Discovery requires the KEL. To verify someone's identity, you need their key event log. If their repo is public, you clone it. If it's private, they need to export an identity bundle. There's no global directory like Sigstore's Rekor where you can look up anyone's signing history. This is by design (decentralization), but it's a UX tradeoff.

Younger codebase. Sigstore has years of production hardening across major package registries. Auths has been in development for months. The cryptographic primitives are proven (Ed25519, KERI, Blake3), but the implementation is young.

The actual numbers

Setup steps1
Key ceremonyautomatic, < 1 second
Keys to manage per device0 (OS keychain)
Key rotationpreserves old commit verification
Verification dependenciesnone (offline, self-contained)
Offline verificationyes (fully)
Post-quantum migration pathrotate key (identity preserved)

Side by side

GPGSigstoreAuths
Setup7 steps, interactive4 steps, config only1 step, automatic
Signing needsGPG agentFulcio + OIDC + RekorOS keychain
Network required to signnoyes (3 services)no
Network required to verifyno (if you have the key)no (bundle embedded; Rekor fallback)no
Key rotationbreaks historyN/A (no keys)preserves history (pre-rotation)
Identity modelkey = identity (fragile)email = identity (borrowed)KEL = identity (self-sovereign)
Multi-devicecopy key or agent forwardlogin on each devicecryptographic device pairing
CI/CDsecret injectionOIDC token (great fit)scoped credential (time + capability bounded)
Post-quantumnew key = new identityredesign log formatrotate key, same identity
Offline air-gapyesnoyes
Who can revoke your identityyou (if you remember)OIDC provider (account deletion)you (only you)

The architectural point

These three systems aren't just different tools. They make fundamentally different claims about what identity means.

GPG says: you are your key. If you lose the key, you lose the identity. If someone else gets the key, they become you.

Sigstore says: you are your account. Google or GitHub vouches for you. The keys are ephemeral and irrelevant. This is practical and it's the reason Sigstore succeeded where GPG key signing ceremonies never did.

Auths says: you are your history. Your identity is the full sequence of cryptographic events — inception, rotations, delegations — chained together and self-verifying. Keys come and go. Devices come and go. The log is the invariant.

The right choice depends on your threat model. If you trust your OIDC provider and want zero key management, Sigstore is excellent. If you need offline verification, key rotation without identity loss, or sovereignty over your own identity, the Auths approach gives you that.

We built Auths because we wanted the third option to exist. You can try it now:

Rust:

cargo install auths-cli
auths init
auths sign HEAD
auths verify HEAD

Python SDK:

pip install auths-dev

The code is at github.com/auths-dev/auths. The verifier runs in your browser. We're interested in where this analysis is wrong.