rspace-online/backlog/tasks/task-77 - EncryptID-Optiona...

93 lines
4.4 KiB
Markdown

---
id: TASK-77
title: 'EncryptID: Optional encrypted VPS backup for client-side data'
status: Done
assignee: []
created_date: '2026-03-02 20:19'
updated_date: '2026-03-03 03:31'
labels:
- encryptid
- privacy
- feature
dependencies: []
references:
- server/local-first/encryption-utils.ts
- server/local-first/backup-store.ts
- server/local-first/backup-routes.ts
- shared/local-first/backup.ts
- server/local-first/doc-persistence.ts
- server/local-first/sync-server.ts
- server/sync-instance.ts
- shared/local-first/sync.ts
- shared/local-first/encryptid-bridge.ts
- docs/DATA-ARCHITECTURE.md
documentation:
- docs/DATA-ARCHITECTURE.md
priority: medium
---
## Description
<!-- SECTION:DESCRIPTION:BEGIN -->
Add an EncryptID settings option for users to backup their encrypted client-side data (wallet associations, etc.) to a VPS. Default is client-side only (maximum privacy). Optional backup enables device-loss recovery and cross-device sync.
Architecture:
- Client-side encrypted localStorage is the default (current wallet-store.ts pattern)
- Settings toggle: "Backup encrypted data to server"
- When enabled, encrypted blobs (already AES-256-GCM) are synced to the EncryptID server or a user-specified VPS
- Server stores opaque ciphertext — same zero-knowledge pattern as encrypted_addresses
- On new device login, user can restore from backup after passkey authentication
Consider extending this to all client-side data (wallet associations, preferences) and potentially migrating encrypted_addresses to the same pattern (client-first, optional server backup).
<!-- SECTION:DESCRIPTION:END -->
## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Settings UI toggle for encrypted backup (default: off)
- [x] #2 Encrypted blobs sync to EncryptID server when enabled
- [x] #3 Restore flow on new device after passkey auth
- [x] #4 Server never sees plaintext — only stores opaque ciphertext + IV
- [ ] #5 User can optionally specify a custom VPS endpoint for backup
<!-- AC:END -->
## Implementation Notes
<!-- SECTION:NOTES:BEGIN -->
2026-03-03: Implemented full 4-layer architecture. AC #5 (custom VPS) deferred to future Layer 3 federated replication phase. Commit 46c2a0b on dev, merged to main, deployed to Netcup.
<!-- SECTION:NOTES:END -->
## Final Summary
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
## Layered Local-First Data Architecture — Complete Implementation
### What was done
Implemented the full 4-layer data architecture (device → encrypted backup → shared sync → federated):
**New files (5):**
- `server/local-first/encryption-utils.ts` — Shared AES-256-GCM primitives (deriveSpaceKey, encrypt/decrypt, rSEN pack/unpack)
- `server/local-first/backup-store.ts` — Filesystem opaque blob storage with manifest tracking
- `server/local-first/backup-routes.ts` — Hono REST API (PUT/GET/DELETE /api/backup/:space/:docId) with JWT auth
- `shared/local-first/backup.ts` — BackupSyncManager with delta-only push, full restore, auto-backup
- `docs/DATA-ARCHITECTURE.md` — 4-layer architecture design doc with threat model and data flow diagrams
**Modified files (10):**
- `server/community-store.ts` — Replaced inline encryption with shared encryption-utils
- `server/local-first/doc-persistence.ts` — Added encryptionKeyId param, rSEN detection in loadAllDocs, saveEncryptedBlob/loadEncryptedBlob for relay blobs
- `server/local-first/sync-server.ts` — Added relay-backup/relay-restore wire messages, onRelayBackup/onRelayLoad callbacks
- `server/sync-instance.ts` — Added encryption key lookup + relay backup/load wiring
- `shared/local-first/sync.ts` — Added RelayBackupMessage/RelayRestoreMessage types, sendRelayBackup(), handleRelayRestore()
- `shared/local-first/storage.ts` — Added loadRaw() for backup manager
- `shared/local-first/encryptid-bridge.ts` — Wired backup stubs to BackupSyncManager, added getBackupManager()/initBackupManager()
- `shared/local-first/index.ts` — Exported new backup + relay message types
- `docker-compose.yml` — Added rspace-backups:/data/backups volume
- `server/index.ts` — Mounted backup routes at /api/backup
### Verification
- `npx tsc --noEmit` — zero errors
- `bun run scripts/test-automerge-roundtrip.ts` — 35/35 pass
- Deployed to Netcup, container starts cleanly with 33 docs loaded
### AC #5 (custom VPS endpoint) deferred to Layer 3 (Federated Replication) — designed in DATA-ARCHITECTURE.md but not yet implemented.
<!-- SECTION:FINAL_SUMMARY:END -->