Skip to content

The Repository Is the Root of Trust

A small Rust project called Auths bets that the entire apparatus of code-signing — certificate authorities, transparency logs, blockchain registries — was always just an elaborate way of avoiding the one tool every developer already runs. The bet is more interesting than it sounds.

In March 2024, a Microsoft engineer named Andres Freund noticed that his SSH logins were running about half a second slow. He went looking. What he found was a backdoor, patiently installed over two years by a "maintainer" named Jia Tan into xz, a compression library so boring and so foundational that it ships inside virtually every Linux distribution on Earth. The payload was designed to hand remote code execution to whoever held a particular private key. It was caught by accident — by a performance-obsessed engineer annoyed at a 500-millisecond delay — roughly two weeks before it would have landed in the stable releases of Debian and Red Hat.

The lesson security people drew from xz was about social engineering and maintainer burnout, and they were right. But there is a colder, more structural lesson underneath it. We had no cryptographic way to answer the simplest question in software: who actually wrote this, and can they prove it? Git commits carry an author field, but that field is a string you type. It is, famously, a lie you can tell about anyone. git commit --author="Linus Torvalds <torvalds@kernel.org>" works on your laptop right now.

The industry's answers to this question are a museum of half-measures. GPG commit signing exists and almost nobody uses it correctly, because GPG's user experience is a war crime and its web-of-trust never achieved escape velocity. SSH signing is better but still leaves you managing key distribution by hand. And the most serious modern attempt — Sigstore, the project behind cosign and npm's package provenance — solved the key-management problem by removing the keys entirely, at the cost of standing up a federated certificate authority (Fulcio) and an append-only transparency log (Rekor) that someone, somewhere, has to operate forever.

Auths — a pre-launch, open-source identity system written in Rust — starts from a heretical premise: that all of this infrastructure exists to work around the fact that developers didn't have a shared, tamper-evident, replicated database to write identity into. Except they do. They've had one since 2005. It's called Git.

The thesis in one sentence

Here is the entire idea: your ~/.auths directory is a Git repository, and every fact about your cryptographic identity — your keys, their entire rotation history, every attestation you've ever signed — lives inside it as Git refs. There is no central server. There is no blockchain. There is no certificate authority. There is no transparency log to operate. Identity is data in a Merkle DAG you already know how to clone, push, and diff.

This is the kind of idea that is either trivial or profound, and you can't tell which until you look at how it's built. So I read the code. What follows is a tour of the machine, because the machine is where the argument actually lives.

The key event log: identity as an append-only history

The conceptual heart of Auths is borrowed from KERI — Key Event Receipt Infrastructure, a protocol that emerged from the decentralized-identity world with one genuinely good idea: your identity is not a key, it's the log of everything that has ever happened to your keys.

In the codebase this log is a GitKel — a Git-backed Key Event Log — and it's stored, with a directness that's almost funny, at the ref path refs/did/keri/{prefix}/kel. Each event in the log is a Git commit. The commits form a linear chain: inception has no parent, and every subsequent event points back at the last one. To replay your identity, the verifier walks the commit chain backward to the beginning and folds the events forward into a KeyState. Your identity history is git log.

There are three event types, and they map cleanly onto the three things that can happen to a key. An inception event (icp) is the genesis block: it declares your first key and commits to your next one. A rotation event (rot) retires the current key and installs the successor. An interaction event (ixn) anchors data — an attestation, a signed commit — without touching the keys at all.

The clever part is how an identity names itself. Auths identities are did:keri: DIDs, and the string after the prefix is not derived from your public key — it's a SAID, a Self-Addressing Identifier, which is a Blake3-256 hash of the inception event itself. The computation, in said.rs, is a small ritual: take the event, replace the digest field d with a 44-character placeholder of # symbols, replace the identifier field i too (since for an inception event the identifier is the digest), strip any detached signatures, serialize, and hash. The resulting 44-character string — an E followed by 43 base64url characters — becomes both the digest and your permanent identifier. Your name is the hash of your own birth certificate. Tamper with any field of the inception event and the name no longer matches the content; the identity is self-certifying by construction.

