mirror of
https://github.com/hanzoai/cek.git
synced 2026-10-09 02:37:18 +00:00
d080617cf60996daeef64f3eb7942b6c98cd044d
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]>
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.
Languages
Go
100%