Announcements

Why We Over-Engineered Our Encryption

Our CTO explains the technical decisions behind Billix's encryption architecture, and why overkill was the right call.

January 13, 2026
7 min read
Marcus Chen

The Decision

When we started building Billix, we knew we'd be handling sensitive data. API keys, OAuth tokens, conversation histories with potentially confidential business information. The question wasn't whether to encrypt—it was how much to encrypt.

The easy path was standard at-rest encryption with a single master key. Most SaaS products do this. It's compliant, it checks the security box, and it's simple to implement. We went a different direction, and I want to explain why.

AES-256 Wasn't Enough

AES-256 is the gold standard for symmetric encryption. Nobody's breaking it. The math is sound. But the algorithm is only as good as your key management. If a single master key encrypts all user data, then compromising that key compromises everything.

We chose AES-GCM 256-bit, which gives us authenticated encryption—not just confidentiality but integrity verification. Every encrypted value includes an authentication tag that detects tampering. If someone modifies the ciphertext, decryption fails rather than producing garbage data that might look valid.

This matters more than people realize. Integrity attacks are often more dangerous than confidentiality breaches because they can go undetected. A tampered API key doesn't look wrong—it just authenticates to the wrong account.

Here's the difference between what most SaaS products do and what we chose:

AspectIndustry StandardOur Approach
EncryptionAES-256, single master keyAES-GCM 256-bit, per-user keys
IntegrityNone (encrypt only)Authentication tags on every value
Key derivationShared key, no derivationPBKDF2, 100,000 iterations per user
IsolationApplication-level scopingRuntime-enforced, query-level isolation
Key rotationAnnual or neverPeriodic, automated

Was all of this necessary? Probably not. Did it matter? Absolutely.

Key Derivation Choices

We use PBKDF2 with 100,000 iterations for key derivation. That number isn't arbitrary. It represents a balance between security and performance—enough iterations to make brute-force attacks impractical, but not so many that legitimate decryption becomes slow.

Each user gets their own derived encryption key. If User A's data is somehow exposed, User B's data remains encrypted with a completely different key. This is more expensive to implement than a shared key architecture, and it adds complexity to operations like database migrations. But it means a partial breach doesn't become a total breach.

We also rotate keys periodically. When a rotation happens, we re-encrypt all affected data with the new key. This is operationally expensive and required us to build a background job system specifically for key rotation. Worth it? I think so. Key rotation limits the blast radius of any single key compromise to the rotation window.

User Isolation

The isolation model goes beyond encryption. Every database query is scoped to the authenticated user. There's no code path that can accidentally return another user's data. This sounds obvious, but it's surprisingly easy to get wrong, especially in serverless architectures where connection pooling and concurrent execution can introduce subtle bugs.

We use Convex as our backend, which enforces data isolation at the query level. Every function runs with the authenticated user's identity, and the runtime prevents cross-user data access. We chose Convex partly for this reason—the security guarantees are built into the platform rather than bolted on as an afterthought.

Performance Trade-offs

I won't pretend this comes for free. Per-user key derivation adds latency to every authenticated request. PBKDF2 with 100,000 iterations takes about 200ms on our infrastructure. We mitigate this with key caching—once derived, the key is held in memory for the session duration.

The re-encryption during key rotation is a significant background load. We've invested in making this incremental and rate-limited to avoid impacting user-facing performance. A full key rotation across all users takes about 6 hours to complete, running at a controlled pace.

Was It Worth It

Here's my honest assessment: from a pure cost-benefit standpoint, we over-engineered this. The probability of a breach that our simpler competitors' encryption wouldn't also survive is low. We spent engineering time on security infrastructure that could have gone toward features.

But here's the thing—when an enterprise security team reviews our architecture (and they do, regularly), they don't have to squint. The encryption story is clean, the isolation is robust, and the key management is mature. That saves weeks of back-and-forth during enterprise sales cycles and builds genuine trust with security-conscious customers.

Security isn't just about preventing breaches. It's about earning trust. And sometimes earning trust means doing more than the minimum.

Let's Make Life Easier

Try Billix for
free right now

Start for free

Enterprise-
Grade Security

Effortless
For Everyone

Automation
Made Natural

Unified
Workflow Sync

Start for free, right now