In Metiva, every client company gets its own dedicated database. Isolation is the database connection itself, not a shared table with a tenant filter, and the request binds to a tenant from a verified claim inside a signed token. If that claim cannot resolve to its database, the request fails closed rather than serving the wrong data.
How is one client's data kept separate from another's?
Most multi-tenant software puts every customer's rows in shared tables and adds a tenant ID column that every query is supposed to filter on. It works until one query forgets the filter. For an agency holding several clients' leads, contracts, and revenue in one place, that is a class of mistake worth designing out entirely.
The approach here is stricter. A separate control-plane database holds only the registry: companies, identities, memberships, plans, and audit records. Actual client business data never touches it. Each client's records live in a database of their own, so there is no shared table for a query to cross by accident.
Binding a request to the right tenant is where isolation usually leaks, so the rule is deliberately blunt: the claim always wins. The tenant is taken from a verified company-ID claim inside the signed token, and any tenant header the browser sends is ignored. If the claim cannot resolve to a database, the request fails closed and serves nothing.
Access sits on top of that boundary. There are eight business roles, scoped per company, so the same person can be an admin at one company and finance at another. Those roles are declared once in a single registry that is code-generated into the front end and checked in CI, so the back end and front end cannot quietly disagree about who can see what.
For a Dutch agency answerable to the AVG, this is not an architecture footnote; it is a selling point. When a client asks where their data lives and how it is kept apart from everyone else's, the honest answer is that it sits in its own database, isolated by design, and that a misrouted request fails closed instead of guessing.
The trade-off is that database-per-company is more work to operate than a single shared table. That is the point. The isolation you can describe to a nervous client in one sentence is worth more than the convenience of a schema that assumes every query behaves.