How we build

What to ask a vendor about tenant isolation

Every multi-tenant vendor says your data is separate. The question that distinguishes them is where the separation is enforced, and how it is tested.

All posts

The Nirogix team · 07/09/2026 · 6 min read

Everyone says yes

"Is our data separate from other hospitals?" has exactly one answer in a sales conversation, so the question does no work. The follow-up does: where is that separation enforced?

There are three common answers, and they are not equivalent.

Three architectures, three risk profiles

Separate databases per customer isolates strongly and costs the vendor dearly in operations, which usually shows up in how slowly they ship, and in a per-customer upgrade schedule that eventually diverges.

Shared database with application-level filtering is the common one. Every query is supposed to carry the tenant identifier. It works until a developer writes one query that forgets, and that single query is a cross-tenant data leak that no test will find unless somebody wrote the test.

Shared database with database-enforced isolation, meaning row-level security, puts the rule where it cannot be forgotten. A query without tenant context returns nothing, because the database refuses, not because the code remembered.

The questions that actually distinguish

Where does the tenant identifier come from? The only safe answer is the authenticated session. If any part of it can come from a request parameter or a header, a request can ask for another hospital’s data and the only defense is that nobody tried.

How is isolation tested? Ask for the shape of the test, not a reassurance. The useful test is adversarial: authenticate as one tenant and attempt to read another tenant’s record by identifier, on every module, and prove it fails.

What happens on a mistake? In a database-enforced model, a forgotten filter returns nothing. In an application-filtered model, it returns somebody else’s data. That difference is the whole argument.

Why we chose what we chose

Nirogix uses PostgreSQL row-level security. Tenant context comes only from the authenticated session and never from anything the client sends. Isolation is tested in both directions on every module: an entitled request works, an unentitled one is refused, and that test is part of the definition of done rather than an audit exercise.

It is slower to build against. A developer cannot take a shortcut that works locally and fails in production, which is occasionally annoying and exactly the point.

See it running with your own workflows.

Book a walkthrough and we will map your clinic or hospital onto the platform, module by module.