feat(db): optional SQLCipher at-rest database encryption (opt-in, off by default) - #232
Merged
Merged
Conversation
kafkade
enabled auto-merge (squash)
July 28, 2026 04:10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds optional, off-by-default at-rest encryption for the live
toku.db, implementing ADR-016. Encryption is scoped to a newsqlciphercargo feature ontoku-db; when the feature is disabled — the default — the database path is byte-for-byte unchanged, and a build compiled without the feature behaves exactly as before. Toku's local-first, offline-first stance is preserved: encryption is entirely opt-in and never phones home.What's included
toku-dbsqlcipherfeature selectingrusqlite/bundled-sqlcipher-vendored-openssl. Scoped totoku-dbonly — the workspace root and thetoku-syncrelay stay on standard SQLite.open_encrypted/open_no_migrate_encryptedconstructors issue a raw-keyPRAGMA keyas the first statement (before WAL,foreign_keys, and migrations), then probesqlite_masterso a wrong passphrase yields a clean"incorrect passphrase or not an encrypted Toku database"error — never a panic or partial open. The unkeyed constructors are untouched.[encryption]section ofconfig.toml— the passphrase and derived key are never written to disk.toku dbcommand group:encrypt,decrypt,status, andforget. Migrations usesqlcipher_export(), keep a verified.bakof the original until the swap is confirmed, are idempotent, and refuse to run destructively without--yes. Without the feature compiled, these print a clear "built without at-rest encryption support" message.TOKU_DB_PASSPHRASEenv var → opt-in OS-keychain cache (toku db encrypt --remember) → interactive prompt (the baseline). Both caching paths are explicitly opt-in.toku.dbopen site (CLI dispatch, web request handlers, sync client) resolves the key once and opens keyed when encryption is enabled. The C FFI gains atoku_open_encryptedentry point (a pure ABI addition;toku_openis unchanged) with a regeneratedtoku.h.sqlcipherCI job proves the feature compiles and its tests pass, without altering theValidatemerge gate.Related Issues
Closes #225
Type of Change
Crate
toku-core— Domain models, traits, state machinetoku-db— SQLite persistence, migrations, FTS5toku-import— Importers (Goodreads, Calibre, StoryGraph)toku-meta— Metadata fetching (Open Library, Google Books)toku-cli— CLI binarytoku-export— Exporters (CSV, JSON, Markdown, BibTeX)docs/— DocumentationAlso touches
toku-web,toku-ffi, andtoku-sync-client(key-aware open sites and the FFI ABI addition).Data Integrity Checklist
db encrypt/decryptare themselves idempotent[encryption]stores only salt/KDF params/verifierSQLite format 3)Checklist
cargo fmt --checkpassescargo clippy --workspace -- -D warningspasses (also-p toku-db --features sqlcipher)cargo test --workspacepasses (feature off;-p toku-db --features sqlcipheralso green)