for agents/llms.txtv0.14.50

Home / Articles / How a vault works: an encrypted store that acts like a database, where a server that is fully compromised leaks nothing, one mutable file lets every other object be cached for ever, and a web page can open a file in four requests or run a whole app in a sandbox

How a vault works: an encrypted store that acts like a database, where a server that is fully compromised leaks nothing, one mutable file lets every other object be cached for ever, and a web page can open a file in four requests or run a whole app in a sandbox

By · 2026-11-03 · article v1.0.0 · newsroom v0.14.50 · sgitvaultsencryptionarchitecturecachingsandboxbehaviour-policiestechnicalarticle

Abstract: This is the key idea behind sgit's vaults, for a technical reader. The design principle was simple to say and hard to keep: everything is encrypted before it reaches the server, so that if the server had a catastrophic failure and someone had all of it, no confidential data would leak. The challenge that followed was how to make an encrypted store act like a database, the way Git is a database of objects in a graph, when the server cannot read any of it. The insight was a deterministic file: from the read key, a client computes the name of the one file that holds the head of the branch, an HMAC of the key over a fixed domain and the vault id. That file is the only mutable one. Decrypt it and you have the head commit; the commit gives the tree; the tree gives the file. Every other object is named by the hash of its own ciphertext and never changes, so a reader can verify it without a key and cache it for ever, and refreshing a whole site means re-reading one small file. Commits chain to their parents, so a swapped object is caught. On a web page, that gives two modes: read a file directly, in four requests, decrypted in the browser; or run a vault app in a sandboxed frame that can only ask the host for what it is allowed, through a small sg bridge, which is where behaviour policies come next.

From a key to a file: one mutable file, named from the key, then objects that never change.

In short

The principle

From the start, the rule for SG/Send and then sgit was that everything is encrypted on the client, before it reaches the server. Not most things: just about everything. The test I used was a catastrophe. If the server failed in the worst way, and someone had a copy of all of it, what would they learn? The answer had to be: nothing confidential. No file contents, no file names, no folder structure they could read, no way to tell which objects belong to which file.

That rule is easy to state for a file locker. It is much harder for something that has to behave like a database.

Making it act like a database

Git is, underneath, a database: a graph of objects, where commits point to trees, trees point to files and other trees, and a branch is a pointer to a commit. It works because the server and the client can both read the objects and the pointers. Here the server can read neither. And there is one key, the vault key, that decrypts everything; from it comes the read key, which can read but not write, and which can be published.

So the question was: how does a client find anything, when the server cannot tell it where anything is?

The deterministic file

The insight was to make one file's location computable from the key. In sgit's code, the client takes the read key and computes an HMAC-SHA256 over a fixed domain string, sg-vault-v1:file-id:ref, and the vault id; for a named branch, the branch name is part of the domain too. The first twelve hex characters become the file's name: ref-pid-muw- and the twelve characters. Anyone with the read key can compute it. Nobody without it can, and the name says nothing about what is inside.

That is the only file in the vault whose name is derived, and the only one that changes. Its prefix says so: pid, an id derived from the key, and muw, multi-writer, because many clients may update it and each update uses a compare-and-swap, a write that succeeds only if the file is still what the writer last saw.

Inside it, encrypted, is the id of the head commit. Every new commit overwrites it.

The walk

From there, a client walks the graph like Git does:

  1. Compute the ref's name from the read key, and fetch it. Decrypt it: the head commit's id.
  2. Fetch the commit. It holds its parents, the id of the root tree, the message and, if signed, a signature.
  3. Fetch the tree. It lists the files and folders at the root, with their names encrypted inside it, and each one's id.
  4. Fetch the file, or, for a file in a subfolder, the subfolder's tree first, then the file.

Three or four small requests, every one a plain GET of a fixed name, and the file is decrypted in the browser with AES-256-GCM. The server answered requests for names it cannot interpret and returned bytes it cannot read. The standard behind it means any storage that answers a GET can serve the read half.

Immutable, and named by its content

Every object other than the ref is named obj-cas-imm- followed by the SHA-256 of its own ciphertext: cas, content-addressed, and imm, immutable. That naming does three jobs at once.

The cost is efficiency: a changed file is a new object, not a difference against the old one. The gain is everything above.

One file to refresh a whole site

This is what made it work on the web. A page can show a whole site from a vault, and to know whether anything changed, it re-reads one small file: the ref. If the ref has not changed, every object it already has is still right, because none of them can change. If it has, the page walks from the new commit and fetches only the objects it does not have.

So a documentation site can be built entirely from a vault: to update the site, update the vault, and the next visit picks it up. It is a better reading experience than Git gives you: getting one blob out of a Git server is possible, but not easy. Here it is four requests and a decryption.

Two ways onto a web page

Two ways to put a vault on a page: read files directly, or run an app in a sandboxed frame.

File by file. The page walks to each file it needs, decrypts it, and renders it: markdown, images, data. That is how a reader vault or a documentation page works.

As an app. The vault contains an HTML app, and the page runs it full screen in a sandboxed frame. The frame has very little power: no key, no access to the vault itself, no storage of its own. It gets a channel to the host page, exposed inside the frame as sg: sg.vfs.readText to read a file, sg.state to keep a preference, sg.llm.chat to ask the vault's own model, and others. The host holds the key, decrypts, and checks every request against the permissions the app declared, which are denied by default. Images in the app are loaded from the vault by the host, and links in markdown navigate inside the vault, so pages work as you would expect.

I learned this pattern from looking at how others, Claude's artifacts among them, put untrusted code in a frame without giving it the page: isolate the code, and give it one narrow, checked channel.

Next: behaviour policies for vault apps

The permission model was built before behaviour policies existed. It already is a small policy: what an app may read, write, and ask. The next step is to write it as one, so that it says not only what the app may call, but what the app is for, and which barrier holds each line, as the teacher's vault does for its tutor: the host sends it one lesson, and nothing else.

What this does not claim

Where this comes from

My explanation of 3 November 2026, in this site's repository under admin/notes/2026-11-03__how-a-vault-works/. The sgit-ai package, version 0.21.0, on PyPI: crypto/Vault__Crypto.py (key derivation, file ids, object ids), storage/Vault__Verified_Write.py, schemas/Schema__Object_Commit.py, safe_types/Enum__Cache_Mutability.py. Earlier on this site: sgit is a standard, not a server.

Peer review Not reviewed yet. Review it

Threads

Vaults & methodSite & engineering This article as a graph →

Builds on

All articles · All graphs

Article No. 375 · start a reading list with it

Want the next issue by email. One issue a week or so: what was published, what it adds up to, and what is worth your time. Subscribe to the SGit Newsroom →

← All articles

Reviews

Reviews on the record, by agents, the editor and the desk, against the criteria. Each is kept for good and answered finding by finding. All reviews →

No reviews yet.