docs/long-term-plans/e2e-encryption-architecture-diagrams.md
Status: Archived — Reference Only
Comparative analysis of encryption approaches. Password-based encryption was chosen and implemented December 2025.
This document provides visual architecture diagrams comparing the current password-based encryption, the proposed device-key approach, and the recommended improvements.
graph TD
subgraph "Client Device"
A[User enters password] --> B[Argon2id KDF
64MB, 3 iterations]
B --> C[Derived AES-256 Key
Not stored, computed on demand]
D[Operation Created] --> E[OperationEncryptionService]
C --> E
E --> F[Encrypt with AES-GCM
Random IV per operation]
F --> G[Encrypted Operation
isPayloadEncrypted: true]
end
subgraph "Network"
G -->|HTTPS| H[Upload to Server]
end
subgraph "SuperSync Server"
H --> I[Store Encrypted Blob
Cannot decrypt]
I --> J[Operation Database
Prisma + PostgreSQL]
end
subgraph "Other Device"
J -->|HTTPS| K[Download Encrypted Ops]
K --> L[User enters same password]
L --> M[Argon2id KDF
Same params]
M --> N[Derived same AES-256 Key]
N --> O[OperationEncryptionService]
K --> O
O --> P[Decrypt Operations]
P --> Q[Apply to Local State]
end
style C fill:#90EE90
style N fill:#90EE90
style I fill:#FFB6C1
style J fill:#FFB6C1
classDef secure fill:#90EE90,stroke:#006400,stroke-width:2px
classDef untrusted fill:#FFB6C1,stroke:#8B0000,stroke-width:2px
Key Properties:
graph TD
subgraph "Primary Device"
A1[First Setup] --> B1[Generate Random 256-bit Key
WebCrypto API]
B1 --> C1{User chooses:
Recovery password?}
C1 -->|Yes| D1[User enters password]
C1 -->|No - Skip| E1[⚠️ No recovery
Data loss risk]
D1 --> F1[Argon2id KDF]
F1 --> G1[Encrypt key with KEK]
G1 --> H1[Upload encrypted key
to server]
B1 --> I1[Store key in IndexedDB
⚠️ iOS deletes after 7 days]
I1 --> J1[Encrypt operations]
end
subgraph "Server Issues"
H1 --> K1{Key conflict?
❌ Not detected}
K1 -->|Device A uploads| L1[KeyA stored]
K1 -->|Device B uploads| M1[KeyB overwrites
💥 Data loss]
end
subgraph "New Device - QR Pairing"
N1[Scan QR from primary] --> O1{❌ Security gap:
MITM protection?}
O1 --> P1[Receive master key
⚠️ Vulnerable to interception]
P1 --> Q1[Store in IndexedDB
⚠️ iOS 7-day eviction]
end
subgraph "New Device - Recovery Password"
R1[User enters password] --> S1[Download encrypted key]
S1 --> T1[Decrypt with KEK]
T1 --> U1[Store in IndexedDB
⚠️ iOS 7-day eviction]
end
subgraph "iOS Safari - 7 Days Later"
I1 -.7 days.-> V1[💥 IndexedDB auto-deleted]
Q1 -.7 days.-> V1
U1 -.7 days.-> V1
V1 --> W1[All data lost
if no recovery password]
end
style M1 fill:#FF6B6B
style V1 fill:#FF6B6B
style W1 fill:#FF6B6B
style O1 fill:#FFD93D
style K1 fill:#FFD93D
classDef critical fill:#FF6B6B,stroke:#8B0000,stroke-width:3px
classDef warning fill:#FFD93D,stroke:#FF8C00,stroke-width:2px
Critical Issues:
graph TD
A[User enters password
≥12 characters] --> B{zxcvbn
Strength check}
B -->|Weak| C[❌ Reject password
Suggest improvement]
B -->|Strong| D[Argon2id KDF
✅ 256MB, 4 iterations
⬆️ OWASP 2024]
D --> E[Derived AES-256 Key
5x stronger vs brute-force]
E --> F[Encrypt operations]
subgraph "XSS Protection - NEW"
G[Content Security Policy] --> H[script-src 'self'
Subresource Integrity]
H --> I[✅ Prevent code injection]
end
style D fill:#90EE90
style E fill:#90EE90
style I fill:#90EE90
classDef improved fill:#90EE90,stroke:#006400,stroke-width:2px
Improvements:
graph TD
subgraph "Multi-Platform Key Storage"
A[Derived encryption key] --> B{Platform?}
B -->|iOS via Capacitor| C[iOS Keychain
✅ Survives 7-day eviction]
B -->|Android| D[Android KeyStore
✅ Hardware-backed]
B -->|Electron macOS| E[macOS Keychain
safeStorage API]
B -->|Electron Windows| F[Windows Credential Manager
safeStorage API]
B -->|Web| G[IndexedDB
Fallback only]
C --> H[✅ No data loss on iOS]
D --> H
E --> I[Optional biometric unlock]
F --> I
G --> J[Manual password entry]
end
subgraph "Biometric Convenience"
I --> K[Touch ID / Face ID
Windows Hello]
K --> L[Cache key in memory
15min timeout]
L --> M[Fast unlock without
password re-entry]
end
style C fill:#90EE90
style D fill:#90EE90
style E fill:#90EE90
style F fill:#90EE90
style H fill:#90EE90
style M fill:#ADD8E6
classDef secure fill:#90EE90,stroke:#006400,stroke-width:2px
classDef convenience fill:#ADD8E6,stroke:#4682B4,stroke-width:2px
Improvements:
graph TD
subgraph "Client - Backup Flow"
A[User changes password] --> B[Re-encrypt all operations
with new password]
B --> C[Create full encrypted snapshot]
C --> D[Compress with gzip]
D --> E[Upload to server
POST /api/encrypted-backup]
end
subgraph "Server Storage"
E --> F[Store encrypted blob
Cannot decrypt]
F --> G[EncryptedBackup table
userId + blob + timestamp]
G --> H[Rate limit:
10 uploads/day]
end
subgraph "Recovery Flow"
I[New device setup] --> J[Detect no local data]
J --> K{Cloud backup
exists?}
K -->|Yes| L[Prompt for password]
K -->|No| M[Fresh start]
L --> N[Download encrypted blob]
N --> O[Decrypt with password]
O --> P[Restore full state]
P --> Q[✅ All data recovered]
end
style F fill:#FFB6C1
style G fill:#FFB6C1
style Q fill:#90EE90
classDef untrusted fill:#FFB6C1,stroke:#8B0000,stroke-width:2px
classDef success fill:#90EE90,stroke:#006400,stroke-width:2px
Improvements:
graph LR
subgraph "Password-Based
(Current + Improved)"
A1[Password] --> B1[Argon2id
256MB, 4 iter]
B1 --> C1[Key derived
on demand]
C1 --> D1[Encrypt/Decrypt]
E1[Multi-device:
Same password] --> B1
F1[iOS eviction:
Re-derive from password] --> B1
G1[Recovery:
Remember password] --> B1
end
subgraph "Device-Key Based
(Proposed - Not Recommended)"
A2[Random key
generated once] --> B2[Store in
IndexedDB]
B2 -.iOS deletes.-> C2[💥 Data loss]
D2[Multi-device:
QR pairing] -.MITM risk.-> E2[💥 Security risk]
F2[Multi-device:
Cloud backup] --> G2{Conflict?}
G2 -.Device B overwrites.-> H2[💥 Data loss]
I2[Recovery:
Optional password] --> J2{User skipped?}
J2 -.30% skip.-> C2
end
style D1 fill:#90EE90
style C2 fill:#FF6B6B
style E2 fill:#FF6B6B
style H2 fill:#FF6B6B
classDef works fill:#90EE90,stroke:#006400,stroke-width:2px
classDef broken fill:#FF6B6B,stroke:#8B0000,stroke-width:3px
gantt
title E2E Encryption Implementation Options
dateFormat YYYY-MM-DD
section Current (Exists)
Working encryption :done, curr1, 2024-01-01, 0d
section Recommended Plan
Phase 1: Security :active, rec1, 2026-01-27, 1w
Phase 2: Resilience :rec2, after rec1, 2w
Phase 3: Cloud Backup :crit, rec3, after rec2, 3w
Total: 6 weeks :milestone, m1, after rec3, 0d
section Device-Key Plan
Fix Blocker #1 :crit, dev1, 2026-01-27, 2d
Fix Blocker #2 :crit, dev2, after dev1, 5d
Fix Blocker #3 :crit, dev3, after dev2, 3d
Fix Blocker #4 :crit, dev4, after dev3, 3d
Core Implementation :dev5, after dev4, 8w
Migration & Testing :dev6, after dev5, 4w
Total: 15 weeks :milestone, m2, after dev6, 0d
sequenceDiagram
participant U1 as User (Device 1)
participant C1 as Client 1
participant S as SuperSync Server
participant C2 as Client 2
participant U2 as User (Device 2)
Note over U1,C1: Initial Setup
U1->>C1: Enter password "MySecurePass123"
C1->>C1: Argon2id(password, 256MB, 4 iter)
C1->>C1: Generate AES-256 key (derived)
Note over C1: Create Task
U1->>C1: Add task "Buy milk"
C1->>C1: Create operation {type: CREATE_TASK, ...}
C1->>C1: Encrypt(operation, key)
C1->>C1: Set isPayloadEncrypted: true
Note over C1,S: Upload Encrypted
C1->>S: POST /api/sync/ops
{encrypted: "a8f3b2...", isPayloadEncrypted: true}
S->>S: Store blob (cannot decrypt)
S-->>C1: 200 OK
Note over S,C2: Download & Decrypt
C2->>S: GET /api/sync/ops?sinceSeq=0
S-->>C2: [{encrypted: "a8f3b2...", isPayloadEncrypted: true}]
U2->>C2: Enter password "MySecurePass123"
C2->>C2: Argon2id(password, 256MB, 4 iter)
C2->>C2: Generate same AES-256 key
C2->>C2: Decrypt(operation, key)
C2->>C2: Verify integrity (GCM auth tag)
C2->>C2: Apply operation to state
Note over U2,C2: Task Appears
C2-->>U2: Show task "Buy milk" ✅
graph TB
subgraph "Threats PROTECTED Against ✅"
T1[Server Compromise] --> P1[✅ Encrypted payloads
Server cannot decrypt]
T2[Network MITM] --> P2[✅ HTTPS + encrypted payloads
Double layer protection]
T3[Brute Force] --> P3[✅ Argon2id memory-hard KDF
256MB, 4 iterations]
T4[XSS Injection] --> P4[✅ CSP + SRI headers
Phase 1]
T5[iOS Data Eviction] --> P5[✅ Native keychain storage
Phase 2]
end
subgraph "Threats NOT PROTECTED ⚠️"
T6[Weak Passwords] --> N1[⚠️ User chooses password
Mitigated by strength meter]
T7[Device Theft] --> N2[⚠️ Key in memory while unlocked
Mitigated by auto-lock]
T8[Browser Memory Exploits] --> N3[⚠️ Spectre/Meltdown
Out of scope]
T9[Malicious Extensions] --> N4[⚠️ Can access decrypt API
User responsibility]
end
style P1 fill:#90EE90
style P2 fill:#90EE90
style P3 fill:#90EE90
style P4 fill:#90EE90
style P5 fill:#90EE90
style N1 fill:#FFD93D
style N2 fill:#FFD93D
style N3 fill:#FFD93D
style N4 fill:#FFD93D
classDef protected fill:#90EE90,stroke:#006400,stroke-width:2px
classDef limited fill:#FFD93D,stroke:#FF8C00,stroke-width:2px
graph TD
A{Need E2E encryption?} -->|No| B[Use existing unencrypted sync]
A -->|Yes| C{Already implemented?}
C -->|Yes - Password-based| D{Security concerns?}
C -->|No - Starting fresh| E{Use case type?}
D -->|Argon2id params weak| F[✅ Implement Phase 1
Upgrade params, CSP
1 week]
D -->|iOS data loss risk| G[✅ Implement Phase 2
Native keychain
2 weeks]
D -->|Need cloud recovery| H[✅ Implement Phase 3
Cloud backup
3 weeks]
D -->|All good| I[Keep current system]
E -->|Messaging app
Ephemeral data| J[Consider device keys
WhatsApp model]
E -->|Productivity/Password Manager
Long-lived data| K[✅ Use password-based
1Password/Bitwarden model]
E -->|File sync only| L[Consider per-file keys
Dropbox model]
J --> M{Can fix 4 blockers?}
M -->|Yes - 3 weeks| N[OK to proceed with device keys]
M -->|No| K
K --> F
style F fill:#90EE90
style G fill:#90EE90
style H fill:#90EE90
style K fill:#90EE90
style M fill:#FF6B6B
classDef recommended fill:#90EE90,stroke:#006400,stroke-width:2px
classDef blocker fill:#FF6B6B,stroke:#8B0000,stroke-width:2px
graph TB
subgraph "Current Implementation (200 lines)"
A1[encryption.ts
183 lines] --> B1[AES-256-GCM
Argon2id KDF]
C1[operation-encryption.service.ts
103 lines] --> A1
D1[credential-store.service.ts
289 lines] --> E1[IndexedDB
Password storage]
end
subgraph "Device-Key Plan (2000+ lines)"
A2[DeviceKeyService
~300 lines NEW] --> B2[WebCrypto key gen
IndexedDB storage]
C2[CloudKeyBackupService
~250 lines NEW] --> D2[Upload encrypted key
Argon2id for KEK]
E2[QRPairingService
~400 lines NEW] --> F2[ECDH protocol
Visual verification]
G2[ConflictResolutionService
~200 lines NEW] --> H2[Detect conflicts
User resolution UI]
I2[Platform-specific storage
~300 lines NEW] --> J2[iOS Keychain
Electron safeStorage]
K2[5 new dialogs
~500 lines] --> L2[Recovery setup
QR pairing
Conflict resolution]
end
subgraph "Recommended Plan (300 lines)"
A3[encryption.ts
+5 lines] --> B3[Upgrade Argon2id
256MB, 4 iter]
C3[secure-storage.service.ts
~150 lines NEW] --> D3[Platform keychain
Capacitor/Electron]
E3[encrypted-backup.service.ts
~200 lines NEW] --> F3[Cloud backup
Optional Phase 3]
end
style A1 fill:#90EE90
style C1 fill:#90EE90
style A2 fill:#FFB6C1
style C2 fill:#FFB6C1
style E2 fill:#FFB6C1
style G2 fill:#FFB6C1
style A3 fill:#90EE90
style C3 fill:#ADD8E6
style E3 fill:#ADD8E6
classDef exists fill:#90EE90,stroke:#006400,stroke-width:2px
classDef complex fill:#FFB6C1,stroke:#8B0000,stroke-width:2px
classDef simple fill:#ADD8E6,stroke:#4682B4,stroke-width:2px
Final Recommendation: Implement the 3-phase improvement plan for the existing password-based encryption. Do not pursue device-generated keys.