One detail in that file is worth dwelling on, because it reveals how much care went into this. The serialization for hashing is deliberately insertion-order, not canonical JSON — and there's a comment, and a guard test that fails the build if the JSON map type ever loses its ordering, explaining why: canonical JSON (RFC 8785, sorted keys) would produce different SAIDs and break interoperability with other KERI implementations. Someone thought about cross-ecosystem compatibility at the level of byte-ordering inside a hash preimage. We'll come back to whether that compatibility actually holds.

Pre-rotation: committing to a key you haven't used yet

The single most elegant mechanism in the whole system is pre-rotation, and it's a genuinely good answer to the oldest problem in key management: what do you do when your key is compromised?

In a naive system, if an attacker steals your signing key, they can also sign a "rotation" to a new key they control, and now they are you, permanently. KERI's answer, implemented in rotation.rs, is that at every step you don't just hold your current key — you've already committed, in your last event, to the hash of your next one. The inception event's n field contains Blake3(next_public_key). To rotate, you must present a key whose hash matches that prior commitment; the code calls verify_commitment() and rejects a CommitmentMismatch outright.

The security consequence is sharp. An attacker who steals your current signing key still cannot rotate the identity, because rotation requires the next key — which was generated separately, never used to sign anything, and may sit in cold storage. The active signing key and the rotation-authorizing key are different secrets with different exposure. It is forward-security applied to identity itself. There's even a notion of deliberate death: a rotation that commits to an empty next-key set sets is_abandoned = true, permanently sealing the identity against all future events. You can cryptographically retire a name forever.

Attestations: the dual-signed unit of trust

If the KEL is who you are, the attestation is what you say. It's the load-bearing data structure, and the struct in the verifier crate is dense with intent. An attestation has a version (currently 2 — they bumped it for a curve-agnostic refactor and, being pre-launch with zero users, simply broke the old format rather than carry compatibility cruft), an issuer and a subject, a device_public_key, an expires_at, an optional revoked_at, a list of capabilities (sign_commit, sign_release, manage_members, rotate_keys), and — the crucial pair — an identity_signature and a device_signature.

That last detail is the whole game. Attestations are dual-signed. When a developer's root identity vouches for a new laptop, the resulting attestation is signed both by the identity key and by the device's own key. The signing path canonicalizes the attestation's semantic fields with json_canon (RFC 8785 — note: canonical JSON here, unlike the KEL, because attestations don't need KERI wire-compatibility) and signs the same canonical bytes twice. The verifier checks both. The identity signature proves authorization — "this root vouches for this device" — and the device signature proves possession — "and the device actually holds the key it claims." Neither alone is enough.

This composes into a chain. The verifier's verify_chain() function walks an ordered list of attestations from a known root public key, and it enforces one beautiful invariant: each link's subject must equal the next link's issuer, and the public key that authorizes link N+1 is the device_public_key of link N. Authority flows down the chain like a delegated current. Root identity vouches for laptop; laptop vouches for a CI agent; CI agent signs a release. A verifier with nothing but the root public key can validate the entire delegation by walking the links — and if any issuer→subject seam doesn't match, it returns a BrokenChain with the missing link named.

The verifier that fits anywhere

Here is where the architecture earns its keep. The verification logic lives in auths-verifier, a crate engineered to be embeddable, which in practice means engineered for what it refuses to depend on. It does not pull in git2. It does not pull in an HTTP client. It does not require tokio unless you ask for the FFI feature. Its dependency list is serde_json, json-canon, chrono, the crypto primitives, and the KERI types — and that's nearly it.

The payoff is a verifier that compiles to WebAssembly and to a C FFI surface. The WASM exports have JavaScript-friendly names — verifyChainJson, verifyAttestationJson, verifyArtifactSignature — meaning a browser, a CI runner, or a VS Code extension can verify a signature with no native dependencies and no network calls. The FFI side exposes extern "C" functions like ffi_verify_chain_json that hand a VerificationReport back across the boundary as JSON, so an iOS or Android app — or a git hook written in anything — can link the verifier directly.

