⚡ Lightning Talk

Git-ratchet: Tooling for Git Commit Transparency

Cryptographic forward-only protection for Git branches and tags

Ben Birt  ·  github.com/project-oak/git-ratchet

Transparency.dev Summit · 2026
Threat Model

Git's Integrity Gap & Threat Model

Adversary assumption: An attacker with the ability to rewrite Git history and update refs (compromised maintainer/CI key, malicious insider, or untrusted Git host).

Without git-ratchet

How Standard Git Is Vulnerable

  • Refs are mutable pointers — don't trust them: Branches (main) and tags (v2.1.0) can be repointed at any time without leaving a trace.
  • 1. Silent modification & cover-up: Force-push a backdoor or move a tag, let victims pull, then move it back—once GC runs, all evidence is gone.
  • 2. Split-view attacks: A compromised host serves a tampered branch or tag to one target while showing a clean repo to everyone else.
With git-ratchet

What git-ratchet Guarantees

  • Branches are a forward-only ratchet: Every logged commit must descend from the previous one. Rewriting history breaks verification permanently.
  • Tags are immutable pins: Once logged, repointing a tag to a second object hash is rejected.
  • Split-view resistance: Independent witnesses cosign checkpoints over the ref log, ensuring a single global history.
main @ c3 ↑ advance ✗ rollback

Like Certificate Transparency: Attacks (such as pushing a bad commit) are still possible — but they cannot be hidden afterwards.

Architecture

One C2SP Transparency Log Per Repository

Early git-ratchet required a bespoke Git-aware witness. Now, each repository keeps a single C2SP transparency log (refs/ratchet/log) inside the repo—operated via three CLI subcommands:

Upstream Repo / CI

1. git-ratchet log

Appends a ref-record/v1 entry (<ref> <hash>) to the in-repo log at refs/ratchet/log.

Upstream Repo / CI

2. git-ratchet checkpoint

Signs the log head as a tlog-checkpoint and collects cosignatures from C2SP witnesses.

Downstream Consumer

3. git-ratchet verify

Verifies the checkpoint against a tlog-policy and walks the logged ref history locally.

Log Entry (written by git-ratchet log under tile/entries/...):

ref-record/v1 refs/heads/main 4f0f30afb02b71590f0b2e0a67f0b846715e1d04

Checkpoint (sent by git-ratchet checkpoint to tlog-witness — zero Git fields):

github.com/project-oak/git-ratchet 42 Ux7DqA1kLZ0mJt9vQhBZ3nR8sYcW2FpKdE6TgNvXjHo= — project-oak/git-ratchet+a1b2c3d4 <origin sig> — witness1+e5f6a7b8 <tlog-cosignature>
Separation of Concerns

How the Ratchet Works: Witnesses vs. git-ratchet verify

Standard witnesses enforce append-only history; the client verifier enforces Git graph rules over that history:

1. Witnesses: Append-Only Log & No Split Views

Witnesses stay 100% Git-agnostic: they verify RFC 6962 consistency proofs so no logged ref entry can ever be erased or forked, and attach timestamped cosignatures.

2. git-ratchet verify: Git Fast-Forward & Tag Rules

Walks every entry for the ref in the witnessed log [0, size) and checks the local commit graph to verify that branches only fast-forward and tags never move.

No Scrubbing Git History

Once a commit is in the witnessed log, removing that commit from Git (via force-push or tag move) breaks git-ratchet verify's ancestry walk against the logged entry.

Verifying Full Log History

Because an attacker can also append arbitrary entries to the log itself (and witnesses will cosign them), git-ratchet verify walks the entire log history for the requested ref—not just the latest entry.

Future: Recorded Rewrites

Logging typed entries to a t-log enables future recorded history rewrites (e.g. court-ordered removals) without changing witnesses. Not built yet—requires careful thought on the exact policy model.

Specification Alignment

What Is (and Isn't) Interoperable with C2SP.org

✓ 100% Standard C2SP Specs
  • tlog-checkpoint — Standard 3-line body with zero Git fields (safe for private repos on public witnesses).
  • tlog-witness — Any existing C2SP HTTP witness can cosign unmodified.
  • signed-note & tlog-cosignature — Ed25519 & post-quantum ML-DSA-44 (timestamped).
  • tlog-policy — Standard log / witness / group / quorum policy grammar.
  • tlog-tiles (Entry Bundles) — Standard tile/entries/<path> bundles + RFC 6962 hashing.
🔧 git-ratchet Specifics & Adaptations
  • In-Repo Git Storage (No Hash Tiles): Stored as a Git commit tree at refs/ratchet/log instead of an HTTP tile server; omits tile/<level>/... hash tiles since every clone holds all entries locally.
  • Leaf Payload (ref-record/v1): Canonical 2-line entry payload inside the opaque tlog-tiles entry bundles (unrecognised entry types are ignored).
  • Domain Verifier (git-ratchet verify): Walks the witnessed log prefix and checks Git commit DAG ancestry & tag immutability.
  • Optional github-issue:// Transport: Custom http.RoundTripper carrying standard message/http add-checkpoint requests/replies via GitHub Issues + Actions.
Wrap-Up

Thank You

Questions?
Speaker Notes · press N to toggle · press P for Presenter View