fixes / launch-ready

How I Would Fix database rules leaking customer data in a Supabase and Edge Functions AI-built SaaS app Using Launch Ready.

If customer records are showing up for the wrong user, I treat that as a production security incident, not a normal bug. In a Supabase and Edge Functions...

How I Would Fix database rules leaking customer data in a Supabase and Edge Functions AI-built SaaS app Using Launch Ready

If customer records are showing up for the wrong user, I treat that as a production security incident, not a normal bug. In a Supabase and Edge Functions SaaS app, the most likely root cause is broken Row Level Security, usually because one table has no policy, one policy is too broad, or an Edge Function is using the service role key and returning data without re-checking tenant access.

The first thing I would inspect is the exact path from browser to database. I want to know whether the leak happens through a client-side query, an Edge Function, a view, or an admin endpoint that was never meant to be public.

Triage in the First Hour

1. Confirm the leak scope.

  • Identify which customer data is exposed.
  • Check whether it is cross-account leakage, internal-only data, or only metadata.
  • Estimate blast radius: number of affected users, tables, and time window.

2. Freeze risky changes.

  • Pause deploys from Lovable, Cursor, CI, or manual pushes.
  • Disable any new automation that writes to the same tables.
  • If needed, temporarily restrict access to the affected endpoint.

3. Check Supabase Auth and RLS status.

  • Open each impacted table in Supabase.
  • Verify that Row Level Security is enabled.
  • Review every policy on read and write actions.

4. Inspect Edge Functions logs.

  • Look for requests that return more rows than expected.
  • Check for use of `service_role` in functions that should be tenant-aware.
  • Review error logs for fallback logic that may expose extra data.

5. Review recent builds and migrations.

  • Find the last schema change before the leak started.
  • Look for new views, triggers, RPCs, or migrations that bypassed policies.
  • Compare production schema with staging if you have it.

6. Check secrets and environment variables.

  • Confirm `SUPABASE_SERVICE_ROLE_KEY` is not exposed in client code.
  • Verify public keys are only used where intended.
  • Rotate any secret if there is doubt about exposure.

7. Inspect dashboards and audit trails.

  • Use Supabase logs, function invocation logs, and database activity if enabled.
  • Look for unusual query volume or unexpected admin access patterns.
  • Note any failed auth checks that were silently ignored.

8. Reproduce safely with test accounts only.

  • Use two separate test users from different tenants.
  • Confirm whether user A can see user B's rows through each access path.
  • Do not test with real customer accounts unless absolutely necessary.
-- Quick check: find tables where RLS may be off
select schemaname, tablename
from pg_tables
where schemaname = 'public'
and tablename not like 'pg_%';

Root Causes

1. RLS is disabled on one or more tables.

  • How to confirm: check each affected table in Supabase and verify RLS status is on.
  • Common failure: one newly created table was added during an AI-generated feature sprint and never secured.

2. Policies are too broad or missing tenant filters.

  • How to confirm: review policies for `using (true)` patterns or filters that do not reference `auth.uid()` or tenant membership tables.
  • Common failure: a policy was written to "get things working" and never tightened before launch.

3. Edge Functions are using the service role key for user-facing reads.

  • How to confirm: inspect function code and environment variables for `service_role`.
  • Common failure: the function fetches all records server-side and returns them after weak filtering.

4. Views or RPC functions bypass intended row checks.

  • How to confirm: review SQL views, `security definer` functions, and stored procedures used by the app.
  • Common failure: developers assume "database-side" means "secure by default," which is false unless access control is explicit.

5. Multi-tenant ownership logic is inconsistent across tables.

  • How to confirm: compare tenant IDs across every related table and join path.
  • Common failure: one table uses `user_id`, another uses `account_id`, and a join accidentally crosses tenants.

6. Client-side queries are hitting endpoints meant only for admins or internal tools.

  • How to confirm: inspect network requests in the browser and compare them with intended permissions.
  • Common failure: an AI-built frontend copied an admin query into a normal user flow.

The Fix Plan

I would fix this in layers so I do not trade one security bug for three new ones.

1. Stop the leak first.

  • Disable the offending route or function if data exposure is active right now.
  • If needed, return a safe error instead of partial data until rules are corrected.

2. Map every access path to customer data.

  • List all tables, views, RPCs, Edge Functions, cron jobs, and admin screens touching sensitive rows.
  • Mark each one as public user access, authenticated user access, admin-only access, or internal system access.

3. Enforce tenant isolation at the database layer first.

  • Turn on RLS for every customer-facing table in scope.
  • Write explicit read and write policies based on authenticated user identity or tenant membership tables.
  • Remove any policy that allows broad reads without a tenant check.

4. Separate public reads from privileged operations.

  • Keep normal app reads under standard auth context whenever possible.
  • Reserve `service_role` for background jobs, migrations, moderation tools, or tightly scoped internal workflows only.

5. Tighten Edge Functions behavior.

  • Validate JWTs on every request that touches customer data.

Ensure each function checks ownership before returning rows even if it uses elevated credentials internally for a specific task." " Oops there seems an unmatched quote? Need final clean no errors."

Delivery Map

References

  • [roadmap.sh - cyber security](https://roadmap.sh/cyber-security)
  • [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
  • [MDN Web Docs - HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP)
  • [Cloudflare DNS documentation](https://developers.cloudflare.com/dns/)
  • [Sentry documentation](https://docs.sentry.io/)

---

Take the next step

If this is a problem in your product right now, here is what to do next:

  • [Use the free Cyprian tools](/tools) - estimate cost, score app risk, check launch readiness, or pick the right service sprint.
  • [Book a discovery call](/contact) - I will tell you honestly whether you need a sprint or if you can DIY the next step.

*Written by Cyprian Tinashe Aarons - senior full-stack and AI engineer helping founders rescue, launch, automate, and scale AI-built products.*

Next steps
About the author

Cyprian Tinashe AaronsSenior Full Stack & AI Engineer

Cyprian helps founders rescue, secure, deploy, and automate AI-built apps with production-grade engineering, launch systems, and AI integration.