What we check and fix (17 items)
On paid plans, with the owner's consent, PatchAndShip checks six areas: Row Level Security on every table, storage bucket policies, secret keys in the client bundle and repository history, secrets in public environment variables, the Supabase auth Site URL and redirect allow-list, and, on Fix & Deploy, the production build, domain, SSL and core flows.
Plain text version: /docs/what-we-check.md
The six areas
On paid plans, after you consent:
- RLS, on every table. Supabase Row Level Security (RLS): switched on for every table, with policies so each user can reach only their own rows.
- Storage, private buckets. Private buckets for private files, with access policies.
- Exposed keys, out of the bundle. We scan the shipped JavaScript bundle and repo history for service_role keys and other secrets, remove them and tell you exactly which keys to rotate.
- Env vars, secrets out of public variables. Secrets moved out of public (for example
VITE_) variables. With Fix & Deploy we also set them on the host. - Auth redirects (fixed on Fix & Deploy). We check the Supabase Site URL and redirect URLs on every paid plan; with Fix & Deploy we point them at production instead of the preview. On Security Fix, any change is listed as a to‑do in your report.
- Deploy, domain and SSL (Fix & Deploy only). Env vars on the host, custom domain with SSL, build fixes, and a smoke test of login, signup and your core flow. The Fix & Deploy package ($249) deploys one app to Vercel or Netlify, or keeps a Lovable or Replit app on that platform's own hosting with your domain. Each order covers one app, one Supabase project (or one Node app) and one deploy target.
Node/Express backends: missing server‑side access checks, open CORS and hard‑coded secrets; these are fixed, but they are not “critical” for the 48‑hour guarantee.
What the guarantee covers
Security Fix: every critical issue on our checklist fixed within 48 hours of working access. Fix & Deploy: fixed and live on your host within 48 hours. Otherwise, a full refund if you ask within 14 days of purchase. “Critical” means only the issues on our published checklist: Row Level Security (RLS) disabled or misconfigured, public storage buckets holding private files, exposed secret keys (in the client bundle, repo or public env variables), and, on Fix & Deploy only, misconfigured environment variables or auth redirects.
Full terms: Refund Policy.
The 17 items
These 17 items are what we check and fix, within your plan's scope (items 14 to 17 on Fix & Deploy only). Only the issues our Refund Policy defines as “critical” are covered by the 48‑hour guarantee, and they differ by package:
- Security Fix:
Row Level Security (RLS) disabled or misconfigured, public storage buckets holding private files, and secret keys exposed in your client bundle, repo or public env variables.
- Fix & Deploy:
Row Level Security (RLS) disabled or misconfigured, public storage buckets holding private files, exposed secret keys, and misconfigured environment variables or auth redirects.
“Live” meansdeployed to production on the host you chose for your order.
SECURITY DEFINER leaks (item 6) and the Node/Express items (9 to 13) are fixed, but they are not “critical” for the 48‑hour guarantee. Full terms: Refund Policy.
Supabase‑backed apps (Lovable, Bolt, Cursor, Replit with Supabase)
- 1. Row Level Security disabled on tables in API‑exposed schemas
- 2. Permissive RLS policies (
USING (true)or open writes) on non‑public data - 3. Public storage buckets (and broad list or upload policies) for private files
- 4. Secret or
service_rolekeys in the client bundle or repo - 5. Other secrets under public env prefixes (
VITE_*,NEXT_PUBLIC_*) - 6. SECURITY DEFINER views or RPCs callable by
anonthat expose private data - 7. Auth Site URL or redirect allow‑list not set for production (customer‑assisted when our Supabase role can't change it; fixed on Fix & Deploy, a to‑do in your report on Security Fix)
- 8. Misconfigured environment variables that block secure production operation (a secret on the client, or a missing server env on the host; host env vars are set on Fix & Deploy only)
Node/Express‑style apps (typical Replit or Cursor backend)
- 9. Missing server‑side authentication or ownership checks on private routes (IDOR, open admin, open destructive methods)
- 10. Open CORS that reflects any Origin with credentials
- 11. Secrets hard‑coded or committed; Replit Secrets not used
- 12. Missing security headers or insecure session cookies (not “critical” for the 48‑hour guarantee)
- 13. Server not bindable for publish (
localhostonly, or the wrong port)
Fix & Deploy only
- 14. Production build failures we can fix without a rewrite
- 15. Single‑page app deep‑link 404s (missing catch‑all rewrite)
- 16. Custom domain and SSL, when you control DNS and apply our records (waiting on DNS pauses the clock)
- 17. Smoke test of signup, login, the password‑reset landing page and one named core flow
Why these matter (from vendor docs)
- Supabase's Security Advisor flags RLS disabled on a public table (lint 0013, level ERROR):
Anyone with your project URL can read, edit, and delete all data in this table because Row‑Level Security is not enabled.
(Supabase Docs: Database Advisors) - Supabase: grants control whether a role can reach an object, RLS controls which rows it can access.
Use both controls for every exposed object.
(Supabase Docs: Securing your API) - Supabase Storage buckets
are private by default
. For a public bucket,anyone who possesses the asset URL can readily access the file
. Supabase's examples are profile pictures, public media and blog content. (Supabase Docs: Storage Buckets) - Supabase:
A secret key bypasses every Row Level Security policy you have. Never put one in a browser, a shipped application, or source control.
Publishable and anon keys are designed to be public. (Supabase Docs: API keys) Supabase is deprecating the
, in favor ofanonandservice_rolekeys by the end of 2026sb_publishable_andsb_secret_keys. (Supabase Docs: API keys)- Vite docs:
Variables prefixed with
And:VITE_will be exposed in client‑side source code after Vite bundling.
(Vite Docs: Env Variables and Modes)VITE_*variables should not contain sensitive information such as API keys. - Supabase: change the Site URL
from
. It ishttp://localhost:3000to your production URLcritical for email confirmations and password resets
. In production, Supabase recommends setting the exact redirect URL rather than wildcards. (Supabase Docs: Redirect URLs) - Vercel: in a Vite single‑page app,
deep linking won't work out of the box
. You need a catch‑all rewrite to/index.htmlinvercel.json. (Vercel Docs: Vite on Vercel) - Replit: a published web server
must listen on
. Listening only on0.0.0.0localhostor127.0.0.1does not work for published apps
. Secrets set in the editordo not automatically carry over to your published app.
(Replit Docs: Troubleshoot publishing) - Supabase's changelog says that once the change reaches a project,
new tables you create in
The Data API is Supabase's auto‑generated REST and GraphQL layer. Existing tables keep their current grants and stay reachable, RLS behavior is unchanged, and apps that only use a direct Postgres connection are not affected. (Supabase changelog)publicschema require an explicit opt‑in (via a Postgresgrant) before the Data API can see them. - Supabase's planned timeline: from May 30, 2026, the new behavior became the default for new projects, rolled out gradually. From October 30, 2026, Supabase plans to apply it to all existing projects. As of October 14, 2026, that step has not happened yet. (Supabase changelog)
- When a grant is missing, the Data API returns error
42501,permission denied for table your_table
. (Supabase changelog) - Supabase's recommended fix treats the grant, enabling RLS and the policies as one unit.
If the grant is missing, Postgres rejects the query before RLS comes into play.
(Supabase changelog)
Vendor quotes last verified: .
What the free check covers
PatchAndShip's free mini check is passive: it looks only at the public homepage, its scripts and its security headers (for exposed secret keys, missing headers and publicly listed storage links), and nothing else: no database queries, no logins, no changes. It returns a one‑page summary within 24 hours. The app owner (or an authorized person) must consent. The signed‑out test of your live app is part of paid orders only.