This is the structural inversion that makes the "no server" claim real. In Sigstore's model, verification ultimately reaches back toward a transparency log; trust has a network dependency. In Auths, verification is a pure function. Give it the attestation bytes and a root key and it returns Valid, Expired, Revoked, InvalidSignature, or BrokenChain — offline, deterministically, in a sandbox. The trust root is something you pin once, not something you phone home to.

Pairing: the ceremony that became two steps

For all its cryptographic seriousness, the part of Auths that will decide whether anyone uses it is mundane: adding a second device. This is where decentralized-identity projects usually go to die, drowning in QR-code ceremonies and seed-phrase rituals that normal humans abandon.

The git log tells a story of ruthless simplification here — one commit literally reads "simplify pairing and rotation steps from 7 steps to 2," another "strip ceremony to one-line confirm." The current flow: on your laptop you run auths pair. It generates an ephemeral P-256 key, spins up a tiny HTTP server bound to your LAN, and prints a QR code plus a six-character short code (drawn from a base32 alphabet with the confusable characters — 0, O, I, L, 1 — removed). On your phone, you scan or type the code, and the devices complete an Elliptic-Curve Diffie-Hellman handshake over the local network. The QR code carries an auths://pair?... URI packing the controller DID, the endpoint, the ephemeral key, the session ID, the short code, an expiry, and the requested capabilities.

The interesting design judgment is what they did with the SAS — the Short Authentication String, a ten-byte value derived from the shared ECDH secret that protects against a man-in-the-middle. The SAS renders two ways: as six emoji (for visual recognition) and as an authoritative seven-digit number. The maximalist version of this UX forces you to compare the codes on both screens, every time. Auths prints the SAS but, by default, doesn't block on it — treating the QR scan as the authenticated out-of-band channel, exactly the way Signal and WhatsApp treat safety numbers as opt-in. Only auths pair --verify reinstates the mandatory comparison, for users pairing across a network they don't trust. It's the correct call: security that gets switched off because it's annoying provides no security, and the people who genuinely need MITM protection are a flag away from getting it.

The honest part: where this thing is breakable

A credible technical assessment names the sharp edges, and to its considerable credit, Auths names them itself. There is a document in the repo, multi_device_accepted_risks.md, that reads less like marketing and more like a flight-incident report. This is the most trustworthy thing about the project, and it's worth taking seriously.

The duplicity fork. The shared identity KEL — the log that enumerates all your devices — currently runs with a key threshold of one (kt=1). Any single device can sign a rotation. With no witness infrastructure to order events, two of your devices can each author a different valid rotation at the same sequence number, and the log forks — permanently. There is no automatic winner. The system's defense is detection, not prevention: a detect_duplicity() function scans the events, groups them by (prefix, sequence), and returns DuplicityReport::Diverging with the conflicting SAIDs the moment it sees two different events claiming the same slot. The policy is explicitly fail-open — a forked shared KEL raises a warning but does not, by itself, invalidate an otherwise-valid signature. Recovery is manual: you run auths device remove on the device you trust. This is a real, unmitigated gap, and the docs say so in plain language.

No witnesses, no global ordering. A verifier trusts the first valid event it sees locally. There is no network-wide source of truth about which rotation came first. The blast radius is bounded — each device replicates the full shared KEL, so the universe of conflicting claims is your own devices rather than the entire internet — but "trust what you saw first" is a weaker ordering guarantee than a transparency log provides, and it's fair to call it that.

The interop gap. Remember that careful, byte-ordered, KERI-compatible SAID computation? The same risk doc catalogs, with disarming honesty, a list of places where the current wire format diverges from the ToIP KERI v1.1 spec — an in-body timestamp field that leaks into the SAID, a mobile FFI struct that duplicates the event type with an in-body signature, and the use of the 1AAI CESR code (technically the non-transferable P-256 verkey code) for transferable identities. The conclusion the authors draw themselves: "Internally consistent; cross-implementation interop with KERIpy / KERIox / Signify is currently broken." So the KERI compatibility that justified all that byte-ordering care is, today, aspirational. That's a meaningful gap between the design's ambition and its current state, and pretending otherwise would be dishonest.

