BlogTechnical

Multi-tenant RAG — the isolation boundary a security review must verify

Shared RAG infrastructure serving multiple tenants introduces a boundary that user-level access control does not cover: retrieval that crosses tenant lines. Here is what a security review must verify before calling that boundary sound.

Drel11 min read

“How do you keep tenants from seeing each other's data?” is a question every RAG-based SaaS vendor answers, and almost every answer we have read in a vendor security questionnaire response describes user-level access control: role-based permissions, row-level security on the source documents, per-user retrieval scoping. That is a real and necessary control. It is also an answer to a different question than the one being asked.

User-level access control governs which documents a given user, inside a given tenant, is allowed to retrieve — the boundary covered in depth in rag-access-control. Tenant isolation governs something upstream of that: can a query from Tenant A's retrieval path ever surface a chunk that belongs to Tenant B's index, regardless of which user issued it or what permissions that user has. These are different boundaries, enforced at different layers, and a vendor who answers the tenant-isolation question with a description of their user-permissions system has not actually answered it.

This piece is about the second boundary: what a security review has to verify when a RAG pipeline serves multiple tenants on shared infrastructure, where the failure mode is not “the wrong user in my company saw a document,” but “a different company's data ended up in my company's retrieval results, or mine ended up in theirs.”

“We have role-based access control” answers a real question. It is not the tenant-isolation question, and a reviewer who accepts it as one has left the actual boundary unverified.

Why this is not rag-access-control again

