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

Illustration: source code, a commit message, an issue, a review and release notes cross a seal line on your device and continue as ciphertext, which is all the host ever receives.
  • 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
  1. 01 Your device

    Your device seals the push

    sgit push bundles 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.

  2. 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.

  3. 03 Your teammate’s device

    Your teammate’s device opens it

    sgit pull fetches 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
  • shub and sgit

    shub is the gh of SealedGit: accounts, repositories, invitations, admissions, issues, pull requests and releases. sgit is 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 app and 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, and sealedgit-accounts, for email identity, invitations and OIDC. In production they use PostgreSQL and S3-compatible object storage.

    • Docker ComposeRun the services as containers.
    • Helm chartFor teams that deploy to Kubernetes.
    • Single-box installerOn AWS or Hetzner, with automatic TLS.

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.

Visibility to the SealedGit host
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.

SealedGit and related products, feature by feature
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.

  • shub

    The hosting CLI, the gh of SealedGit: accounts, repositories, invitations, admissions, issues, pull requests and releases. shub app starts the app.

  • sgit

    The git of SealedGit: clone, push, pull and fetch over encrypted sgit:// remotes. Every other command passes straight through to your own git.

  • git-remote-sgit

    The remote helper git uses for sgit:// URLs.

Works with the git you know

  • branches
  • tags
  • force-with-lease
  • submodules
  • SHA-256 repositories
Install and use the CLI
ledger · first push
# 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: shub lfs.

    Use shub 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

FAQ

Straight answers.

The questions engineers and security teams ask first.

Read the security model
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_256_MLKEM1024_AES256GCM_SHA512_MLDSA87: 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.