zkgit Alpha · invite only

Git hosting that can’t read your code.

Every object is encrypted on your machine before it leaves it. The server stores ciphertext under opaque IDs and holds no key to any of it — not to your files, not to your filenames, not to your commit messages, not even to the name of the repository.

On your machineplaintext
repo  acme-pricing-engine
file  src/margin.rs
file  contracts/northwind.pdf
log   fix rounding on tiered discounts
log   add Q3 client rates
ref   refs/heads/main
On the serverwhat we store
6de215ef97543f8d831d77b00162063f
a41f0c9d38b7e5620c1d84f7ab90e3d5…
0b77c4e1592af8d3e6104bb27c98fa10…
e83d21af0c76b9541de027ca3b6f8419…
7c05be93d1a4f082635cb7de40a91f6b…
d2029b1e342e482e32498ad4f6367299…

Same repository, both sides. The right column is everything we could hand over if we were asked to, or breached.

How it works

Ordinary git, with the encryption underneath it.

1

You keep using git

A remote helper handles zkgit:// URLs, so git push and git clone work the way they always have. Branching, merging and rebasing happen in your local git, on plaintext, untouched by any of this.

# after `zkgit repo create`, this is just git
git push origin main
2

Objects are sealed before they leave

Each git object is encrypted with XChaCha20-Poly1305 under a key only you hold, and filed under an HMAC of its hash — so the server never sees a real SHA either. Fetching re-hashes every object and refuses anything that doesn’t match what was asked for.

3

Collaborators get their own copy of the key

Inviting someone seals the repo key to their public key alone, after you’ve confirmed their fingerprint out of band. Removing them re-encrypts the entire repository under a fresh key, so the copy they can still reach stops opening.

zkgit repo invite <server> pricing-engine RYU2-45PU-IYK7-LACK write
zkgit repo revoke <server> pricing-engine RYU2-45PU-IYK7-LACK

The honest ledger

What we hold, and what we can’t.

Encryption hides content, not the fact that content exists. Here is the whole list, including the parts that aren’t flattering.

The server does hold

  • Opaque repo and account IDs — random, not names
  • How many bytes each account stores, and when
  • Which account IDs share a repository
  • Connection metadata: IP, timing, request sizes
  • An email address, only if you write to the waitlist

The server cannot hold

  • File contents, filenames, or directory structure
  • Commit messages, author names, or history
  • Repository names and descriptions
  • Your password, or any key that opens the above
  • A way to reset any of it for you — by construction

Before you ask for an invite

Things it deliberately doesn’t do.

Lose both your password and your recovery code, and the data is gone.

There is no reset, no support override, no backdoor. That isn’t a policy we could change under pressure — there is simply no key on our side to use.

Revoking access doesn’t reach backwards.

Someone who already cloned a repository still has that clone. Revocation re-keys everything from that moment forward; it can’t reach into a laptop, and we won’t build something that can.

It protects what, not whom.

Priorities in order: security, then privacy, then convenience, and anonymity last — best-effort, never absolute. Someone watching the network still learns that you talk to this server and roughly how much you push.

It’s alpha software holding real work.

It is tested end to end and used daily by the person who wrote it, which is not the same as being proven. Keep another copy of anything you can’t lose.

Invite only, for now

Ask for an invite.

Tell us what you’d use it for. Invites go out in batches, and you’ll get a single-use code that works with zkgit signup. The email you write from is never linked to the account you create — we can’t match them up afterwards, and that’s on purpose.