The bootstrap problem. And underneath all of it sits the question no decentralized identity system fully escapes: the first time you encounter a did:keri:E..., why should you trust it? Auths can prove an identity is internally consistent — that the log is unbroken, the signatures check, the chain is intact. It cannot, by itself, tell you that this identity belongs to the human you think it does. That binding has to come from somewhere external: a verified commit on a public repo, an out-of-band exchange, an organization's published roster. This isn't a bug specific to Auths — it's the irreducible core of the trust-establishment problem — but it's the work that remains after the cryptography is done.

The good news is that the fix for the worst of these is already designed. The roadmap to eliminate the duplicity fork is multi-signature thresholds: move the shared KEL from kt=1 to m-of-n, and the race vanishes by construction, because no single device can produce a rotation that satisfies the threshold alone. Two devices can no longer fork the log because neither one, acting alone, can advance it. The pieces — dual-index CESR signatures, threshold-aware validators, a partial-signing UX — are specced. Whether they ship is, candidly, the question that determines if this is a research toy or an industry primitive.

The market: a real and rising tide

Now the part the skeptics undersell. It is easy to look at a pre-launch project with a duplicity bug and a broken interop story and wave it off. It is harder to look at the market it's aimed at, because that market is large, growing fast, and structurally unsettled in exactly the way that rewards a clean new primitive.

Start with the obvious envelope. The software supply chain security market sat around USD 2.16 billion in 2025 and is tracking toward roughly USD 3.8 billion by 2032 at a low-teens CAGR; broader platform definitions put it at USD 5.53 billion in 2025, heading to USD 10.1 billion by 2030. These are healthy, double-digit growth markets — but they're not the whole prize, because Auths isn't only a supply-chain tool. It's a developer-identity primitive, and the decentralized-identity market is on a different curve entirely: estimates cluster around USD 5–7 billion in 2026 and project past USD 50 billion by the early 2030s at CAGRs north of 50%, pulled forward by regulation like the EU's eIDAS 2.0 wallet mandate. Auths sits in the overlap of these two waves — supply-chain integrity and decentralized identity — which is the most attractive real estate a young primitive can occupy.

And the demand signal underneath the analyst numbers is concrete, not speculative. npm's Sigstore-powered provenance went generally available and, by the numbers, over 16,000 unique packages now publish with provenance, and provenance-enabled versions have crossed hundreds of millions of downloads. That matters enormously for Auths — not as competition, but as proof of appetite. Sigstore did the expensive cultural work of convincing the JavaScript ecosystem that signed provenance is normal and good. A few years ago, "every package should carry a cryptographic provenance attestation" was a security researcher's dream. Today it's a default in the world's largest package registry. The behavior Auths needs already exists in developers' hands.

The regulatory picture is genuinely interesting rather than simply tailwind-shaped. The Biden-era executive orders (14028, then 14144) drove SBOM and signing mandates hard; the 2025–2026 OMB memoranda walked the prescriptive mandates back toward a "risk-based approach," letting agencies choose their own controls. Read pessimistically, that's softening regulatory pressure. Read the way a builder should, it's better for a tool like Auths: a world that demands cryptographic provenance but doesn't dictate the mechanism is a world where the simplest, cheapest, most operationally trivial mechanism wins on merits rather than on a compliance checkbox. Mandates favor incumbents with compliance teams. Open competition on cost and ergonomics favors whoever has the lowest-friction primitive. SLSA adoption, meanwhile, keeps climbing on its own momentum — Docker's Hardened Images ship SLSA Level 3 provenance by default — which means the concept of build-and-identity provenance is being normalized by the biggest names in the ecosystem regardless of which administration holds the pen.

Put the pieces together and the market thesis is neither hype nor hand-waving. The behavior is proven (16,000 packages signing today). The budgets are real and compounding (two overlapping markets, both double-digit-or-better growth). The regulatory environment has shifted from mandate-driven to merit-driven, which favors the low-friction challenger. And the total addressable population isn't "enterprises that buy security platforms" — it's every developer who makes a Git commit, which is the largest identity market that has ever existed and one that no incumbent has cleanly captured.

How you actually unseat the incumbents

Disruption stories are usually told as feature-versus-feature. The real ones are almost always cost-structure stories, and that's where Auths has its sharpest argument.

