Back to blog
The Great Encryption Migration: How We Upgraded Every Module in a Single Release
3 min read
BREAKING CHANGE

The Great Encryption Migration: How We Upgraded Every Module in a Single Release

Migrating a live application to Zero-Knowledge encryption is like replacing an airplane engine mid-flight. Here's how we encrypted all 10 data modules in one massive release without losing a single user record.

EncryptionZero-KnowledgeArchitectureMigration Strategy

Version 4.0.0 introduced the Zero-Knowledge Vault — a secure foundation. But a foundation is useless without walls and a roof. Version 4.1.0 was the wall we built: the complete migration of every personal data module to the ZK encryption standard.

Ten modules. Thousands of lines of migrated code. A live user base actively writing data. No downtime. No data loss. No rollbacks. This is the story of the most ambitious release in Simple Money Tracker's history.

Ten Modules, One Encryption Standard

The migration touched every corner of the application. Expenses with their amounts, categories, and mood data — encrypted. Budgets with their time-series allocations — encrypted. Debts and lendings with their payment histories and contact links — encrypted. Goals with their target progress and contribution logs — encrypted. Subscriptions with their billing cycles — encrypted. Investments, contacts, notes, and linked storage — all encrypted.

Every module now uses the same KEK/DEK architecture: a Key Encryption Key derived from the user's master password via PBKDF2 with 600,000 iterations, and a Data Encryption Key for the actual AES-256-GCM encryption. The architecture is consistent. The security is uniform. The user experience is invisible — and that's the point.

10 modules. 0 data loss. 0 rollbacks.

We migrated expenses, budgets, debts, lendings, goals, subscriptions, investments, contacts, notes, and storage — all while users were actively using the app. The encryption layer sits between the UI and Firestore, completely transparent.

The Migration Strategy: Invisible to Users

The key engineering challenge was straightforward but terrifying: how do you encrypt data that's already stored in plaintext without breaking the app for active users? Our solution was a phased read-then-write approach. On first access after the update, each module reads existing data, encrypts it with the user's DEK, writes back the encrypted version, and updates the metadata tracking.

This means a user opens their Expenses page, and in milliseconds the system detects unencrypted records, encrypts them silently, and continues operating on encrypted data from that point forward. No migration wizard. No 'please wait while we update.' No friction. Just invisible protection.

Multi-Device Sync: The Hardest Problem We Solved

Encrypting data is one thing. Keeping it consistent across devices when every device has its own DEK is another. We implemented metadata-based sync tracking: every record gets an `updatedAt` timestamp and every deletion gets a metadata log. When a device comes online, it fetches only records changed since its last sync — not the entire collection.

We also migrated all caching from LocalStorage to IndexedDB, which gives us better performance, larger storage quotas, and proper async access patterns. The combination of incremental fetch + IndexedDB caching + metadata tracking means multi-device users experience near-instant sync without redundant Firestore reads.

The Vault Experience: Polished to Perfection

Beyond the data migration, v4.1.0 brought significant Vault UX improvements. We centralized the master key input into a single, beautiful dialog. We added rate limiting via Upstash Redis to prevent brute-force attacks on the vault password. We optimized the login flow with trusted device support and a 5-minute OTP timeout.

We also fixed a subtle but critical DEK race condition: if the DEK appears during the polling interval, the wait promise now resolves immediately. And we fixed the Web Worker offloading for heavy crypto operations, with a proper fallback to the main thread when Workers aren't available.

The Result: A Fortress, Not a Feature

Version 4.1.0 wasn't about adding new buttons or shiny animations. It was about completing a security promise. When we launched the ZK Vault in 4.0.0, it covered the core. With 4.1.0, it covers everything. Every byte of personal data that leaves a user's device is now ciphertext that only their device can read.

This is the standard every finance app should meet. Not because encryption is trendy, but because your financial data is nobody else's business. Period.

Want to see these features in action? Try Simple Money Tracker for free.

Get Started
Share:

Comments

Back to blog
    reCAPTCHA Enterprise Logo

    protected by reCAPTCHA