In this article
Context
As we expand from a single-tenant learning platform to supporting teams and organisations, we need to isolate content data between tenants in our RAG pipeline. A data leak where Tenant A's proprietary content appears in Tenant B's responses would be a critical trust and compliance failure.
Options Evaluated
Row-Level Security (RLS) with tenant_id filter
Pros
- +Single database, single schema โ simpler operations
- +PostgreSQL RLS enforces isolation at the database level โ can't be bypassed in application layer
- +Works with our existing pgvector setup
- +Scales to thousands of tenants without infrastructure changes
Cons
- โRLS policies add query planning complexity
- โDeveloper mistakes in disabling RLS can expose all data
- โMetadata filtering on vector indexes adds ~10-20ms per query
Collection-per-tenant (separate vector namespace)
Pros
- +Strong physical isolation โ tenant data never shares an index
- +Easy to delete all tenant data (drop collection)
- +No risk of cross-tenant query leakage at the vector DB level
Cons
- โDoes not scale beyond ~1000 tenants in most vector DBs
- โOperational overhead: N tenants = N indexes to manage
- โCannot do cross-tenant analytics
Schema-per-tenant (separate PostgreSQL schema)
Pros
- +Strong isolation
- +Each tenant schema is independently backupable
Cons
- โOperationally complex โ schema management, migrations must run per-tenant
- โOnly practical for a small number of large tenants
Decision
Pending final evaluation. Lean toward RLS with tenant_id metadata filtering for vector queries, combined with application-level tenant context validation. This balances isolation quality with operational scalability. Will implement collection-per-tenant for any tenants with > 100K documents and compliance requirements.
Consequences
- โขAdd tenant_id column to all content tables with NOT NULL constraint
- โขEnable RLS on all content tables with tenant_id-based policies
- โขAll vector search queries must include tenant_id metadata filter
- โขAudit all LLM prompt assembly to verify cross-tenant context cannot be injected
- โขImplement output validation step to detect and redact potential cross-tenant references

