Multi-tenancy is the easiest thing in the world to claim and one of the hardest to prove. Any platform can put two organisations behind the same login and call them isolated. The real question is what stands between them at the exact moment a single line of application code forgets to add a filter.
For us, the answer is that the isolation does not live in the application at all. It lives in the database.
The forgotten WHERE clause is the whole problem
Most multi-tenant systems enforce separation in application code. Every query that touches shared tables carries a condition — this organisation only — bolted on by the developer who wrote it. It works right up until someone writes the one query that doesn’t. A new endpoint, a reporting job, a hurried hotfix, an ORM call that builds its own SQL. Miss the filter once and one organisation’s data is served to another. The boundary is only ever as strong as the least careful query in the codebase, and codebases grow.
That is a bad place to keep your most important security guarantee. Application code is exactly the layer that changes fastest and gets reviewed least when the deadline is close.
One central rule the whole system defers to
So we moved the guarantee down a level, into the database’s row-level security (RLS). Instead of trusting every query to remember the boundary, the database refuses to return a row that doesn’t belong to the caller’s organisation — regardless of what the query asked for.
The important design decision is that there is a single, central access rule that every data-access policy defers to. It is written once, in one place, and every table that holds organisation-scoped data points back at it. There is no per-table copy to keep in sync and no chance that one table quietly disagrees with another about who can see what. A forgotten filter in application code no longer leaks anything, because the application code was never the thing enforcing the filter.
The database is the final line of defence
A rule is only as good as the identity it runs under. Ours matters: the application talks to the database as an unprivileged role — one that has no power to see across organisations and no power to switch the rule off. When a request comes in, the database evaluates the central access rule as that constrained role and returns only what the role is allowed to see.
This is the part that makes the guarantee honest. The database, not the application, is the last thing standing between two organisations. A bug in the application layer — a broken check, a mis-scoped session, a query that should never have been written — does not disable the boundary, because the application never had the authority to disable it in the first place. The enforcement and the code most likely to contain the mistake are two different layers with two different privilege levels.
Proving it, without cheating
Claiming isolation is cheap. We back it with more than 500 automated isolation tests, and the way they run matters as much as the fact that they exist.
Most importantly, the tests connect as the same unprivileged role the application uses. A test suite that runs as a superuser proves nothing — a superuser bypasses row-level security by definition, so it would sail through every check while a real user hit a wall. By running under the enforced role, the tests exercise the actual boundary a real request meets, not a friendlier one.
Among them are property-based (fuzz) tests: instead of a human enumerating cases, the suite generates adversarial inputs — such as cross-organisation references and malformed scopes — and asserts that not one of them returns another organisation’s row. It is deliberately trying to break out, over and over, from inside the constrained role. When it can’t, that is evidence, not a slogan.
One instance, government and enterprise, side by side
This is what lets a single instance safely serve two very different worlds at once. On one side, government organisations — the local-government sector the platform was built for — grouped under a parent, state-level grouping. On the other, multi-site enterprises with their own internal structure. Between any two organisations, the isolation is strict and identical, whichever world they belong to. Nobody gets a weaker boundary because of who sits next to them.
Being honest about that boundary means naming its one deliberate hole. Two kinds of privileged role — a platform administrator operating the system and a read-only auditor reviewing it — do have cross-organisation visibility. That is not a leak; it is a documented, intentional exception, scoped to the narrow job of running and auditing the platform. For every ordinary organisation-scoped user — every administrator, every viewer inside a tenant — isolation is absolute. We would rather state the exception plainly than pretend the system has none and be wrong.
Isolation is more than rows
Keeping one organisation’s rows away from another is the floor, not the ceiling. Some operations are sensitive enough that seeing your own data isn’t sufficient authority to perform them, so they carry a second gate on role and organisation type.
The clearest example is vocational data. Only an organisation flagged as a Registered Training Organisation (RTO) can generate a Vocational Education and Training (VET) data export — the domain governed by public standards such as AVETMISS (the Australian Vocational Education and Training Management Information Statistical Standard). An administrator at an organisation that isn’t an RTO is refused outright, even for its own data, because it has no business producing that export in the first place. The row boundary decides whose data you can touch; the role-and-type gate decides whether this operation is yours to run at all.
How this connects
Putting the guarantee in the database is the same philosophy that runs through the rest of the platform: wire the connections into the schema, not into middleware, and keep every organisation’s data inside Australian data sovereignty guarantees. It is also what makes it safe to sell one platform rather than a bag of modules: when isolation is enforced by the database and proven by tests that can’t cheat, one instance can hold both a state’s worth of government organisations and a national enterprise without either ever seeing the other — each signing in through its own identity provider and seeing the product in its own branding.
Isolation you enforce in application code is a promise. Isolation the database enforces, under an unprivileged role, against hundreds of tests that try to break it — that is something you can hand an auditor.