VVektorIndex
Supabase / Next.jsSecurity / Database📈 High search volume

Supabase Multi-Tenant Data Leak — User Accessing Another Tenant's Data

The Exact Error

// CRITICAL INCIDENT — Production data exposure
// Discovered via user report: "I can see other company's invoices"

// The query that should fail but doesn't:
const { data } = await supabase
  .from('invoices')
  .select('*')
  // Missing: .eq('tenant_id', user.tenant_id)
  // RLS policy has a bug — tenant_id check not enforcing

// Affected data: 2,847 invoice records across 15 tenants
// Regulatory exposure: GDPR Article 32 breach notification required
// Time to notify regulator: 72 hours from discovery

What's Happening

A user from Company A can query and view records belonging to Company B. The RLS policy has a gap that isn't caught by unit tests.

Root Cause

Supabase RLS policies rely on correct JWT claims and policy syntax that is easy to get wrong under edge cases. Common causes: RLS policy missing on a joined table, tenant_id comparison using wrong type (UUID vs text), or OR condition that accidentally widens access.

Quick Diagnosis Checklist

Run through these steps to confirm this is your issue:

1

Immediately use Service Role key to audit which users accessed which tenant_ids in the last 24h

2

Check if the breach is ongoing — temporarily disable the affected table's RLS and re-enable with corrected policy

3

Identify all users who may have accessed data they shouldn't — required for GDPR breach notification

4

Check every table that joins to the affected one — multi-hop RLS gaps are common

The Permanent Fix

Implement automated RLS boundary tests in your staging CI/CD pipeline that intentionally try to cross tenant boundaries before every deploy. Never let this reach production again.

Drop-In Package That Permanently Fixes This

Instead of building the fix from scratch, use this production-ready package.

🧪
Multi-Tenant RLS Isolation Tester
Prove Client A can never see Client B's data — before you deploy to production.
$79
/month
What the fix looks like
// rls-tester.config.ts
import { RLSTester } from './rls-tester'

const tester = new RLSTester({
  supabaseUrl: process.env.SUPABASE_URL!,
  serviceKey: process.env.SUPABASE_SERVICE_KEY!,
  tenants: ['tenant_a_id', 'tenant_b_id', 'tenant_c_id'],
  tables: ['documents', 'invoices', 'user_profiles'],
  attacks: ['tenant_escalation', 'null_rls', 'jwt_tampering'],
  outputReport: 'compliance-audit-log.json'  // hand to auditors
})

// Run in CI before every deploy
await tester.runAll()  // throws if any isolation failure found
Setup time
60 minutes
Files included
8 files

Related Compliance Law

🇪🇺
GDPR Article 22 — Automated Decision-Making
ACTIVE ENFORCEMENT — reinforced by EU AI Act 2026
Max fine: €20 million or 4% of global annual turnover

Related Errors

supabase multi-tenant data leak fix, supabase rls tenant isolation failure, tenant a sees tenant b data supabase, supabase rls bypass cross tenant data exposure, fix supabase rls policy data breach