Home / Articles / Seven vaults, one method

Seven vaults, one method

2026-08-19 · vaultspublishingmethod

Publishing seven encrypted vaults in a fortnight turned an ad-hoc process into a repeatable one. Every rule in it exists because something went wrong first — including three vault keys submitted for publication that would have handed the world write access.

Between 14 and 18 August this site published seven vaults. Each one is a real encrypted vault you can open in a browser from a read key printed on its page: a photo gallery, field notes, a patient-held supplement record, a risk register, a browser-isolation risk graph, a fact-to-risk explorer, and the catalogue that indexes them — itself a vault.

By the third one it was obvious that we were repeating ourselves badly. By the seventh there was a method, and every rule in it exists because something went wrong first.

The rule that matters most

Classify the credential before it touches anything.

Three of the seven vaults arrived as a vault key described as a read key. A vault key is write access. Publishing one would have handed anybody who read the page the ability to rewrite the vault — and because a vault key is also the address and the encryption root, there is no revocation, no rotation, and no undo.

They were caught by shape. A read key is 64 hex characters; a vault key is a generated passphrase, which is 24 lowercase alphanumerics. That catch depended on somebody looking, which is not a control. So it became a script:

$ python3 admin/build/check_credential.py '<credential>'
  form      : vault key (legacy passphrase:vault_id)
  publish?  : NO
  why       : 24 characters before the colon and not 64 hex, so it is a
              passphrase — a WRITE credential

Exit 0 means publishable. Exit 1 means stop. It never echoes what it was given.

Behind it sits a second line: the release validator scans every tracked file for any key-shaped string and for the actual passphrases, read at build time from a gitignored tier. That tripwire has caught its own author three times — each time writing the prefix in prose, in documentation explaining what a write credential looks like. Which is the point: a rule that only catches other people is not a rule.

Derive rather than refuse

The interesting part of the vault-key catch is what happens next. A read key is derived one-way from a vault key, so a submission that cannot be published can still become one that can:

c = Vault__Crypto()
pw, vid  = c.parse_vault_key(vault_key)
read_key = c.derive_keys(pw, vid)['read_key']

The vault key goes into a gitignored tier that the tripwire then scans for. The derived read key gets published. It is one-way: nobody can turn it back.

That is the whole shape of the thing this project is about — a capability you can hand over that is strictly less than the one you hold, with the reduction enforced by mathematics rather than by policy. The seven vaults span the range deliberately, from one that requests no permissions at all to one that can write a single folder.

Audit with the key you are about to publish

Not with the vault key. With exactly the credential a reader will have, across every file.

This caught a real problem. One vault carried a sealed LLM credential, and a published read key in front of a metered capability is an open tab on somebody else's budget. Rather than reasoning about whether the sealing was sound, we took the published read key and attempted to open the credential with it. AES-GCM refused — InvalidTag — so no budget was exposed. Checked rather than assumed, and recorded either way.

That rule did not come from us. It came from the sixth vault, Risk Graph Explorer, which is the first one here that was public by design: it carries its own PUBLIC.md whose three rules its build enforces, and the third — no metered capability behind a published read key — was not in our guidance. It is now.

Capture evidence by driving the real product

Every screenshot on a vault page is taken by opening the actual vault in a real browser with the published read key, performing the navigation, and cropping the result. No mock-ups.

This is slower than it sounds and worth every minute, because it repeatedly disagreed with what we were about to write. The rig grew a appProbe step for exactly that reason — ask the running app what its elements are called instead of guessing and burning a capture run per guess:

probe [class*=node] -> 37
  shapes ["g.cnode.inh","g.cnode","g.cnode.corp"]
  text   ["R1 An autonomous system operates in the es","R2 Stopping the agent is itself…"]

The alternative is a page that describes a product as its author remembers it.

Describe, show, then admit

Every vault page ends with what the vault does not do. Not as a disclaimer at the bottom in small type — as a section with the same weight as the features.

This is the part that is tempting to skip and never should be. A published vault is an argument that this way of working is sound; an argument that omits its own edges is a brochure. The limitations page is the same instinct at site level, and the comparison pages go further still — they include rows where vaults lose.

What it cost, and what it bought

Seven vaults, roughly four days of work, and the method is now written down as a playbook aimed at another site's agent rather than at us — which was the real test of whether it was a method or just a habit.

The honest ledger:

The last line is the one to keep. Every rule above is short and specific because it was learned by getting something wrong, in public, and writing down what it cost.


The full method, step by step, is on the publishing playbook. The vaults themselves are in the catalogue, each with the read key that opens it.

← All articles