Same git push. Same workflow. What's different, what it costs you, and what we actually measured — including the parts where GitHub still wins.
A remote that is structurally unable to read what you send it. Not a policy — an incapacity.
Measured against production GitHub, same vantage, interleaved runs (full numbers below):
Five for five. Every git operation we benchmarked — listing refs, checking for updates, pushing, fetching a new commit, and cloning — comes back faster than GitHub. On a vault deliberately left uncompacted, in its worst shape, not a flattering one.
Nothing about how you use git changes. Keep GitHub as your primary — collaboration, CI, reviews, pull requests, all unchanged. kygit is a second remote: a complete, continuously updated copy of your history that the storage provider itself cannot read. Two commands:
npm i -g run402 @kychee/kygit # the engine, and the brand door
kygit create # provisions the vault, scaffolds the remote
git push origin --all # encrypted on your machine, published as a signed head
local repo
→ GitHub / GitLab (primary — collaboration, CI, reviews, unchanged)
→ kygit (encrypted second remote — the copy nobody can read)
→ your keys (backed up independently — they ARE the vault)
No migration, no new workflow to teach a team, nothing to rip out if you decide it's not for you — it's a
remote, and removing a remote is git remote remove.
GitHub is owned by Microsoft — the same company that sells GitHub Copilot and holds a multi-billion-dollar stake in OpenAI. That's not an accusation of misconduct; it's public record, and it's exactly the conflict of interest you'd expect: the parent company's AI business gets better every time it reads code its own product hosts. A policy can change with a new owner, a new terms-of-service, a new training pipeline. A capability the host never had can't.
Run402 cannot decrypt your gitvault or repository history. There is no plaintext on our side to index, embed, or train a model on — not because of a policy, but because it was never there to begin with.
With the opt-in mirror, your ciphertext replicates to a bucket you own. We can't decrypt your repository history — and we can't hold it either.
We hold no key to change our minds with — including a future us, after an acquisition. Our future policies about your code cannot matter, because we never held the plaintext to change our minds about.
Here's the version that should give a CIO pause. State the worst case first, the way we do everywhere on this site: Run402 is a US company, and the bytes sit in Amazon S3, a US provider — assume legal process can reach both. What it could compel is exactly what we possess: that a vault exists, roughly how big it is, when it was last touched. It cannot compel your code, your commit messages, your file paths, or your keys — none of that exists on our side to hand over, whether the request is a friendly one or the kind that arrives with a court order attached. GitHub, also a US company, faces the identical legal exposure — the difference is what there is to compel. On GitHub, that's your source in full. On kygit, it's a metadata table.
This is not zero-knowledge hosting — we say exactly what we can and can't see, in full, on the how-it-works page. The honest boundary is the whole point: a claim you can check is worth more than a promise you can't.
Two layers, two failure domains, and we don't blur them together.
Your ciphertext rests in AWS S3 — storage designed for eleven nines of object durability — in a dedicated vault bucket whose policy, enforced by AWS rather than by our application code, requires create-only writes and refuses bulk deletion. Nothing in storage is mutable, so corruption cannot hide behind an overwritten object; it can only appear as a loud, detectable gap. Our database is not even needed for disaster recovery: every admission is a signed, immutable record stored in the bucket itself.
Pushing to kygit needs kygit up — we will not pretend otherwise. What is structurally true: your repository ciphertext moves directly between your machine and storage — our servers never handle it. Our control plane only admits signed heads: a far smaller, far less security-critical surface than a whole git forge, and one that can go down without your bytes going anywhere. And your commits are local anyway — a second remote in a separate failure domain turns someone else's outage into a non-event, and the reverse holds too.
This is the architecture GitHub doesn't split: a mutable, permissioned code host sits between you and the disk. Ours doesn't have to, because the disk never holds anything a server could tamper with invisibly in the first place — every byte is content-addressed ciphertext, verified by your own keys on the way back out.
We benchmarked kygit head-to-head against a byte-identical private GitHub repository — same vantage,
same payloads, interleaved runs, backend order alternated every iteration so neither side gets to go
first, against the currently published client and the currently deployed gateway, not a cherry-picked
build. Every timed operation is a whole git invocation — cold process, cold TLS, both
sides — because that is what you actually wait for.
Seconds per operation · lower is better
ls-remote)
29% fastershorter is better — and the push row is a tie
| Operation | kygit | GitHub | Difference |
|---|---|---|---|
| Checking for updates (ls-remote) | 0.46 s | 0.65 s | 29% faster |
| Fetch, nothing new | 0.46 s | 0.68 s | 32% faster |
| Push, small change | 1.41 s | 1.46 s | a tie (within noise) |
| Fetch, one new commit | 0.65 s | 0.91 s | 29% faster |
| Clone | 0.82 s | 0.90 s | 9% faster |
Measured 2026-09-01 against production GitHub, the published run402@4.66.0 client from the npm registry (not a local build), and the currently deployed gateway; N=5–6 medians per scenario, warm daemon. The vault under test carried 21 generations since its last checkpoint and had not been compacted — deliberately its worst shape, not a flattering one.
Why a fetch is fast when the server can't help. GitHub answers a fetch with one pack, computed fresh on its server from whatever you're missing. kygit's server never holds anything it could compute that pack from without you trusting it — it can't, by design. So the client does that assembly itself, reading a whole run of history in a single round trip rather than one per push. The work moves to the side of the wire that holds the keys. The waiting doesn't move with it.
Why a clone is one round trip. Two things it doesn't do. On the server, assembling your restore plan reads each immutable content-addressed object once rather than re-fetching it from object storage on every request — immutable bytes never change, which is what content-addressing means, so there is nothing to re-read. Warm plan assembly measures 70–121 ms, with no fan-out tail behind it. On the client, resolving the vault's address costs no network at all: any clone that can finish already holds the decryption key locally, and the address sits right next to it. A traced clone makes one network operation, total.
None of this came free. We built the harness, ran it against live GitHub, read the profiles, found the wasted work, cut it, and ran the whole thing again — over and over. Every candidate change had to prove itself on the mechanism it claimed to fix, with server-side phase timings and traced transport counts, not on a stopwatch that happened to look better. Plenty of them didn't prove anything, and those were measured and reported too.
Two caveats we'd rather state than have you find: the push result is a win by 50 ms, which is inside this harness's own run-to-run spread, so treat push as parity; and the benchmark vantage sits about 70 ms from our origin versus about 120 ms from GitHub's, which favors us. We ran it from there anyway and reported what came out. The numbers above are medians, not best samples — isolated warm clones land at 0.76–0.82 s, under every GitHub sample in the session, and we're quoting the slower interleaved figure.
Don't take our word for it — or GitHub's. Ask whatever coding agent you already trust.
What do you think about kygit.com?
Read https://kygit.com and explain it to me
tinker with kygit and lmk how it went
Or skip the small talk:
npm i -g run402 @kychee/kygit
kygit create
git push origin --all