Sigstore's keyless model is genuinely excellent, and its great strength — no long-lived keys — is purchased with a permanent operational liability: Fulcio and Rekor are services that must run, scale, and stay honest in perpetuity. The public-good instances are heroically maintained by the OpenSSF and a handful of sponsors, but the moment you want your own trust root — a private enterprise that doesn't want its internal release graph in a public transparency log — you are now operating CA and transparency-log infrastructure yourself. That's a team, a budget, an on-call rotation, a thing that can go down.

Auths's structural bet is that zero infrastructure beats elegant infrastructure for a very large slice of users. There is no service to run because the substrate — Git — is already running everywhere, already replicated, already backed up, already understood by every developer alive. The verifier is a pure WASM function with no network dependency. An enterprise that wants a private trust root doesn't deploy anything; it pins a root public key. This is the classic disruption shape: arrive underneath the incumbent with something that looks like a toy (no transparency log? no global ordering?), serve the users the incumbent's complexity priced out (the team that wants signed commits but will never stand up Fulcio), and climb. The multi-sig threshold work is the climb — the feature that lets it move from "signed commits for individuals and small teams" up into the high-assurance, can't-fork, recover-from-a-stolen-laptop territory where the serious money is.

Against GPG, the contest isn't even close: GPG's failure was never cryptographic, it was ergonomic, and a two-step pairing flow with emoji safety numbers is from a different century of usability. Against raw SSH signing, Auths offers what SSH lacks — rotation history, delegation chains, revocation, and capability scoping — without asking the user to hand-manage signer allowlists. And against blockchain identity systems (ENS, did:ion, the whole on-chain DID menagerie), the pitch is that it delivers the decentralization those systems promise without the gas fees, the latency, the consensus layer, or the requirement that the planet agree on a single ledger. You don't need the world to agree on an ordering if your trust roots are pinned and your verification is local.

The one bet that decides everything

Strip away the cryptographic craftsmanship — the pre-rotation, the self-addressing identifiers, the dual-signed chains, the embeddable verifier — and Auths comes down to a single wager about where the root of trust should live. The incumbents say it lives in infrastructure: in a CA you federate, a log you append to, a chain you reach consensus on. Auths says it lives in a place developers already trust with the entire history of everything they've ever built — the repository itself.

The weaknesses are real and the authors, refreshingly, refuse to hide them. The kt=1 fork is a live wound. The KERI interop is currently broken. The bootstrap problem is unsolved, as it is everywhere. But these are the weaknesses of a project that has made its hard architectural choices and is executing against a clear-eyed list, not the vagueness of a project that hasn't figured out what it is. The threshold-signature upgrade is the hinge: ship it, and the most dangerous gap closes by construction, and the "just Git and cryptography" pitch acquires the high-assurance teeth it needs to climb upmarket.

The supply-chain attacks aren't slowing down. The budgets are compounding. The behavior — sign your code, prove who you are — has already gone mainstream on the back of Sigstore's cultural groundwork. The open question was never whether developers would accept cryptographic identity. xz settled that. The open question is what it will cost them to adopt it. Auths's answer is the most aggressive one on the table: nothing you don't already run. If that holds up under the weight of the threshold work, the root of trust may turn out to have been sitting in ~/.git the entire time, waiting for someone to notice.


Sources

  • Verified Market Research — Software Supply Chain Security Market: https://www.verifiedmarketresearch.com/product/software-supply-chain-security-market/
  • Mordor Intelligence — Software Supply Chain Security Platforms Market: https://www.mordorintelligence.com/industry-reports/software-supply-chain-security-platforms-market
  • Mordor Intelligence — Decentralized Identity Market: https://www.mordorintelligence.com/industry-reports/decentralized-identity-market
  • Sigstore Blog — npm provenance goes GA: https://blog.sigstore.dev/npm-provenance-ga/
  • AquilaX — Software Supply Chain Security Beyond SBOMs (Sigstore, SLSA, provenance): https://aquilax.ai/blog/supply-chain-artifact-signing-slsa
  • Dark Reading — Trump Administration Rescinds Biden-Era SBOM Guidance: https://www.darkreading.com/application-security/trump-administration-rescinds-biden-era-sbom-guidance