Security for Legal SaaS

Episode 27 · Module 6 · Authorization & Access Control

Multi-Tenant Data Isolation

19 May 2026 · 8:47 · Security for Legal SaaS

8:47 8:47

Your legal SaaS platform stores data for 50 law firms. Firm A's privileged litigation strategy. Firm B's M&A deal terms. Firm C's client communications about a pending regulatory investigation. If Firm A ever sees Firm B's documents, you don't have a bug — you have a lawsuit, a breach notification obligation, and likely the end of your company. Multi-tenant data isolation is the architectural foundation that prevents this. In Episode 25, we covered ethical walls — information barriers within a single firm. Multi-tenancy is the inter-firm equivalent: every firm's data must be completely invisible to every other firm, with no possibility of cross-contamination.

Today’s Lesson

Security for Legal SaaS — Episode 27: Multi-Tenant Data Isolation

The Stakes

Your legal SaaS platform stores data for 50 law firms. Firm A's privileged litigation strategy. Firm B's M&A deal terms. Firm C's client communications about a pending regulatory investigation. If Firm A ever sees Firm B's documents, you don't have a bug — you have a lawsuit, a breach notification obligation, and likely the end of your company.

Multi-tenant data isolation is the architectural foundation that prevents this. In Episode 25, we covered ethical walls — information barriers within a single firm. Multi-tenancy is the inter-firm equivalent: every firm's data must be completely invisible to every other firm, with no possibility of cross-contamination.

Three Isolation Models

The industry has converged on three primary approaches to multi-tenant data isolation, each with different tradeoffs between security, cost, and operational complexity:1

1. Shared Database with Row-Level Security (Pool Model)

All tenants share the same database tables. Every row contains a `tenant_id` column, and access is controlled at the row level.

