zeekayandHanzo Dev d080617cf6 Read a database whose key is beside it
Every database written before derived keys was born with a DEK from crypto/rand,
wrapped under a key derived from its owner and a random file id, and stored in a
sidecar next to it. Those pages are encrypted under that random key and under
nothing else, so no derivation reproduces it — arithmetic, not a policy choice.

Deriving a key for such a file and opening it is what SQLCipher answers at the
first statement, not at open:

  sqlite: decrypt orgs/hanzo/kms.db (wrong key or corrupt file):
  page 1: sqlcipher: wrong key or corrupted page

The files are there: 211 org directories, each with kms, agents, finance, code,
treasury and the rest. So Open now asks the one question that decides which key
a file has — is there a sidecar next to it. A sidecar means the key is in the
sidecar; no sidecar means the key is derived. The file says which scheme it
belongs to, which is the only thing that can say it.

This is a READ path and nothing more. It mints no sidecar, wraps no key and
rewrites no file, so a database opened through it is untouched and can be
converted later by something whose job that is. New databases are still born
with a derived key and no sidecar, so the set this governs only shrinks, and
this file can be deleted with the last of them.

A damaged sidecar or a wrong master is an error, never a fallthrough to the
derived key: falling through reports a healthy database as corrupt and sends the
reader to the wrong file.

Tests build stores in the real on-disk format using the same public primitives
the old scheme used, for both an org and the system namespace, and fail with the
production error when the read path is removed.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-02 00:12:18 -07:00
2026-08-02 00:12:18 -07:00

cek

Opens a namespace's SQLite database encrypted at rest.

cek.SetMaster(k)                            // once, at boot, from KMS
db, err := cek.Open(ns, "treasury", dataDir) // everywhere else

The key is derived from the master and the namespace. It is not generated, not wrapped, not stored, and not rotated in place — so there is no unwrap step, no rewrap step, no per-file key material to lose, and no migration path to maintain. A database is born encrypted or it does not exist.

Losing the master loses the data. That is the property you want from encryption at rest, and the reason the master lives in KMS.

Where it sits

hanzoai/namespace names the entity, and where its file lives
hanzoai/cek turns the master + that name into the file's key, and opens it
hanzoai/sqlite opens a file under a raw key; knows nothing about who owns it
hanzoai/kms holds the master

Nothing here knows about orgs, users, billing or plugins. It knows a namespace, a subsystem, and a master key.

S
Description
No description provided
Readme MIT
128 KiB
Languages
Go 100%