The Problem
You're building a SaaS. Multiple businesses will use the same database. Business A must never see Business B's data. Not "probably won't" — must not.
This is the multi-tenant data isolation problem.
The Solution: Row-Level Security
Supabase (PostgreSQL) has built-in Row-Level Security. Every row in every table can be filtered by who's asking.
CREATE POLICY "business_isolation" ON job_cards
USING (business_id = (auth.jwt() ->> 'business_id')::uuid);
That one line means: every query automatically filters to only rows where the business_id matches the caller's business (read straight from their JWT). No application code needed. No middleware. No accidentally forgetting a filter.
How It Works in Practice
- User logs in → gets a JWT carrying their business_id
- Every query against Postgres automatically has the RLS policy applied
- Business A queries job cards → only sees their own
- Business A tries to read Business B's rows → empty result (not an error, just empty)
What I Built
A workshop management ERP with:
- Multi-tenant architecture
- 17 SQL migrations
- Job card management
- Invoicing & billing
- Inventory tracking
- WhatsApp integration
All running on Supabase with RLS policies enforcing data isolation.