Aspect Detail
How it works Every table has a `tenant_id` column. Every query includes a `WHERE tenant_id = :current_tenant` filter. PostgreSQL Row-Level Security (RLS) can enforce this at the database engine level — even if application code forgets the filter
Strengths Lowest infrastructure cost, simplest operations, easiest to scale horizontally
Weaknesses A single query bug can expose cross-tenant data. Noisy neighbour problems (one firm's heavy usage affects others)
Best for Early-stage SaaS with many small tenants and cost sensitivity

PostgreSQL RLS — which we introduced in Episode 8 — is the critical safety net here. RLS policies run at the database engine level, below the application code:2

sql
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON documents
  USING (tenant_id = current_setting('app.current_tenant')::uuid);

With this policy active, even a query that omits the `WHERE tenant_id = ...` clause will only return rows belonging to the current tenant. The database enforces isolation regardless of application bugs — a defence-in-depth pattern from Episode 4.3

2. Schema-Per-Tenant (Bridge Model)

Each tenant gets their own database schema within a shared database instance. Tables, indexes, and views are duplicated per schema.

Aspect Detail
How it works Tenant A's data lives in schema `tenant_a`, Tenant B's in schema `tenant_b`. The application sets the search path to the correct schema at connection time
Strengths Stronger logical isolation than shared tables. Schema-level backup and restore. Easier to customise per-tenant (additional fields, indexes)
Weaknesses Schema management overhead grows with tenants. Database migrations must apply to every schema. Connection pool management becomes complex
Best for Mid-tier SaaS with moderate tenant count (tens to low hundreds) and customisation needs

PostgreSQL's Citus 12.0 introduced schema-based sharding specifically for this model — enabling horizontal scaling across nodes while preserving schema-per-tenant isolation.4

3. Database-Per-Tenant (Silo Model)

Each tenant gets their own dedicated database instance — completely separate infrastructure.

Aspect Detail
How it works Tenant A connects to `db-tenant-a.rds.amazonaws.com`, Tenant B to `db-tenant-b.rds.amazonaws.com`
Strengths Strongest isolation — no shared resources at all. Independent backup, restore, and migration. Per-tenant performance guarantees. Simplest compliance story
Weaknesses Highest cost. Operational complexity scales linearly with tenant count. Cross-tenant analytics requires a separate data pipeline
Best for Enterprise clients with strict compliance requirements, large data volumes, or contractual isolation mandates
For legal SaaS: Many enterprise law firm clients will contractually require database-per-tenant isolation. Their security teams (and their insurers) want certainty that a vulnerability in the shared application code cannot expose their data to another firm. When a client's RFP says "dedicated database instance," they mean the silo model.5

Defence in Depth for Multi-Tenancy

No single isolation mechanism is sufficient. Defence in depth means layering multiple independent controls:6

Layer Control What It Catches
Application code Every query explicitly scoped by `tenant_id` First line of defence — prevents most cross-tenant data access
ORM/query builder Automatic tenant scoping middleware that injects `tenant_id` into every query Catches queries where developers forgot the tenant filter
Database (RLS) Row-level security policies enforce tenant isolation regardless of query content Catches bugs in both application code and ORM middleware
Network Tenant-specific database instances or schemas on separate network segments Prevents lateral access if one database connection is compromised
Testing Automated cross-tenant access tests in CI Catches isolation failures before they reach production

The testing layer is often overlooked. Your CI pipeline should include tests that explicitly attempt cross-tenant data access and verify it fails:

python
# CI test: ensure Tenant A cannot see Tenant B's data
def test_cross_tenant_isolation():
    # Set context to Tenant A
    set_tenant_context(tenant_a_id)
    
    # Create a document as Tenant A
    doc = create_document(content="Tenant A privileged communication")
    
    # Switch context to Tenant B
    set_tenant_context(tenant_b_id)
    
    # Verify Tenant B cannot access Tenant A's document
    assert get_document(doc.id) raises NotFoundError
    assert search_documents("privileged communication") returns []

Tenant Context Propagation

The most common source of multi-tenancy bugs is tenant context propagation — ensuring that every component in the request chain knows which tenant the current request belongs to.7

The tenant context must flow through:

  1. Authentication — the JWT token or session contains the user's `tenant_id`
  2. API middleware — extracts `tenant_id` from the token and sets it in the request context
  3. Service layer — passes `tenant_id` to every database query and external service call
  4. Database connection — sets `app.current_tenant` for RLS enforcement
  5. Background jobs — async tasks (email notifications, report generation) must carry the `tenant_id` from the originating request
  6. Logging — every log entry includes `tenant_id` for debugging and audit
The background job trap: A scheduled report generation job runs outside a user request context. If it doesn't explicitly set the tenant context, it may default to no tenant filter — and the report includes data from all tenants. This is a real and documented failure mode. Every background job must explicitly set and verify its tenant context before accessing data.7

The Snowflake Incident: A Cautionary Tale

The 2024 Snowflake breach affected over 165 organisations, including AT&T, Ticketmaster, and Santander.8 Critically, Snowflake's core infrastructure was never compromised. The attackers used stolen credentials — harvested from infostealer malware dating back to 2020 — to log into individual Snowflake accounts that lacked MFA.

The lesson for multi-tenant SaaS is twofold:

  1. Tenant-level security policy enforcement matters. If your platform allows tenants to opt out of MFA, some will — and those are the accounts that get breached. Enforce baseline security requirements across all tenants.
  2. Credential hygiene is a multi-tenant concern. Even with perfect data isolation, a compromised tenant account gives the attacker access to that tenant's data. Combine isolation with strong authentication (Episode 21) and SSO (Episode 22).9

Ethical Walls vs. Multi-Tenancy: The Complete Picture

With Episode 25 fresh in memory, here's the complete access control picture for legal SaaS:

Concept Scope Mechanism Failure Impact
Multi-tenant isolation Between firms Database isolation (RLS, schema, silo) Firm A sees Firm B's data — catastrophic
Ethical walls Within a firm Application-layer deny rules, search filtering Conflicted lawyer sees restricted matter — ethics violation
Matter scoping Within a firm User-to-matter assignment checks Unassigned user accesses matter — privilege breach
RBAC Within a firm Role-to-permission mapping User exceeds their access level — unauthorised action

Each layer is independent. A bug in ethical wall enforcement should never compromise multi-tenant isolation. A misconfigured role should never expose data across tenants. Independence between layers is the essence of defence in depth.

What's Next

Episode 28 covers Encryption at Rest vs. in Transit — how to protect data when it's stored on disk, when it's moving between services, and the envelope encryption pattern that makes key management practical.

Sources & Further Reading

Sources & references

  1. AWS, Multi-Tenant Data Isolation with PostgreSQL Row Level Security — RLS patterns for SaaS.
  2. DZone, Multi-Tenant Data Isolation and Row Level Security — implementation patterns.
  3. Redis, Data Isolation in Multi-Tenant SaaS: Architecture & Security Guide — comprehensive isolation model comparison.
  4. Citus Data, Citus 12: Schema-Based Sharding for SaaS — horizontal scaling for schema-per-tenant.
  5. Hunchbite, Multi-Tenant SaaS Architecture: Row-Level Security vs. Schema-Per-Tenant — architectural comparison.
  6. Aloa, How to Build a Multi-Tenant SaaS Database — comprehensive implementation guide.
  7. Dev.to, Multi-Tenant SaaS Data Isolation: Row-Level Security, Tenant Scoping, and Plan Enforcement with Prisma — tenant context propagation patterns.
  8. Cloud Security Alliance, Unpacking the 2024 Snowflake Data Breach — breach analysis.
  9. Push Security, Snowflake: Looking Back on 2024's Landmark Security Event — lessons learned.
  10. OneUptime, How to Design a Multi-Tenant Data Isolation Strategy on Azure SQL Database — Azure-specific guidance.
  11. Wikipedia, Snowflake Data Breach — timeline and impact.