← All articles

Article · 2 min

Privacy by design, not by retrofit

On a healthcare platform, we didn't add security at the end. It shaped the architecture from day one — and that order of operations is the whole point.

There’s a moment in many projects where someone says “we should probably encrypt that,” and it’s usually too late for the answer to be good. I worked on a secure healthcare platform where that conversation happened before the first line of backend code — and the difference it made changed how I think about security entirely.

Database encryption is where the thinking starts, not ends

The default posture — encrypt the database, call it done — protects data at rest. But it leaves plaintext exposed to anything that can reach the database: application bugs, over-broad queries, internal tooling. For a platform handling highly sensitive healthcare information, that residual exposure was unacceptable.

So the design went further: multiple categories of personal data were encrypted at the application layer, before they ever reached the database. Defense in depth, past the database boundary. Even something with direct database access sees only ciphertext.

The decision has a price, and you pay it everywhere

Application-level encryption isn’t a free upgrade. Two costs dominated.

First, key management gets real. We used envelope encryption to separate the encrypted data from the encryption keys — the data lives in one place, the keys that unlock it in another. More moving parts, but the data/key separation is exactly what you want when the data is this sensitive.

Second — and this is the one that surprises people — you lose the ability to query what you encrypted. You can’t WHERE email = ? a ciphertext column. The answer was deterministic hashing: hash the sensitive value on the way in, and equal inputs produce the same hash, so you can do secure equality lookups without ever exposing plaintext. The honest trade-off: deterministic hashing leaks equality — identical values produce identical hashes. We accepted that where lookups were genuinely required, with the exposure understood.

Security stops being a module

Once you commit to this, security requirements propagate outward into places that don’t look like “security work”: API contracts, the data model, validation flows, logging rules (no sensitive data in logs — ever), least-privilege access throughout. Security became a design driver across the backend, not a checklist at the end.

I participated in implementing and maintaining these mechanisms as part of the backend and full-stack engineering effort, and the lasting shift for me is simple: security is an architectural requirement, decided up front — not a feature added at the end. Retrofitting privacy into a mature system is a crisis. Designing for it from day one is tractable.

It also reframed “done” for me. On sensitive-data work, a feature isn’t done when it works. It’s done when it works and the data it touches is protected by default.

↑↓ navigate · open · esc close