White-label security audits
Your client asked how you guarantee tenant isolation.
You ship Supabase apps. You carry the liability. And when a client’s security reviewer asks whether one customer can reach another’s rows, nobody on the project has checked, because checking properly is boring to write and nobody writes it.
I prove it, and you hand the result to your client with your name on it.
Not a policy review. I seed rows owned by two synthetic tenants, assume each identity the way auth.uid() actually resolves, and attempt cross-tenant reads, blind writes, and blind deletes, including on tables whose ownership runs through a foreign key. Then I roll all of it back. If data comes back, it comes back, and there is no interpretation step left to get wrong.
Why the answer you have is not one
-- What the security questionnaire asks
"How do you guarantee tenant A cannot access tenant B's data?"
-- What most Supabase projects can actually answer
"Row Level Security is enabled on every table."
-- ^ a description of an intention, not a result.
-- RLS enabled with using (true) is RLS enabled.
-- What you hand them instead
LEAK none
UNPROVEN none
OK 41 tables, 164 cross-tenant probes, 0 reached
-- proven 2026-09-05T04:11Z, re-proven on every mergePer-command policies mean a table can be correct for reads and wide open for deletes at the same time, and the obvious test cannot tell the difference, because the obvious test reads a column and therefore triggers the SELECT policy that hides the row. Every scanner that reads pg_policies calls that table protected.
The same blindness covers column privileges. A perfect policy, with both USING and WITH CHECK scoped correctly, still lets a logged-in user rewrite every column of their own row, including role, plan, and credits. Supabase grants update table-wide by default, so nearly every project you have shipped has this open right now.
Run it on a client project first
The prover is open source and MIT licensed. Point it at a preview branch of any project you maintain and you will know within minutes whether this is a portfolio-wide problem or whether your team is already handling it.
npx rls-sentinel --db "$DATABASE_URL"github.com/investnovation/rls-sentinel
What you get
A report you can hand over. Severity ranked, every finding with the exact SQL or code that fixes it rather than a description of what should be fixed. Under your letterhead and your name, or unbranded so it reads as your own capability, or with mine on it if an independent third party is what the client wants. Your call, per engagement.
A retest after the fixes land, included in every tier above the Exposure Check. Most firms charge again for this. It is an afternoon, and it is the difference between a report and a resolution.
A per-project proof URL. A page your client’s reviewer can open themselves that says when isolation was last proven and exactly what was probed. It updates on every run. This is the thing that ends the email thread.
Overnight turnaround. I work UK and US business hours from Manila. You send a schema at the end of your day and read findings at the start of your next one.
In writing, so you never have to ask
I will not take your clients. Not during the engagement, not after it, and not if they contact me directly. If a client of yours emails me, I forward it to you. This is in the terms on every job, not a handshake.
I stay behind you. Unbranded is the default. I have no interest in being visible on your client’s account, and no part of my business depends on being seen there.
No production access, and I will refuse it. A preview branch, a staging project, or a schema and policy export covers it. The tool actively refuses to run against a database that looks live. No customer data changes hands, which means no DPA to negotiate and no conversation with your client’s legal team.
I will not help anyone look secure while being otherwise. If a finding is real it goes in the report. If what you need is a document saying everything is fine, I am the wrong supplier and I would rather tell you now than after you have paid.
Partner pricing
Fixed price per engagement, and no scoping call. Partner rates sit below the published rates on the audit page, with room for you to mark up, and they move with how many projects you bring. So they come in a reply rather than off a table. One email, one number, no meeting.
Exposure Check
Proof run against one client project, plus an anon-key exposure check and the column-privilege pass. The leaks, with the exact fix for each. If it finds nothing, it is free.
Full Audit
Everything in scope, written up as a client-ready report, severity ranked, in your branding or unbranded. Retest after the fixes land, included.
Audit and Remediation
The full audit, and I implement the fixes in a branch with a pull request, every commit naming the finding it closes, then verify with a second proof run.
Continuous Verification
The prover wired into CI as a merge gate on every client repo, plus the per-project proof URL, plus a monthly review of each new table, policy, function, and bucket that appeared. Minimum five projects.
In scope
- Cross-tenant read, write, and delete isolation, proven
- Ownership through foreign keys and multi-hop joins
- Column-level write privileges and privilege escalation
- RLS coverage and policy correctness
- Anon-key exposure on the public Data API
- Identity trust boundaries, the IDOR class
- SECURITY DEFINER exposure and search_path pinning
- Storage bucket policies and signed URLs
- Service-role key reachability
- Auth configuration and redirect allowlists
Not in scope
- Network and infrastructure security
- Frontend XSS
- Penetration testing
- Compliance certification
- Anything needing production data access
- Client relationships. Yours stay yours.
How it runs
You send a schema and policy export, or point me at a preview branch. One email, no call. I run the proof and the manual pass on everything the tool cannot reach. You get the report in the agreed turnaround. Your team fixes what came back, and I retest free and update the proof URL.
Half up front, balance on delivery, via PayPal, Wise, or Payoneer. A call is available if you want one, but it is never the deliverable and nothing waits on it being booked.
Or write to hello@investnovation.com from wherever you read your mail.
Tell me the stack, roughly how many client projects you maintain on Supabase, and whether you want the report branded or unbranded. I will reply with a scope, a price, and a date, not a questionnaire. Or run npx rls-sentinel on a client project first and email me what it printed.
Investnovation
Written by the author of rls-sentinel.
The same audit, at published rates, for direct clients