viberaven
VibeRaven checks AI-built apps on Vercel + Supabase for launch gaps before you ship: tables without RLS, permissive policies such as using (true), service_role keys in client code, anon-callable security definer functions, the wrong pooler port and unverified Stripe webhooks.
npx -y viberaven check
Requires Node.js 20 or newer. Run it from your app's project root. It reads the repository on your machine, needs no VibeRaven account or API key, and names the file and line for each gap. On Windows PowerShell, use npx.cmd if npx is blocked by the execution policy.
This package launches @viberaven/cli at the same version and forwards arguments and exit status.
What it checks
| A public table created in a migration with row level security never enabled | rls_disabled | rls_disabled_in_public (guide) |
A policy with using (true) that lets anyone read or write every row | rls_policy_allows_all_write, rls_policy_allows_all_read | none |
The service_role key in a file that ships to the browser, or under a NEXT_PUBLIC_ name | service_role_key_in_client_code, service_role_key_in_client_env | none |
A security definer function in public that no migration closes to anon | security_definer_function_executable | anon_security_definer_function_executable (guide) |
| A direct Postgres connection on port 5432 from serverless code, instead of the transaction pooler on 6543 | pooler_port_mismatch | none |
| A Stripe webhook handler that never checks the signature over the raw body | unverified_stripe_webhook | none |
Env vars missing from .env.example, queries with no row limit, no error monitoring | env_var_drift, unbounded_query, missing_monitoring | none |
VibeRaven has no rule yet for security_definer_view or function_search_path_mutable. These guides explain the fix: security_definer_view, function_search_path_mutable.
Example output
From viberaven check 1.6.12 on a synthetic Next.js + Supabase app (project path shortened, last four findings cut):
viberaven check · ~/my-app
🔴 No RLS policy proof in migrations (rls_disabled)
1 public table without row level security: public.profiles (supabase/migrations/20260301000000_init.sql:1). The Data API does not enforce row restrictions for roles and operations allowed by the table's grants. Verify those grants to determine who can read or change rows.
🔴 A policy lets anyone write every row (rls_policy_allows_all_write)
Policy "orders are editable" on public.orders (supabase/migrations/20260301000000_init.sql:13) lets anyone, signed in or not, update every row, to any values: using (true).
🔴 Service role key used in client code (service_role_key_in_client_code)
app/admin/page.tsx:4: creates a Supabase client with the service role key. This file ships to the browser, and the service role key skips RLS entirely. Move the call behind a server route or edge function and rotate the key.
🟡 Supabase connection is not using the pooler port (pooler_port_mismatch)
Found direct 5432 DATABASE_URL/POSTGRES_URL evidence. Vercel/serverless deployments should prefer Supabase transaction pooler port 6543.
🟡 Security definer function callable by the Data API roles (security_definer_function_executable)
public.grant_credits(uuid, integer) at supabase/migrations/20260301000000_init.sql:15 is security definer, so it runs with its owner's rights and RLS does not limit what it touches. No migration revokes EXECUTE from public, anon, authenticated, so anyone holding the anon key can call it at /rest/v1/rpc/grant_credits. ...
Verdict: ❌ 3 blockers, 5 warnings · score 5
Fix: viberaven fix · Details: ~/my-app\.viberaven\agent-tasklist.md
check writes .viberaven/agent-tasklist.md, gate-result.json and context-map.json without changing your source, so a coding agent can work through the list. check --json prints a summary.
When to use it, and when not to
Use it before you launch or hand off a Vercel + Supabase app built with Lovable, Bolt, Cursor, Claude Code or Codex, after a Supabase migration or policy change, or when a production error points at RLS, the service_role key, env vars, the database connection or a Stripe webhook.
It is a repository check, not a live database test. It reads migrations and code, so it cannot see a policy added in the Supabase dashboard; use Supabase Security Advisor for the live project. A clear result is not a full security audit: it sends no requests to your app and does not look up dependency CVEs (use OWASP ZAP, Semgrep, Snyk or CodeQL for that). It does not prove the app works (use Playwright or your own tests).
Exit codes
check returns 0 with no blockers (warnings allowed), 1 with blockers, 2 on a scan error. --strict=warning --json also fails on warnings, and returns 3 for unknown or unavailable results. Unrestricted SELECT can be intentional public content, so it is a warning.
More
npx -y viberaven with no command opens the local Studio, where your own coding agent (Claude Code, Codex or Gemini CLI) makes a change and you see the steps, your checks, the running app and the diff.
- MCP hosts use
@viberaven/mcp.
- In 512 public Lovable projects with a supabase/migrations folder, 47.3% (242) define at least one security definer function in the public schema that a signed-out caller with the anon key can run: the data.
- GitHub · Supabase Security Advisor guides · agent reference
License: MIT.