It is worth being precise about the layering, because the two boundaries compose. A well-built multi-tenant RAG system needs both: tenant isolation at the infrastructure layer (no query from Tenant A's application context can retrieve a chunk indexed under Tenant B), and user-level access control within each tenant (User X at Tenant A cannot retrieve a document User Y at Tenant A marked confidential to their team). A system with strong user-level controls and weak tenant isolation is not partially secure — the tenant boundary failing is a worse incident than any single user-permission gap, because it can expose one customer's entire corpus to another customer's entire user base at once.

The reason this gets conflated in vendor conversations is that both controls sound, described casually, like “access control.” A review has to separate them explicitly: ask the tenant-isolation question first, as an architecture question, before moving on to the user-permissions question as a within-tenant question.

Three isolation models

Vendors building multi-tenant RAG on shared infrastructure choose, whether they say so explicitly or not, from a small set of architectural models. Knowing which one a vendor has actually built determines what questions matter next.

Three tenant-isolation models for a shared RAG pipeline

ModelIsolation strengthTrade-off
Index-per-tenantStrongest — physical separationHigher infra cost; cross-tenant retrieval structurally impossible, not just policy-forbidden
Shared index, metadata-filteredDepends entirely on filter enforcementCheapest to run; isolation is a query-time control, not an architectural guarantee
Shared index, namespace-partitionedStrong if the vector store enforces namespace boundaries nativelyDepends on the vector database's own namespace guarantees — verify, don't assume

Index-per-tenant makes cross-tenant leakage an infrastructure-provisioning bug, not a query-logic bug — a meaningfully different (and lower) risk profile. Shared-index-with-metadata-filtering is the cheapest and most common model at scale, and it is also the model where the four threats below live most directly, because isolation depends entirely on a query-time filter being applied correctly, every time, with no architectural backstop if it is not.

1. Metadata-filter bypass

In the shared-index model, every chunk is tagged with a tenant identifier, and every retrieval query is supposed to include a filter restricting results to the requesting tenant's identifier. The isolation guarantee is only as strong as the guarantee that this filter is applied on every code path that can reach the vector store, with no exceptions.

In practice, this fails in predictable ways: a debug or admin endpoint that queries the index without the tenant filter for troubleshooting purposes and never gets removed; a batch job (re-indexing, analytics, evaluation) that operates across the whole index and has a bug in its own tenant scoping; a newly added retrieval path — a different feature, a different team — that reuses the vector-store client but forgets to apply the filter the original retrieval path always applied. None of these require an attacker. They are the ordinary way multi-tenant systems degrade as more code touches the same shared store.

2. Embedding proximity leakage

A subtler failure exists even when the metadata filter works correctly on every retrieval path: some vector database configurations compute approximate-nearest-neighbour search across index structures (graph or tree indexes) that were built across the full, multi-tenant corpus before the tenant filter is applied at query time — “filter after search” rather than “filter as part of search.” Depending on the specific implementation, this can leak signal about the existence or approximate content of other tenants' data through side channels: search result counts, latency differences between a query with many same-tenant matches versus few, or, in the worst implementations, an actual result-set overflow where too aggressive a top-k parameter surfaces a cross-tenant chunk before the post-filter step removes it — if the removal step has its own bug.

This is a genuinely narrower and lower-severity threat than a filter-bypass bug, but it is worth verifying specifically because it is invisible to the most common testing approach (functional test: “query as Tenant A, confirm no Tenant B document appears in the final response”) which only tests the end state, not whether the underlying search touched Tenant B's vectors at all. A vendor whose only isolation testing is functional, end-to-end testing has not tested this failure mode.

3. Shared cache and rate-limit side channels

Performance optimisations in a shared RAG pipeline — embedding caches, retrieval result caches, LLM response caches keyed on a normalised query — are a common source of cross-tenant leakage that has nothing to do with the vector store at all. A response cache keyed only on the literal query text, without a tenant identifier in the cache key, will serve Tenant B a cached answer generated from Tenant A's retrieved context if both tenants happen to ask a similarly phrased question.

Rate limits and quota systems can leak in a lower-severity but still material way: shared rate-limit buckets let one tenant infer something about another tenant's usage volume, and in poorly isolated implementations, one tenant's heavy usage can degrade another tenant's service — a noisy-neighbour problem covered next, but worth flagging here because the root cause (shared infrastructure state without a tenant dimension) is the same pattern that causes cache leakage.

4. Noisy-neighbour retrieval quality

Not every multi-tenant RAG failure is a confidentiality breach. Shared infrastructure without resource isolation lets one tenant's usage degrade another tenant's retrieval quality or availability — a large tenant's bulk re-indexing job consumes enough vector-store throughput that a small tenant's live queries slow down or time out; a tenant with a very large corpus pushes index structures into a regime where approximate search accuracy degrades for everyone sharing that index.

This belongs in a security review, not just an SRE review, because availability and integrity of retrieval are part of the system's security posture for any use case where a degraded or stale retrieval result feeds a decision. A procurement or compliance RAG assistant that silently returns lower-quality results during another tenant's bulk load is a different kind of failure than a cross-tenant data leak, but it is still a failure a security review should surface — particularly for a system whose evidence pack claims a specific retrieval-quality guarantee.

Verifying a vendor's isolation claim

A vendor security questionnaire answer of “we use logical isolation with tenant-scoped access controls” is a claim, not evidence. Reviews that treat it as evidence are the reason this boundary goes unverified as often as it does. The evidence that actually supports the claim looks like:

  • The architectural model from the table above, named explicitly — not a generic phrase.
  • A list of every code path that reaches the vector store, with confirmation of how each one enforces the tenant boundary.
  • Test evidence for cross-tenant isolation specifically — not just functional correctness tests, but tests designed to attempt a cross-tenant retrieval and confirm it fails at the architecture level, not just the response-formatting level.
  • Confirmation of tenant-scoped cache keys for every cache in the pipeline.
  • For shared-index deployments: the specific mechanism (pre-filter vs. post-filter search) the vector database uses, and whether that mechanism has been independently verified rather than assumed from documentation.

Where the vendor cannot produce this evidence, the honest disposition is not “isolation is broken” — it is “isolation is unverified,” and that distinction matters for how the finding gets written up. An unverified control is an evidence gap with an owner and a target date, feeding the disposition's residual risk acceptance, not a confirmed vulnerability.

Review checklist

For a RAG system built on shared, multi-tenant infrastructure, a review is complete on the isolation boundary when it can answer each of these with evidence rather than a policy statement:

  • Which of the three isolation models does the vendor actually run — named specifically, not described generically?
  • Is the tenant filter enforced at a layer that makes an unfiltered query impossible to construct, across every retrieval path including debug, batch, and analytics paths?
  • Does the vector database apply the tenant filter as part of search, or only after search — and has that mechanism been confirmed rather than assumed?
  • Are all caches in the pipeline (embedding, retrieval, response) keyed on tenant identity?
  • Does the vendor have test evidence specifically targeting cross-tenant isolation, distinct from functional correctness testing?
  • Is resource usage (query throughput, indexing jobs) isolated enough that one tenant's load cannot materially degrade another's retrieval quality or availability?

This checklist sits alongside, not instead of, the user-level access control checklist from rag-access-control. A complete review of a multi-tenant RAG system verifies both boundaries, and names which one each finding belongs to — because the fix for a leaking metadata filter and the fix for an over-broad user role are different teams, different code paths, and different urgency.

Verify the tenant boundary, not just the user permissions.

Drel's RAG pipeline review checks tenant isolation and user-level access control as distinct boundaries, so a vendor's 'we have access control' answer gets tested against the specific architectural claim it needs to support.

A note on scope: Drel reviews assessed systems against documented architecture, configuration and intent. It does not ingest live telemetry from production environments. Dispositions reflect the assessed system at the time of review and the re-assessment triggers that govern when the disposition must be revisited.