Cross-Device Sync via Encrypted Snapshots
Cross-Device Sync via Encrypted Snapshots
Status: Delivered
CAS: CAS-1093
Delivered: 2026-04-29
PRs: #314, #317, #322, #329
What’s new
You can now sync your Casaconomy database across multiple desktop machines. Changes made on one device are encrypted on-device, uploaded to Cloudflare, and available to pull on any other paired device — Cloudflare never sees your plaintext financial data. Pairing is done once via a 24-word recovery phrase or a QR code; after that, Sync now handles everything.
How to use it
First-time setup (new device or fresh install):
- Open Settings → Sync.
- On your primary machine, tap Pair this device to display your recovery phrase and QR code.
- On the second machine, open the same pane and enter the recovery phrase (or, once mobile lands, scan the QR).
- Both devices are now paired. The recovery phrase is shown once — store it somewhere safe.
Day-to-day sync:
- Tap Sync now in Settings → Sync to push the latest snapshot from the current device or pull the newest one from the cloud.
- Casaconomy also snapshots automatically when the app closes.
- A banner appears when a newer snapshot is available remotely — click it to pull.
Recovery (lost device or fresh machine):
- Open Settings → Sync on the new machine.
- Enter the recovery phrase to derive the vault key, re-authenticate against the Worker, and restore the latest snapshot.
What changed under the hood
- Cloudflare infrastructure (PR #314): R2 buckets
casaconomy-snapshots-{prod,dev}, D1 databasecasaconomy-sync-prod(accounts / devices / snapshots / audit tables), 30-snapshot lifecycle rule to cap storage growth. - Sync Worker (PR #317): TypeScript Worker deployed to
sync.casaconomy.com— endpoints for snapshot push/pull, device pairing, and versioned metadata. Per-device JWT auth; SHA-256 content-addressing on every upload. - Rust snapshot service (PR #322):
CloudSnapshotServiceinsrc-tauri/src/services/— BIP-39 recovery phrase → PBKDF2-HMAC-SHA256 vault key → AES-256-GCM encryption → gzip → R2. Vault key persisted in macOS Keychain. Migration 47 addscloud_sync_metatable. Four Tauri commands:cloud_pair,cloud_snapshot,cloud_sync_status,show_recovery_phrase. - Settings > Sync pane (PR #329):
SyncPanecomponent +useSyncStoreZustand store. Status indicator, Sync now button, pairing flow (QR + phrase), one-time recovery-phrase reveal with confirmation modal.
Why we built it
Before any monetisation work made sense, the board needed to be able to use Casaconomy across devices without manually copying database files. A single-user, zero-knowledge sync model — where Cloudflare is a dumb encrypted-blob store and the vault key never leaves the device — solved the day-to-day pain without requiring a multi-user account system or server-side decryption. This lays the groundwork for mobile sync once CAS-645 matures.
Known limitations / follow-on work
- SyncStatusDot amber state not wired: the indicator always shows green; the “Syncing…” amber state tied to
isSyncingis not yet displayed. Small follow-up issue to file. resetConflictDismissunused: the function is defined in the store but never called from the UI. Cleanup item for the next Sync iteration.- Mobile sync deferred: pairing and snapshot restore on iOS/Android land in a later CAS-645 phase once the mobile shell is stable.
- Real-time sync is V2: V1 is manual Sync now + auto-snapshot on close. Push notifications or live sync are out of scope for this epic.
- Windows Keychain equivalent not yet verified: vault-key persistence uses macOS Keychain via the
keyringcrate; Windows credential store path needs smoke-testing on a Windows build.