Crypto-shredding: how deletion actually deletes
2026-07-15 · Vorluno
Vorluno's one hard rule about data is never delete it — soft deletes, status flags, reversible history, no exceptions, everywhere in niiko. The right to erasure under GDPR is the sole nominated exception to that rule, and for a specific reason: a deleted_at flag does not satisfy it, because the row is still sitting there, still readable by any query that does not filter it out. That satisfies the article on restriction, not the article on erasure — closing the actual gap, without turning "never delete" into a company-wide lie for one case, needed a mechanism that could destroy data without ever running a DELETE statement.
The answer is a three-zone model. Business records get a real hard-delete once a valid erasure request lands. Audit trails and the deletion ledger itself stay append-only and untouched, because they hold no raw personal data to begin with. And the personal data trapped in append-only stores and backups — the copies a DELETE can never reach — gets crypto-shredded instead: every data subject is issued their own encryption key at the moment their record is created, and destroying that one key makes every row it protected permanently unreadable, everywhere a copy of it exists. Each erasure is recorded in a deletion ledger — no personal data in the row, just a pseudonymized reference and a hash the audit chain can verify later.
The key hierarchy has three levels, not two: a global root key, a per-tenant key wrapping it, and a per-data-subject key wrapping that — destroying one subject's key never touches the tenant's other subjects or the tenant's own stored credentials. Rotation exists at every level as a rewrap: re-encrypting the wrapping key, never the underlying data. The per-tenant rotation tooling, and the runbook that operates it, shipped and is exercised in the test suite — it is built and exercised, not something we have run against live production keys yet.
None of this could be retrofitted. A data subject has to be born with their own key at the moment their record is created, or erasing an existing subject later would mean re-encrypting everything else that happened to share their old key — exactly the kind of migration nobody wants to run under a legal deadline. That is why the key infrastructure went in before niiko accepted a single byte of personal data from an external agency's client, with a strict processor-to-controller SLA already written into the data agreement. What is retroactive, deliberately, is which columns get encrypted — that rolls out incrementally, column by column, because encrypting everything at once would break the indexes the product depends on to find a lead by phone number or email. Running the tooling that executes a full export or erase across every module in one pass is still manual work today, not a single button.
Per-subject encryption, plus export and delete tooling, shipped publicly on 27 June. The honest framing matters more than the headline: deletion here is not an endpoint you call, it is an architecture decision made months before the first request arrives — and the piece still being finished, full orchestration across every module, is exactly the kind of thing that is hardest to notice when it is missing and hardest to retrofit once you needed it yesterday.