Encrypt content at rest - phase 1 of the #189 data-minimization track #322
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "phase-1-at-rest-encryption"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
cards.source_data (the message snapshot), cards.notes and outgoing_posts.content become Fernet ciphertext under two new HKDF domains (waggle-cardcontent-v1, waggle-outgoing-v1), decrypted transparently at the ORM boundary (EncryptedJSON/EncryptedText over bytea in models/base.py). A database dump, backup or SQL-injection read no longer yields message content, notes or unsent drafts.
Why this is functionally free: nothing filters on these columns in SQL. The note filter and the retention sweep's note check already ran in Python after load; the one cheap SQL pre-filter on notes is removed. Import dedupe keeps working through column projections, which decrypt like any ORM read.
The revision (e5a9c31d7f02) converts existing rows in place and is NOT rolling-safe - the changelog carries a 'Note when rolling out': stop the old pod first and take a database backup; reading the converted columns requires the WAGGLE_SECRET_KEY the migration ran with.
waggle rotate-keys now also re-encrypts the three content columns, on raw table clauses rather than the ORM (the mapped types decrypt with process settings, not --from/--to). docs/security.md gains the two domains and a 'Content at rest' section; the key-rotation runbook in deployment.md names the covered columns.
Gates: 1981 backend tests at 100% coverage (including two new migration tests: in-place conversion of seeded plaintext, and bytea column types at head), 1177 vitest, vue-tsc + build, pinned pre-commit, full e2e suite green against a stack that boots through the new migration.
f8c82565c9d93c086c3a