Privacy-Preserving Data Collection Strategy for Lantern โ
What You Already Have โ โ
Your encryption.js implements true zero-knowledge architecture:
- Keys derived from user passphrase via PBKDF2 (600,000 iterations)
- AES-256-GCM encryption with random IVs
- Backend cannot decrypt dataโonly stores ciphertext + salt
- Passphrase never leaves device
Strategy for Collecting Data While Maintaining 100% Privacy โ
1. Encrypt All PII Client-Side (Current Architecture) โ
User Data โ Client Encryption โ Ciphertext โ Firebase |
|---|
- Interests, preferences, personal notes โ encryptData() before storage
- Backend stores only encrypted blobs
- Even a data breach reveals nothing
2. Aggregate Analytics Without Individual Data (Differential Privacy) โ
For product insights (e.g., "what interests are trending?"), use:
| Technique | How It Works | Use Case |
|---|---|---|
| Local Differential Privacy | Add noise on client before sending | Interest categories (not exact values) |
| k-Anonymity | Only report if k+ users share a trait | Venue popularity by interest type |
| Randomized Response | Users flip a coin before answering | Sensitive preferences |
Example for interests:
// Instead of: { interest: "Looking for hiking partners" } // Send anonymized category: { interestCategory: "activities", noise: randomNoise() } |
|---|
3. Separate Identifiable from Aggregate Data โ
| Data Type | Storage | Encryption |
|---|---|---|
| User PII (name, email, birth date) | Firestore /users/ | โ Client-side encrypted |
| Lantern metadata (mood, interest text) | Firestore /lanterns/ | โ encryptedMetadata field |
| Anonymous aggregates (venue popularity) | Firestore /analytics/* | โ Not neededโno PII |
| Geolocation | Stored as geohash, not exact coords | Partial privacy via precision loss |
โ
Cryptographic Erasure: How to Guarantee Data Deletion โ
This is the killer feature of your architecture. Here's how it works:
Option A: Delete the Key = Delete the Data โ
Since user data is encrypted with a key derived from their passphrase:
User requests deletion โ 1. Delete user's salt from Firestore 2. Delete encrypted documents 3. Key can never be regenerated 4. Data is cryptographically irrecoverable |
|---|
Even if backups exist, without the salt + passphrase, data is mathematically unrecoverable.
Option B: Per-Document Key Wrapping (More Granular) โ
For selective deletion (e.g., "delete my interests but keep my account"):
| // Each data category has its own wrapped key { userId: "abc123", interestsKeyWrapped: "encrypted-aes-key-for-interests", // Wrapped by master key lanternsKeyWrapped: "encrypted-aes-key-for-lanterns", // ... } // To delete interests: Just delete interestsKeyWrapped // The encrypted interest data becomes garbage |
|---|
Implementation Recommendation โ
Add a function to encryption.js:
| /** * Cryptographic erasure - makes user data permanently unrecoverable * Deletes salt so key can never be derived again */ export async function cryptographicErasure(userId) { // 1. Delete salt from Firestore (key derivation impossible) await deleteDoc(doc(db, 'users', userId)) // 2. Delete all encrypted documents // (Optional - they're useless without key, but saves storage) await deleteUserLanterns(userId) await deleteUserPreferences(userId) // 3. Clear local key cache clearEncryptionKey() // Data is now mathematically irrecoverable } |
|---|
Summary: Lantern Privacy Architecture โ
| Question | Answer |
|---|---|
| Can Lantern read user data? | โ Noโencrypted client-side |
| Can Lantern delete user data? | โ Yesโcryptographic erasure |
| Can Lantern prove deletion? | โ Yesโsalt deletion = key destruction |
| Can a court order force decryption? | โ NoโLantern doesn't have keys |
| Can we still get product insights? | โ Yesโvia differential privacy on aggregates |
โ
Next Steps โ
- Extend encryption to cover all user preferences (interests, moods, etc.)
- Add a cryptographicErasure() function for GDPR "right to be forgotten"
- Implement differential privacy for aggregate analytics if needed
- Document in security docs for transparency with users