Of all the challenges ISV teams face when adding embedded reporting to their products, multi-tenant data isolation is the one that causes the most serious problems — not because it's impossible to solve, but because its failure mode isn't a bug, it's a security incident.

Tenant A seeing Tenant B's data is not a UX problem you patch in the next sprint. It's a breach. For ISVs serving enterprise customers with data privacy obligations, it can end contracts and create legal exposure. Getting this right isn't optional — and most teams underestimate what "getting it right" actually requires until they're well past the first version.

The Root of the Problem: Assumed vs. Enforced Isolation

The most important distinction in multi-tenant reporting security is whether isolation is enforced by the analytics platform or assumed to be handled by your application layer.

Assumed isolation means the reporting platform trusts whatever data your application sends it. You're responsible for filtering correctly before anything reaches the analytics layer. If your application passes a misconfigured query, a stale session, or a cached result from the wrong tenant — the platform displays it. There's no safety net. The security model is only as strong as every line of your application code that touches the data pipeline, forever.

Enforced isolation means the platform itself is tenant-aware. It knows who is making a request, which tenant they belong to, and what data that tenant is permitted to see — independently of what your application layer does. Even if your application has a bug, the platform won't serve the wrong tenant's data. The guarantee comes from the platform architecture, not from the correctness of your code.

When evaluating any embedded reporting platform, ask this directly: "Where is tenant isolation enforced — at the platform level or in my application?" If the answer puts the responsibility on your application, that's assumed isolation. For a production ISV deployment, that's not sufficient.

The Three Data Architectures — and What Each Requires

How you structure your tenant data determines what the isolation problem actually looks like for your specific deployment.

Shared database, shared schema

All tenants' data lives in the same tables, separated by a tenant ID column. Isolation depends on every query including the correct WHERE clause filter. This is the simplest architecture to build initially — and the most vulnerable. A single missing filter anywhere in the reporting query pipeline exposes cross-tenant data. For ISVs handling sensitive data categories, this architecture is difficult to certify as secure regardless of how carefully it's implemented.

Shared database, separate schema per tenant

Each tenant has their own schema within the same database instance. Tables are namespaced — there's no WHERE clause to forget, because the isolation is structural. This is a solid middle-ground architecture. The reporting platform needs to know which schema to query for each tenant at runtime, but the isolation guarantee is stronger than the shared-schema approach. Schema migrations are the operational complexity: changes need to propagate across every tenant schema.

Separate database per tenant

Each tenant has their own database instance entirely. Complete isolation — no shared infrastructure between tenant data stores. This is the most secure pattern and the most common in enterprise ISV deployments where customers have data residency requirements or host their own infrastructure. It's also the most demanding for the reporting layer: the platform must route each query to the correct database instance at runtime, based on the authenticated user's tenant context. This is called dynamic data source routing, and it's not supported by most reporting tools or charting libraries out of the box.

Dynamic Data Source Routing

Yurbi resolves the connection string at query time from the authenticated user's tenant context — no static list of connection strings to maintain, no manual configuration per customer. New tenant provisioning can be automated via API. The platform handles the routing; your team handles the integration. For a full technical breakdown of all three architectures, see Chapter 4 of the Build vs. Buy guide.

Row-Level Security: Query Filter vs. UI Filter

Tenant-level isolation addresses which database a user can query. Row-level security (RLS) addresses which rows within that database a user can see. Both are required for a complete multi-tenant security model.

The critical distinction is where the filter is applied. A UI-level filter hides rows from the display but doesn't prevent the underlying query from fetching them. An export, an API call, or a cached report can still return the restricted rows. UI filtering is not security — it's cosmetic.

A query-level filter applies the restriction in the SQL WHERE clause itself. Only the permitted rows are ever fetched from the database. Export, API access, cached results — all of them are filtered at the source. This is what row-level security actually means when it's implemented correctly.

Test this during any evaluation: apply RLS to a test user, then attempt to access the restricted data via CSV export. If restricted rows appear in the exported file, the implementation is UI-level only.

The Dynamic Routing Operational Challenge

For ISVs using per-tenant databases, dynamic data source routing introduces an operational question: how do new customers get connected to the reporting platform?

Platforms that require static connection string configuration — manually adding each tenant's database credentials to the analytics admin — create an onboarding dependency. Every new customer requires a manual step in the reporting platform before they can see any data. At 10 customers, manageable. At 100, a bottleneck. At 200, a reliability risk.

The right answer is API-driven provisioning: when a new customer is onboarded in your application, an API call to the analytics platform registers their data source. No manual step, no dependency on an admin completing a task before the customer can access reporting. This is how mature ISV deployments handle tenant onboarding at scale.

What Solving This Challenge Actually Looks Like

A correctly implemented multi-tenant reporting layer enforces isolation at multiple levels: the database connection is routed to the correct tenant instance at query time, row-level security filters are applied in the query layer not the display layer, cached results are namespaced per tenant so no cached data is ever served across tenant boundaries, and SSO passes the authenticated user's tenant context to the reporting platform so it knows from the first request which tenant is active.

Building all of this from scratch is possible — it's also a significant engineering project that most ISV teams underestimate. The teams that get it wrong most often are the ones that shipped a working first version quickly and discovered the isolation gaps when they had real customers on real data. At that point, fixing it requires retrofitting security into an architecture that wasn't designed for it — which is harder and riskier than getting it right the first time.

Multi-tenant isolation enforced at the platform layer.

Dynamic data source routing, query-level row security, per-tenant cache isolation — included in every Yurbi plan. Test it against your architecture with a free trial.

Download Free Trial