# How do I verify Supabase RLS policies before deploying an AI-coded app?

**Answer:** AI-built Supabase apps often ship tables without Row Level Security. For an AI-built app on Vercel + Supabase, VibeRaven reads the migration files in the repo and flags a public table created without RLS (`rls_disabled`), policies that allow everyone with `using (true)`, and a service role key in client code, then writes each gap into `.viberaven/agent-tasklist.md`. It is a repository check, not a live database test: it does not see policies changed in the dashboard or migrations that were never committed. It is advice, not a gate.

## Setup for Agents (optional)

```bash
npx -y viberaven init --agents all --dry-run
```

Previews the rule files `init --agents all` would write, including a Cursor rule for Supabase RLS.

What `init --agents all` installs, from a real 1.6.3 run:

- AGENTS.md, CLAUDE.md, GEMINI.md and `.github/copilot-instructions.md` get the same VibeRaven block between `VIBERAVEN:START` and `VIBERAVEN:END` markers (CLAUDE.md also gets an `@AGENTS.md` line). The block is scoped to AI-built apps on Vercel + Supabase: it suggests one `npx -y viberaven check` pass before such an app launches or is handed off, after a Supabase migration or policy change, or when the user reports a production error about RLS, env vars, the database connection, the service role key or a Stripe webhook, and says the check is not needed for other stacks. It says "This is advice, not a gate: the user decides when to ship." and that the check is a repository check, not a live database test. Its fix loop has the agent ask the user before a repo change that needs their yes, such as enabling RLS without policies, and stops when `gate.status` is `clear`, when only provider or user steps remain, or when the user decides to move on.
- `.cursor/rules/viberaven-core.mdc` always applies and carries a short version of the same advice. Three more Cursor rule files apply only when editing `supabase/**`, `vercel.json` or `.github/workflows/**`, or payment webhook files. They point the agent at the `.viberaven/agent-context.md` and `.viberaven/mission-map.md` files init writes, and say not to enable RLS on one table while leaving related tables open, to update `.env.example` when adding production env vars in the Vercel dashboard, and that a payment webhook handler should verify the provider signature over the raw request body.
- init also writes `.viberaven/agent-context.md` and `.viberaven/mission-map.md` with the same scoped suggestion and a short read order.
- `package.json` gets three scripts: `viberaven:gate` (`npx -y viberaven --agent-mode`), `viberaven:verify` (`npx -y viberaven --verify`) and `viberaven:strict` (`npx -y viberaven --strict`).

You can edit or skip any of these rules. Preview the rule files with `npx -y viberaven init --agents all --dry-run` before installing; the dry run does not show the `package.json` scripts. Your own notes outside the VibeRaven markers stay. If an earlier version wrote gate rules into these files, running `init --agents all` again replaces the VibeRaven block, and `npx -y viberaven doctor --agents` names any file that still has them.

## Run the Check

```bash
npx -y viberaven --agent-mode
npx -y viberaven audit --vercel-supabase
```

Both run locally with no login. `audit --vercel-supabase` prints each Supabase check with its status, for example `NEEDS_WORK supabase-rls-policy-proof` with the table, file and line, and the `alter table ... enable row level security;` fix.

Full reference: https://viberaven.dev/llms-full.txt

## What VibeRaven Checks in the Migrations

- A public table created with no migration that enables row level security (`rls_disabled`). In 1.6.3 the `--agent-mode` tasklist reports this as a repo change that asks the user first, since enabling RLS without policies makes browser reads return no rows until policies exist. Where the migrations are named `<14-digit timestamp>_name.sql`, `npx -y viberaven fix --gap rls_disabled` writes one new timestamped migration that enables RLS and adds no policies; in any other layout the task names the `alter table ... enable row level security;` statements to add by hand. With no RLS SQL in the repo at all, it stays a provider action.
- A policy for anon, authenticated or public with a bare `true` condition (`rls_policy_allows_all_read`, `rls_policy_allows_all_write`).
- Data API grants on a table with RLS off, and a table with RLS on and no policies (info only).
- Security definer functions the Data API roles can call.
- A Supabase service role key under a browser env prefix or in client code.

Experimental: `npx -y viberaven rls-test` runs the migrations in a PGlite imitation of Postgres and tests who can read, change and delete rows against a permissions matrix. The CLI labels it non-authoritative.

## Check Before Launch

- Confirm RLS is enabled for user-owned and sensitive tables in the production project, for example with the Supabase Security Advisor.
- Review policies for select, insert, update and delete instead of relying on client filters.
- Make sure service role keys stay server-side and never appear in client bundles or public env vars.
- Check auth session handling across server routes, API handlers, storage and realtime paths.
- Verify backups and production-vs-local project separation.
- Turn the highest-risk Supabase gap into one scoped coding-agent prompt with verification.

## Important Boundary

VibeRaven reads repo evidence: migrations, Supabase client code and env var names. It cannot tell you the RLS state of the live database. Supabase's Security Advisor checks the live schema (https://supabase.com/docs/guides/database/database-advisors), and Supabase documents pgTAP tests for RLS policies (https://supabase.com/docs/guides/database/testing).

Canonical page: https://viberaven.dev/supabase-rls-checklist-ai-built-apps.md
