원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.
Supabase Security Skill
A pure-Node.js audit + remediation toolkit for Supabase projects. No dependencies, runs locally, your token never leaves your machine.
What it checks
- Tables with RLS disabled + grants to anon/authenticated → critical leak
- Tables with RLS enabled but zero policies AND direct anon grants → defense-in-depth issue
- SECURITY DEFINER functions executable by anon → privilege escalation surface
- Default privileges still grant CRUD on future tables → Supabase enforces revoke by Oct 30, 2026
- Public storage buckets → asset leakage
- Auth signups with autoconfirm enabled → signup abuse risk
Each finding includes the exact SQL needed to fix it. The skill never applies fixes automatically — it generates, you review, you run.
How to use
Quick audit (JSON to stdout)
SUPABASE_ACCESS_TOKEN=sbp_xxx \
node scripts/audit.js <project-ref>HTML report (recommended for sharing)
SUPABASE_ACCESS_TOKEN=sbp_xxx \
node scripts/audit.js <project-ref> --html report.htmlOpen report.html in any browser. Self-contained (~25KB), Tailwind + Chart.js via CDN, copy-to-clipboard buttons on every fix.
Get a token
https://supabase.com/dashboard/account/tokens → New token. Read-only is enough for the audit; remediation needs no extra scope (you run the SQL yourself).
Remediation flow
- Run the audit, get the HTML report.
- Review each finding. Don't blindly apply fixes. Some "high" findings (e.g.
is_admin()exposed to anon) are intentional API endpoints. - Click "Copy all SQL" at the bottom and paste into Dashboard → SQL Editor.
- Run inside a transaction:
BEGIN; ... ROLLBACK;first to verify, thenBEGIN; ... COMMIT;.
Scope and limits
- Read-only by default. No fix is ever applied without you running the SQL.
- Cannot revoke `supabase_admin` default privileges via the Management API (Postgres permission limit). The audit reports this and points to the Dashboard toggle (
Project Settings → Data API → "Automatically expose new tables" = OFF). - No false-positive suppression for app APIs. A
get_dashboard_stats()function intentionally exposed to anon will still appear as a high finding — exposed code paths are the surface area; you decide if intentional. - Storage scan covers buckets only. Per-object RLS is not audited (would require iterating every object).
Why another Supabase scanner?
Most existing tools (SupaExplorer, AuditYourApp, Vibe App Scanner) are SaaS — your project ref + URL go to a third party. This skill runs locally with your own PAT. The only network calls are to api.supabase.com. Audit it: see scripts/audit.js, ~250 lines of plain Node.
License
MIT — see LICENSE.
