Supabase security audit — a real audit, not a scanner.
The vulnerability almost every Supabase app has at some point
Supabase's Row-Level Security is opt-in, not on by default. The most common flaw isn't a missing lock — it's a lock that looks fastened and isn't. The canonical example:
-- Looks correct. Lets ANY logged-in user read EVERY tenant's rows.
CREATE POLICY "users can read" ON documents
FOR SELECT USING (auth.role() = 'authenticated');That policy passes a glance, passes most automated checks, and quietly exposes every tenant's data to every logged-in user. Only reading the code — and then testing it — catches it. The same class includes service_role keys on client-reachable paths (which bypass RLS entirely by design), over-fetching API routes, unauthenticated endpoints, and IDOR.
Why a scanner isn't enough
| Question about your app | Automated scanner | Harvey audit |
|---|---|---|
| Finds known-CVE dependency issues | ✓ | ✓ |
| Flags syntax-level patterns | ✓ | ✓ |
| Understands your authorization logic | — | ✓ |
| Tests whether tenant A can read tenant B's data | — | ✓ live |
| Reviews RLS policy semantics, not just presence | — | ✓ |
| Proves a finding is actually exploitable | — | ✓ pen-test |
| Covers code health, not just security | — | ✓ 10 modules |
| Tells you what it did not check | — | ✓ ledger |
Scanners are good continuous hygiene — keep yours. An audit answers the question a scanner structurally can't: does my app actually leak?
What Harvey checks on a Supabase + Next.js app
Ten modules, equal weight (security and code health). Among much else:
- Multi-tenant isolation — every RLS policy reviewed for semantics, not just enabled/disabled:
USING(true), wrong-column predicates, weakWITH CHECK, user-metadata trust,SECURITY DEFINERfunctions with unguarded writes. - service_role exposure — anywhere a service key sits on a client-reachable path.
- Live cross-tenant pen-test — we seed two tenants on a local copy of your stack and try to read across the boundary. Proof, not a warning.
- App Router boundaries — server→client data leaks, Server Action auth and validation.
- Data classification — every PII/PHI/PCI column and where it lives.
- Plus performance, duplication, dead code, maintainability, and test quality.
Full methodology → The Audit.
What you get
- A findings report in plain English, ranked by blast radius — written for a founder, not a pentester.
- For each finding: what it is, where it is, why it matters, and how to fix it.
- A coverage ledger: exactly what we checked and what we didn't, with reasons. No silent gaps.
- A re-audit credit: when you ship the fixes, we re-verify the critical findings once at no extra charge, if requested within 30 days of the original audit. Additional re-audits within that window are a paid add-on at 50% of the original audit price.
- Optional investor-ready summary: a buyer-facing document for fundraise or acquisition diligence.
Pricing
No "book a call to hear the price." Priced by codebase size, measured automatically during the free scan:
- Free scan — $0. Source-only, no credentials, same-day. Static findings from every module source alone can run, plus the ten-module coverage ledger, yours to keep.
- Connected audit — from $500. The full review with real verdicts, plus a read of your live database: live RLS, Supabase advisors, PII in production.
- Full audit — from $1,000. Everything in Connected, plus Harvey stands up a copy of your stack and proves findings with a live pen-test, and runs full mutation testing.
Full grid and size bands → Pricing.
Supabase security audit — common questions.
Is the Supabase anon key supposed to be public?
Yes — the anon key is public by design. Your security comes from Row-Level Security, not from hiding the key. If RLS is missing or misconfigured, that public key becomes a master key to your database. That's the single most common failure we find.
Can't I just run an automated scanner?
A scanner checks patterns and known CVEs. It can't tell whether your users can read each other's data, because that depends on your authorization logic across multiple files. That's what an audit is for. Run both — they do different jobs.
How much does a Supabase security audit cost?
Harvey's free scan is $0. Paid tiers are priced by codebase size, measured automatically during the free scan: a Connected audit (adds a read of your live database) starts at $500, and a Full audit (which stands up and attacks a copy of your stack) starts at $1,000. Most boutique vibe-code audits run $1,500–$5,000 for source review only; a traditional pentest runs $4,000–$12,000. Harvey sits between: deeper than a source-only audit, faster and cheaper than a pentest firm.
Do you need access to my database?
Not for the free scan — it runs on source only, no credentials. Only the Connected and Full tiers read your production database, and only read-only. The Full-tier pen-test runs against a copy Harvey stands up on its own machines, never against your production.
What if my app was built with Lovable, Bolt, Cursor, or v0?
That's exactly who this is for. AI-built Supabase apps are where we most often find cross-tenant data exposure — and the fix is usually straightforward once you can see it.
Will you help me fix what you find?
Every finding comes with a fix. The audit includes a free re-verification of the critical findings after you ship the fixes.
Run the free scan on your Supabase app.
Source-only, no credentials, same-day. If it finds nothing worth going deeper on, don't buy a thing.