Rowseal

Can one of your customers read another customer's data?

Rowseal reviews multi-tenant apps on Postgres, Supabase and Prisma for one kind of bug: data leaking between customers. You get the answer in writing, with proof, the fix, and tests that keep it fixed.

Request a reviewSee what we check

Same query. Two policies.

Signed in as Acme Dental

select * from invoices;

create policy "read invoices"
  on invoices for select
  using (auth.uid() is not null);

This policy checks that a user is logged in. It never checks which company they belong to. It passes every test written with a single user.

Rows returned to Acme Dental
CompanyInvoiceAmount
Acme Dental
INV-1042
1,280.00
Globex Labs (another company)
INV-2210
9,400.00
Acme Dental
INV-1043
640.00
Initech (another company)
INV-3307
2,150.00
Globex Labs (another company)
INV-2211
5,725.00

3 of 5 rows belong to other companies.

Example data. Fictional companies.

What we check

The ways one customer's data can reach another, in the database and in the app code that talks to it.

Tables with RLS turned off
Exposed through the API with no row rules
Login checked, ownership not
Policies like auth.uid() is not null
Writes into other companies' data
Insert and update policies whose with check ignores the company
Trusting what users can edit
Policies that read user_metadata
Functions that skip tenant checks
security definer functions callable from the API
Views that ignore RLS
Views without security_invoker
Storage buckets
Files readable across companies
RLS that never runs
Apps connecting as table owner or superuser
Prisma queries
Reads and writes missing the tenant filter
After Supabase's Oct 30 change
GRANTs added to fix 'permission denied' errors on new tables, without RLS

How an engagement works

Every review is done personally by the founder, never outsourced.

  1. 20-minute scoping call Your stack, how tenants are separated, what's in scope.
  2. Fixed quote and written permission Scope, dates, staging only.
  3. Schema-only dump pg_dump --schema-only. No customer data leaves your hands.
  4. We try to break it Two test users in two companies, every read and write path in scope.
  5. Report Each finding with proof, severity, and the exact SQL that fixes it.
  6. Tests in your repo Plain SQL tests (pgTAP if you already use it) that run in your CI and fail if the leak comes back, plus one retest after you fix.

We need read-only access to a staging database, or a schema dump plus policy definitions. We never need production data or the service_role key for production. NDA available on request. Any dump is deleted within 30 days after the engagement ends.

We never call a database "secure." A clean report says: no isolation failures found in the tested scope.

Engagements

  • Tenant Isolation Review Full review, written report, fix SQL, tests, one retest. About five business days; dates fixed in the quote.
  • Fix implementation We write and test the fixes with your team.
  • Evidence Pack The report, fixes and retest results, formatted for SOC 2 evidence requests, security questionnaires and investor due diligence.

Also available: migration verification. After a database move, we prove every row arrived intact.

Fixed price, quoted after the scoping call.

Built on Rowseal Engine

Reviews use our own checking tool for row-level security, grants and policies. It has more than 6,500 automated tests of its own, tested against PostgreSQL 13 through 18. Before using it on anyone's database, we put it through twelve rounds of hostile security review and fixed all 81 findings. It reports what it could not test instead of passing it.

Request a review

mark@rowseal.com

Open in mail app

Tell us your company, your stack, and what's driving the review (SOC 2, an enterprise customer, a fundraise, the Oct 30 change). We'll reply to set up the scoping call.