RowWarden

Security review for Supabase + Vercel apps

Free scanners flag it. We fix it.

A fixed-price review of your Row Level Security, auth, API routes, keys and Stripe webhooks. In 48 hours you get a written report and a pull request with the fixes.

  • $249 launch price
  • 48 hours to results
  • Read-only in production

The problem: your app has a second door

Most Supabase apps lock the front door, their own API code. But the database can also be reached straight from the browser, using the public key your app ships with. Whether that's safe depends on Row Level Security being right on every table, including the ones added later.

On a live payments app, a review found strangers could read every customer's history through the database's public door, while the app's own code looked fine.

Code review alone can miss this, because the hole isn't in the code. It's in the database's rules.

What we check

For apps built on Supabase and deployed on Vercel (Next.js or Vite).

  • Row Level Security

    Can a stranger, or a logged-in user who isn't the owner, read or change rows that aren't theirs? Every table, not just the ones you remember.

  • Auth

    Is sign-in doing what you think it does, and does "logged in" get treated as "allowed"?

  • API routes and serverless functions

    Does each route check that the user owns the record it touches, not only that they're logged in?

  • Exposed keys

    Is any secret key in the browser bundle, a public environment variable, or your git history?

  • Stripe webhooks

    Are payment events verified, and do amounts come from your server rather than the browser?

What you get

  • A written report in plain language, with each finding explained.
  • Findings ranked by real-world impact: what someone could actually take or change, in money or data, first.
  • A pull request with fixes you can review and merge.
  • Results in 48 hours.

How it works

  1. Book

    Reserve a review at the $249 launch price.

  2. Sign the one-page scope

    You list exactly which systems we may look at. Nothing starts until it's signed.

  3. We review

    Production stays read-only. We never write to your live app.

  4. Get the report and the fix PR

    Within 48 hours: the written report and a pull request with the fixes.

Who does the work

Straight answer: the review is done by an AI agent named Rowan. AI does the reading, and that's why it costs $249 and not thousands.

A human signs off on every finding. Scott Frischhertz reviews each one before you see it. Nothing reaches your report without his sign-off.

Price

$249 fixed price, one app

Launch price. It goes up after the first clients.

  • RLS, auth, API routes, exposed keys, Stripe webhooks
  • Written report, ranked by real-world impact
  • Pull request with fixes
  • Results in 48 hours
  • Production read-only; one-page signed scope first
Book a review

Questions first? rowan@rowwarden.com

Free: the 10-point Supabase self-check

Ten things to confirm on your own project. Each one is a setting or a fix, and each takes minutes. If any answer surprises you, that's what the review goes deep on.

  1. RLS is enabled on every table in exposed schemas. Not just the ones you remember: backup, _old and copy tables you made by hand count too, and they don't inherit your hardening.
  2. Run Supabase's built-in Security Advisor (Dashboard → Advisors) and clear everything it flags. It's free, and it's the floor, not the ceiling.
  3. No policy says true for everyone unless that table is genuinely public. Look for USING (true) and WITH CHECK (true) on anything with user data.
  4. Policies scope rows to the user (auth.uid()), not just to "is logged in." A logged-in stranger is still a stranger.
  5. The service-role key is server-only. It must never appear in a VITE_ or NEXT_PUBLIC_ variable, the browser bundle, or git history. If it ever did, rotate it.
  6. Views and functions respect RLS. A view created without security_invoker runs with its owner's rights, and so does a SECURITY DEFINER function. Make sure each one is meant to.
  7. Storage buckets are private unless they must be public, with file-size and file-type limits set on the bucket itself.
  8. Your API routes check ownership, not just login. If a route takes an id from the request, it confirms the logged-in user owns that record.
  9. Stripe webhooks verify signatures and ignore duplicates. Amounts always come from your server, never from the browser.
  10. You'd notice. Something alerts you to failed payments and unusual data access, instead of the only trace being buried in a log nobody reads.

FAQ

Is an AI really doing my review?

Yes. Rowan, an AI agent, does the review. Scott Frischhertz, a human, reviews and signs off on every finding before you see it. That split is how we keep the price at $249.

Will you touch my production app?

Production is read-only: no writes, no signups, no payments, no deletes. Nothing starts until you sign a one-page scope listing exactly what we may look at.

What's the difference from a free scanner?

A scanner flags things. We rank what we find by what it could actually cost you, explain it in a written report, and send a pull request with the fixes.

My app isn't exactly Supabase + Vercel. Can you still help?

The review is built for Supabase apps on Vercel using Next.js or Vite. If your setup is different, email rowan@rowwarden.com before booking and we'll tell you straight whether it fits.

What happens to my data and keys?

We keep your data only for the review and delete it after. If you share a key with us for the review, rotate it once we're done.