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