Multi-Tenant Data Isolation for AI SaaS Products
Last updated:
The leak nobody tested for
Most SaaS teams have tenant isolation reasonably under control for ordinary records. Every query includes a tenant ID, row-level security backs it up, and the test suite checks a few obvious cases. Then an AI feature arrives, and data starts flowing through places the original design never considered.
The classic incident goes like this. A customer asks the assistant a question. Retrieval searches the vector index for similar content, finds a very relevant paragraph, and the model quotes it. The paragraph came from a different customer's contract. Nobody wrote a bug, exactly. The similarity search simply had no tenant filter, because the index was added in a hurry by someone who assumed the application layer handled it.
The general tenancy patterns are covered in our notes on multi-tenant AI integration. This post focuses on where AI SaaS specifically leaks, and how to close each gap.
Where AI features leak between tenants
| Leak path | How it happens | Control |
|---|---|---|
| Vector and search indexes | Similarity search runs across all tenants' chunks | Mandatory tenant filter enforced in the query layer, or per-tenant namespaces |
| Response caches | Cache key based on the question text alone | Tenant ID and permission scope in every cache key |
| Conversation memory | Session or thread IDs guessable or reused | Server-side ownership checks on every thread load |
| Prompt and output logs | Support staff see all tenants in one tool | Scoped access, redaction, access logging |
| Fine-tuned or adapted models | Training on pooled customer data | Per-tenant adaptation or strict consent and de-identification |
| Agent tools | A tool accepts any record ID | Tools resolve tenant from the session, never from model arguments |
| Evaluation sets | Real customer examples copied into shared test data | Curated, consented or synthetic examples only |
Push tenant scope below the application
Relying on every developer to remember a WHERE clause does not scale, and it certainly does not survive an AI feature built at speed. Tenant scope should be enforced somewhere that a forgotten filter fails closed rather than open.
- PostgreSQL row-level security on tables holding chunks, embeddings and model outputs, with the tenant set per connection
- A retrieval function that takes the tenant from the authenticated context and refuses to run without it
- Separate namespaces or collections per tenant in a dedicated vector store, where the product's scale allows
- For high-sensitivity customers, separate databases or deployments, priced accordingly
Within a tenant, permissions matter too. An employee who cannot open the HR folder should not get its contents summarised by the assistant. Retrieval should filter by document-level permissions, ideally mirrored from the source system rather than reinvented.
Never let the model choose what it can see
It is tempting to give an agent a tool like search_documents(query, customer_id) and trust the model to pass the right customer. Prompt injection, a confused model or a crafted document can all change that argument. The tool should ignore any tenant supplied by the model and take it from the server-side session.
Instructions in a prompt are suggestions. Filters in the query layer are facts. Isolation belongs in the second category.
The same applies to documents. A malicious file uploaded by one user can contain instructions aimed at the model. If the model has no access path to other tenants' data, those instructions have nothing to reach.
Test for leaks like you test for bugs
- Create two or more synthetic tenants with distinctive, recognisable content, such as invented product names
- Run every AI feature as tenant A with questions designed to surface tenant B's content
- Assert that no output, citation or cached response contains tenant B markers
- Repeat after every change to retrieval, caching, prompts or agent tools
- Include permission tests within a tenant, not just between tenants
This runs in the same pipeline as your quality checks, which we describe in evaluation pipelines for AI SaaS. It is cheap, and it is the evidence enterprise security reviewers will ask for.
Deletion, retention and the provider side
When a tenant leaves or asks for data removal, every derived copy must go: chunks, embeddings, cached answers, stored conversations and logs past their retention window. Map these explicitly, because derived data is easy to forget and hard to find later.
Check the model provider's terms as well. Enterprise API agreements typically exclude your data from training and allow limited retention for abuse monitoring, but the specifics vary and change. Know which arrangement applies, where processing happens, and write it into your data processing agreements with customers.
Pooled learning without pooled leakage
Many AI SaaS products want to improve from all customers' usage. That is possible, but it needs care. Aggregate signals, such as which extraction fields users correct most often, are generally safe to use. Raw content from one customer should not end up generating output for another.
If you want to fine-tune on customer data, get explicit contractual permission, de-identify properly and consider per-tenant adapters for sensitive work. When SpiderHunts designs these systems through our SaaS development practice, we default to no pooled training on raw content unless a customer has clearly opted in.
Frequently asked questions
Is a shared vector index safe for multiple tenants?
Can prompt injection cause a cross-tenant leak?
Do enterprise customers require single-tenant deployments?
Should support staff see customer prompts and outputs?
Concerned about data separation in your AI features?
Tell us how tenants and AI features are set up today. We will walk the data path with you and flag the places a cross-tenant leak could realistically happen.
Related services
What we build for problems like this one