mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 20:27:15 +01:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WzxdWXTUM9dpnCS2wtFkx4
39 lines
1.6 KiB
Markdown
39 lines
1.6 KiB
Markdown
# Encrypt crdt_sync payloads end to end
|
|
|
|
## what
|
|
Firebase RTDB stores every crdt_sync record in plaintext, so Google can read
|
|
all app data. Encrypt record payloads on the device before push and decrypt
|
|
after pull, so RTDB stays a blind relay (the "ownership" meaning of
|
|
local-first: hologram.page/blog/local-first-means-three-different-things).
|
|
|
|
## open decisions (ask kuhy before coding)
|
|
- Key source: derived from the shared crdt-sync password (Argon2id) or a
|
|
random key stored in the OS keystore and copied to new devices.
|
|
- Migration: re-encrypt existing logs in place, or new prefix + one-time copy.
|
|
- Scope: payload only (keep HLC/ids clear for merge) or whole record.
|
|
- tutor uses its own RTDB client (`~/src/tutor/app/lib/sync/rtdb_client.dart`):
|
|
in or out of scope.
|
|
|
|
## steps
|
|
1. Add an encrypt/decrypt seam in `crdt_sync_dart/lib/src/remote_store.dart`
|
|
(push/pull), AEAD (XChaCha20-Poly1305), version byte per record.
|
|
2. Property test: decrypt(encrypt(r)) == r; merge result identical with and
|
|
without encryption (see property-and-differential-tests skill).
|
|
3. Read path accepts plaintext and v1 records during migration.
|
|
4. Roll out app by app (todo first), bump pins, verify on the phone.
|
|
|
|
## done
|
|
`dart test` in `crdt_sync_dart` passes, and
|
|
`firebase database:get /<prefix> | grep -c '"title"'` returns 0 for every
|
|
migrated app.
|
|
|
|
## verify
|
|
Pixel 6a + desktop todo: edit on one, see it on the other; raw RTDB JSON shows
|
|
only ciphertext.
|
|
|
|
## read first
|
|
- `crdt_sync_dart/lib/src/sync.dart`, `log.dart`, `remote_store.dart`
|
|
- `crdt_sync_flutter/lib/src/bootstrap.dart`
|
|
|
|
REMOVE ME AFTER FINISH
|