End-to-end encrypted Git hosting
Git hosting that can’t read your code.
SealedGit encrypts your repositories, issues and pull requests on your own devices. The host stores ciphertext, and holds no key that would let it read a single line.
NIST Category 5 post-quantum encryptionmacOS and Linuxworks with the git you knowself-hostable
-
Post-quantum MLS
NIST Category 5
Every repository is an MLS group on ML-KEM-1024 (FIPS 203) and ML-DSA-87 (FIPS 204), NIST’s highest security category, with AES-256-GCM and SHA-512.
-
Committing AEAD
On every push
A sealed push is bound to the one key that made it, so it can’t be opened into two different results.
-
Host-blind storage
Ciphertext only
Encrypted git bundles, opaque MLS framing and hash-chained RefHeads. Nothing the host can open.
-
Device-held keys
None on the host
Keys live on members’ devices. The host holds no key that would decrypt a repository.
How it works
Sealed on your device. Stored blind. Opened only by your team.
At no step does the host decrypt anything: not to index it, not to display it, not for a moment. Encryption and decryption both happen on members’ devices.
The full walk-through: devices, pushes, members and the cryptography-
01 Your device
Your device seals the push
sgit pushbundles your commits and encrypts them on your machine, with keys from the repository’s MLS group and a committing AEAD. Plaintext never leaves your device. -
02 The host
The host stores ciphertext
SealedGit keeps the encrypted bundle, opaque MLS framing and a hash-chained RefHead, and serves them back when asked. It holds no key that would open any of them.
-
03 Your teammate’s device
Your teammate’s device opens it
sgit pullfetches the ciphertext and decrypts it locally, because their device is a member of the repository’s group. From there it’s ordinary git.
What you get
Repositories, reviews and releases. All of it sealed.
The everyday work of a code host, built so that your code and your team’s conversation about it are encrypted before the host ever holds them.
-
Encrypted repositories
Your code and every commit message are sealed into encrypted git bundles before they leave your machine. Repository descriptions are encrypted too.
sgit://encrypted git bundles -
Encrypted issues, pull requests and releases
Issues, pull requests, reviews and release notes are encrypted to the repository’s members and decrypted on their devices.
issuespull requestsreviewsreleases -
shubandsgitshubis the gh of SealedGit: accounts, repositories, invitations, admissions, issues, pull requests and releases.sgitis its git: clone, push, pull and fetch over encrypted remotes, with every other command passed straight to your own git. -
The SealedGit app, on your computer
Run
shub appand it opens in your browser at a local address. See your repositories, create new ones, invite and admit members, browse code, commits, issues and pull requests, and manage your profile and settings.It runs on your machine because that’s where your keys are.
shub appmacOSLinux -
An invitation isn’t access
Inviting an email address records an invitation and sends a link. Access begins only when a member’s device admits the invitee: an MLS Add the host cannot perform, after comparing a safety number that pins their device key.
invitecompareadmit -
Self-host every part of it
Run
sealedgit-server, the ciphertext host, andsealedgit-accounts, for email identity, invitations and OIDC. In production they use PostgreSQL and S3-compatible object storage.
Honest metadata
What the host sees, and what it never sees.
Encryption hides what you write, not the fact that you use a host. This is exactly where the line falls.
| Data | The host sees | The host never sees |
|---|---|---|
| Accounts | Your handle, which is your username | Any key that would decrypt your work; keys live on members’ devices |
| Repositories | Each repository’s name, and who is a member | The code, the commit messages and the description |
| Pushes | Their size and timing | Their contents: every push is an encrypted git bundle |
| Issues and pull requests | Ciphertext only | Issues, pull request bodies and reviews |
| Releases | Ciphertext only | Release notes |
The accounts service also holds the email address you sign up with, so that it can send confirmation links, password resets and invitations. Repository names are visible, so choose them accordingly.
Compared
How SealedGit compares.
Git hosts keep your repository readable to whoever runs them. Encryption add-ons hide some of it from an ordinary host. SealedGit is a host built so that it never holds anything it could read.
| Feature | SealedGitencrypted Git host | GitHubGit host | GitLabhosted or self-managed | Gitea / Forgejoself-hosted forges | git-cryptencrypts chosen files | git-remote-gcryptencrypts a whole remote |
|---|---|---|---|---|---|---|
| The host can’t read your code | Yes | No | No | No | Only the files you choose to encrypt | Yes |
| Commit messages and file names hidden from the host | Yes | No | No | No | No: it encrypts file contents only | Yes |
| Issues, pull requests and reviews | Yes, encrypted to members | Yes, readable by the host | Yes, readable by the host | Yes, readable by the host | None of its own | None |
| The host can’t grant anyone access | Yes: only members’ devices admit anyone | No: the host grants it | No: the host grants it | No: the host grants it | Not to encrypted files; the rest is plain | Yes: access is a participant’s GPG key |
| Post-quantum, NIST Category 5 | Yes: ML-KEM-1024 and ML-DSA-87 | Not end-to-end encrypted | Not end-to-end encrypted | Not end-to-end encrypted | AES-256 files; keys as strong as your GPG keys | As strong as your GPG keys |
| Hosted CI, webhooks and web code search | No: each needs plaintext on the host | Yes | Yes | Yes | The host’s, blind to encrypted files | No: the host holds only encrypted packs |
| Run it yourself | Yes: Compose, Helm or one machine | Paid: GitHub Enterprise Server | Yes, self-managed | Yes | Works on any Git host | Works on any Git remote, or rsync |
- yes
- partly
- no
Other products as their public documentation describes them. Self-hosting a forge changes who runs the host, not what the host can read. SealedGit makes the opposite trade: it gives up hosted CI, webhooks and host-side search to keep plaintext off the host entirely. What that costs, in detail.
Two tools, both familiar
shub for the host. sgit for the code.
If you know gh and git, you already know the shape of SealedGit. Both come in one download for your computer.
shubThe hosting CLI, the gh of SealedGit: accounts, repositories, invitations, admissions, issues, pull requests and releases.
shub appstarts the app.sgitThe git of SealedGit:
clone,push,pullandfetchover encryptedsgit://remotes. Every other command passes straight through to your own git.git-remote-sgitThe remote helper git uses for
sgit://URLs.
Works with the git you know
- branches
- tags
- force-with-lease
- submodules
- SHA-256 repositories
# install: one program, the build for this computer
curl -fsSL \
https://github.com/sealedgit/sealedgit/releases/latest/download/install.sh | sh
# create an encrypted repository and clone it
shub repo create ledger --clone && cd ledger
# work as usual; sgit seals what it pushes
echo "opening balance 0" > BALANCES.md
sgit add BALANCES.md && sgit commit -m "open the ledger" && sgit push
# invite a teammate, then admit their device
shub repo invite-email you/ledger --email teammate@example.com
shub repo admissions --repo you/ledger --user <their handle> \
--key-package-digest <their digest>
Deliberate omissions
What SealedGit deliberately does not do.
Each of these would need the host to read your plaintext. Rather than weaken that guarantee, SealedGit leaves them out.
-
Webhooks
A webhook is the host telling another service what changed in your repository. It can’t describe what it can’t read.
Not offered -
Hosted CI runners
Building your code on the host’s machines would mean handing those machines your plaintext.
Not offered -
Hosted codespaces
An editor that runs on the host is your source code, decrypted, on the host.
Not offered -
The Git LFS wire protocol
LFS hands file contents to the server as they are. SealedGit has its own sealed large-file store instead:
Use shub lfsshub lfs. -
Shallow or partial clones
Trimming history on the server takes a server that can read the history.
Not offered -
Host-side search, diffs and merges
All three need the plaintext, and only members’ devices have it. Search, diff and merge locally, with git.
Not offered
A trade made on purpose: fewer conveniences, and a host that never holds your plaintext. Why, in detail
Can SealedGit read my code?
No. Your code, commit messages, issues, pull request bodies, release notes and repository descriptions are encrypted on members’ devices before they reach the host. The host stores ciphertext (encrypted git bundles, opaque MLS framing and hash-chained RefHeads) and holds no key that would let it decrypt any of it.
What can the host see, then?
Metadata: handles (usernames), repository names, who is a member of which repository, and the size and timing of pushes. The accounts service also holds your email address, so it can send confirmation links, password resets and invitations.
If a repository name would itself give something away, choose a different one.
Do I have to change how I use git?
Barely. Use sgit for clone, push, pull and fetch against sgit:// remotes; every other command passes straight through to your own git. Branches, tags, force-with-lease, submodules and SHA-256 repositories all work. Git reaches SealedGit through the git-remote-sgit helper.
Do I have to install anything?
Yes, one download, because SealedGit decrypts on your computer and nowhere else. There is a build for each system and processor (macOS or Linux, Apple silicon or Intel, Arm64 or x86-64), and each is a single program of a few megabytes that runs as shub, sgit, git-remote-sgit and the app. You also need git.
The installer downloads only the build for your computer and checks its SHA-256: curl -fsSL https://github.com/sealedgit/sealedgit/releases/latest/download/install.sh | sh. Every download, and how to verify it.
Why does the app run on my computer instead of a website?
Because that’s where your keys are. A page served by the host could only show you your code if the host could decrypt it, and it can’t. The SealedGit app runs on macOS or Linux, opens in your browser at a local address, and decrypts on your device. Start it with shub app.
If I invite someone, can they read the repository?
Not yet. An invitation records their email address and sends them a link. They sign up or sign in and accept; then a member’s device admits them with an MLS Add, which the host cannot perform.
Admission pins the invitee’s device key, which you compare as a safety number, so the host cannot substitute a key of its own.
What happens when someone leaves?
Removing a member rotates the repository’s epoch. Their device never receives the new keys, so it cannot decrypt anything pushed afterwards.
Removal can’t reach into their laptop, though: whatever their device fetched before, it still has.
Does a new member see the whole history?
That depends on their grant. A full-history grant opens the whole history. A forward-only grant gives them a snapshot of the tree as it is when they join, and every change afterwards, but none of the earlier history.
Why post-quantum, and what does Category 5 mean?
The host keeps your ciphertext for as long as the repository exists, and stored ciphertext can be attacked long after it was written. Each repository’s MLS group uses the ciphersuite MLS_: ML-KEM-1024 (FIPS 203) for key establishment and ML-DSA-87 (FIPS 204) for signatures, both designed to resist quantum attacks.
Both are the Category 5 parameter sets, NIST’s highest security category: breaking them should take at least as much work as a key search on AES-256, which is also what encrypts the group’s messages. The algorithms, one by one.
Can we run it ourselves?
Yes. sealedgit-server is the ciphertext host; sealedgit-accounts handles email identity, invitations and OIDC. In production they use PostgreSQL and S3-compatible object storage. Deploy with Docker Compose, the Helm chart, or the single-box installer for AWS or Hetzner, which sets up TLS automatically.
Self-hosting changes who runs the host, not what the host can see.
What about large files?
SealedGit doesn’t speak the Git LFS wire protocol, which hands file contents to the server as they are. It has its own sealed large-file store: shub lfs.
Start sealed
Start a repository the host can’t read.
Create an account, open the SealedGit app on your computer, and push your first sealed commit.