Communityコーディング&開発github.com

atokim4/supabase-rls-audit

リポジトリ内のマイグレーションファイルからSupabaseのRow Level Security(RLS)を監査します。

supabase-rls-audit とは?

このスキルは、プロジェクト内のSupabaseマイグレーションまたは`schema.sql`ファイルを解析し、RLS関連の9つの問題を検出します。データベース接続は不要で、Node 20+で動作するスクリプト`scripts/preflight.mjs`を実行します。パブリックテーブルでRLSが無効になっている、パーミッシブなポリシー(`using (true)` / `with check (true)`)、RLSが有効だがポリシーがないテーブル、ユーザーが自身の`plan`/`role`/`credits`列を変更できる更新ポリシー、RLSをバイパスするビュー、`auth.users`を参照するビュー、固定の`search_path`がないSECURITY DEFINER関数、anonロールから呼び出し可能なSECURITY DEFINER関数、パブリックなストレージバケットをチェックします。Claude Code、Cursor、CodexなどのAIエージェントと連携して、アプリリリース前やマイグレーション作成後、あるいはLovable / Bolt / Cursorで生成されたSupabaseプロジェクトのレビュー時に使用します。結果はJSONまたはテキスト形式で出力され、各問題の修正方法も案内されます。

対応✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/atokim4/vibe-preflight/tree/HEAD/skills/supabase-rls-audit

Installed? Explore more コーディング&開発 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Supabase RLS監査

このスキルは、vibe-preflightスキャナーのデータベース部分を実行します(scripts/preflight.mjs、Node 20+、依存関係なし、ネットワーク不要)。プロジェクト内の .sql ファイル(Supabaseマイグレーション、schema.sql)を読み取り、テーブル、ポリシー、ビュー、関数、権限、ストレージバケットを順序どおりに再現し、9つの問題を報告します。データベースには接続しません。

実行方法

プロジェクトルートから:

node ${CLAUDE_SKILL_DIR}/scripts/preflight.mjs . --only database --format json

Claude Code は ${CLAUDE_SKILL_DIR} を自動補完します。他のエージェント:このスキルのフォルダ(例:.agents/skills/supabase-rls-audit または .claude/skills/supabase-rls-audit)を指定してください。

終了コード 1 は少なくとも1つのエラーがあることを意味します。--fail-on warning を追加すると警告でも失敗します。--explain(テキスト出力)で修正理由と方法を表示します。JSON出力:{ summary: { error, warning }, findings: [{ rule, severity, message, file, line }] }

結果が 0 SQL files の場合、ポリシーがダッシュボードにしか存在しない可能性があります。supabase db pull(リモートスキーマをマイグレーションファイルに書き出す)を実行してから再スキャンするようユーザーに依頼してください。空のスキャン結果をプロジェクトがクリーンだと報告しないでください。

チェック一覧

ルールレベル意味
rls-disablederrorpublic テーブルで enable row level security が実行されていないため、anonキーを持つ誰でもAPIを通じて読み書き可能。
rls-permissive-policy書き込みはerror、読み取りはwarningusing (true) または with check (true)。挿入/更新/削除で任意のユーザーが他のユーザーの行を変更可能。選択ですべての行が公開される。
rls-no-policywarningRLSは有効だがポリシーなし。APIはすべての操作を拒否。サーバー専用テーブルなら問題なし。ブラウザで読み取ると空のリストが返る。
rls-update-privileged-columnwarningユーザーが自身の行を更新でき、その行に plan、role、is_admin、credits などがある。RLSは行を制限するが、列は制限しない。
view-bypasses-rlserrorsecurity_invoker = true がないビューは所有者として実行され、その基になるテーブルのRLSをバイパスする。
auth-users-exposederrorpublic スキーマ内のビューが auth.users から選択している。
definer-search-pathwarningset search_path なしの security definer 関数。
definer-function-anonerror / warningpublic スキーマ内の security definer 関数で、anonが /rest/v1/rpc/<name> から呼び出せるもの。anonへの明示的な権限付与がある場合はerror、Supabaseのデフォルト権限の場合はwarning。
storage-public-bucketerror / warningパブリックバケット。storage.objects の選択ポリシーが誰でもリスト表示を許可している場合error。

修正方法

必ず新しいマイグレーションファイルを作成してください。データベース上で既に実行されたマイグレーションを編集しないでください。

ポリシーがない、またはパーミッシブな場合:アプリに必要なアクセス権限を確認し、各ポリシーをロールと所有者にスコープします。

alter table public.notes enable row level security;
create policy "notes: read own" on public.notes
  for select to authenticated using ((select auth.uid()) = user_id);
create policy "notes: insert own" on public.notes
  for insert to authenticated with check ((select auth.uid()) = user_id);

特権列:ユーザーが変更してもよい列のみ更新を許可します。

revoke update on public.profiles from authenticated;
grant update (display_name, avatar_url) on public.profiles to authenticated;

ビュー:alter view public.<name> set (security_invoker = true);(Postgres 15以上、現在のすべてのSupabaseプロジェクトで使用可能)。マテリアライズドビューはRLSを使用できません:public から移動するか、anon, authenticated からのselect権限を取り消してください。auth.users については、サインアップトリガーで共有可能なフィールドを public.profiles にコピーします。

SECURITY DEFINER関数:set search_path = '' を追加し、すべての名前をスキーマ付きで記述します。その後、呼び出し可能なロックをかける:

revoke execute on function public.admin_set_plan(uuid, text) from public, anon, authenticated;
grant execute on function public.admin_set_plan(uuid, text) to service_role;

Supabaseでは、public からの取り消しだけでは不十分です。anonは新しい関数に対して独自の権限を持っているためです。

ストレージ:プライベートバケットはプライベートにし、読み取りを所有者のフォルダ((storage.foldername(name))[1] = (select auth.uid())::text)にスコープし、署名付きURLを提供します。製品画像やロゴはパブリックのままで構いません。

意図的なもの(公開カタログ、サーバー専用テーブルなど)は、該当行またはその上の行に -- vibe-preflight-ignore <rule-id> を付けることで警告を抑制できます。同じコメントに理由を記載してください。

報告手順

  1. 検出された各行をSQLと照合して確認してから変更してください。スキャナーはSQLテキストを読み取るため、誤検出の可能性があります。誤りの場合はその旨を伝えてください。
  2. ルールごとに結果をグループ化します。エラーを最初に表示し、次にユーザーと確認した警告を表示します。
  3. 修正後にスキャンを再度実行し、新しい結果を報告します。

制限事項

  • .sql ファイル内のものだけが対象です。ダッシュボードのみの変更、他のスキーマ、関数本体の内部処理はチェックされません。
  • クリーンな結果は、これら9つのパターンが見つからなかったことを意味します。ポリシーがアプリのルールと一致していることを証明するものではありません。実際のanonユーザーおよび認証ユーザーとしてのテスト(anonキーを使用したSupabaseクライアント)は依然として推奨されます。
  • ブラウザ側や環境変数(クライアントコード内のservice_roleキー、NEXT_PUBLIC_ 変数内のシークレット、コミットされた .env)については、--only なしでフルスキャンを実行するか、vibe-preflight スキルを使用してください。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル