データベースのテーブルは、作った直後は守られていない。
今回は、この開いたドアに自分の手で鍵をかけます。
対象はSupabase(Vibe Coding実装編で使ったデータベース)ですが、考え方はFirebaseなど他のサービスでも同じです。名前が「セキュリティルール」に変わるだけで、「初期状態は開いている。閉め方を知っているかどうか」という構図は変わりません。
- RLSって、結局なにをしてくれるの?
- 有効にすると、なぜ自分のアプリまで動かなくなるの?
- 鍵がかかったことは、どうやって確かめるの?
今日はこの3つに答えます。
ㅤ
RLSは「行ごとの受付係」
RLS(Row Level Security、行レベルセキュリティ)は、データベースの行ひとつひとつに受付係を立てる仕組みです。
病院の受付を思い浮かべてください。診察券を出すと、受付係はその人のカルテだけを出してきます。「全患者のカルテを全部ください」と言っても、渡しません。
RLSが無効なテーブルは、受付係のいない棚です。来た人が自由に棚を開けられます。
RLSを有効にして「ポリシー」という規則を書くと、受付係が立ちます。
ポリシー(規則)の例
本人だけ
作った本人だけが読める
ログイン済み全員
誰でも読めるが、書き換えは本人だけ
誰でも
読める(公開データ)
注意
RLSを有効にしただけでは、まだ何も許可されていない
RLSを有効化した直後のテーブルは「全部拒否」になります。アプリが急にデータを読めなくなったら、それは壊れたのではなく、受付係が立ったのに規則をまだ渡していない状態です。ここで慌ててRLSをオフに戻すのが、いちばん危険な逆走です。戻すのではなく、規則(ポリシー)を書きます。
ㅤ
手を動かす: 鍵をかける3ステップ
自分のSupabaseプロジェクトで、次の3ステップをやってみます。SQLはAIに書かせて構いません。ただし、何を頼んでいるのかは自分で分かって頼みます。
現状を確認する
Table EditorでRLS disabled警告の有無を見る
RLSを有効化しポリシーを書く
自分の行だけ読み書きできる規則をAIと一緒に書く
鍵がかかったことをテストする
シークレットウィンドウと別アカウントで確認する
ステップ1: 現状を確認する
Supabaseのダッシュボード → Table Editorで各テーブルを見ます。RLSが無効なテーブルには「RLS disabled」という赤い警告が出ます。この警告が出ていれば、前回のCVE-2025-48757型の事故(170件超)と同じ状態です。
ステップ2: RLSを有効化し、ポリシーを書く
例として「メモアプリで、自分のメモは自分だけが読み書きできる」規則をかけます。
-- RLSを有効化(受付係を立てる)
alter table notes enable row level security;
-- 規則1: 自分の行だけ読める
create policy "read own notes"
on notes for select
using (auth.uid() = user_id);
-- 規則2: 自分の行だけ書ける
create policy "write own notes"
on notes for insert
with check (auth.uid() = user_id);
auth.uid() は「いまログインしている人のID」です。行の持ち主と、いま来ている人が同一のときだけ通す規則です。
AIに頼むときの指示文はこうなります。
「notesテーブルにRLSを有効化して、user_id列が自分のIDと一致する行だけをselect/insert/update/deleteできるポリシーを書いて。他人の行には一切アクセスできないこと」
ステップ3: 鍵がかかったことをテストする
ここがいちばん大事です。かけたつもり、で終わらせない。確実な方法は、ログインしていない状態や別アカウントで、他人のデータが実際に見えないかを確かめることです。
明日のアクション
今日中にやる3点セット
- Supabaseの全テーブルで「RLS disabled」警告が出ていないか確認する
- 警告が出たテーブルにRLSを有効化し、ポリシーをAIと一緒に書く
- シークレットウィンドウと別アカウントで「見えないこと」をテストする
ㅤ
「あとでやる」が通用しない理由
第1回で見たとおり、公開されたURLは数時間で自動スキャンに見つかります。「まず動くものを公開して、セキュリティはあとで」の「あとで」が来る前に、ドアノブを回す機械のほうが先に来ます。
公開する前に、RLS。
これは標語ではなく、Supabase公式の本番移行チェックリストの最上段に書かれている要件です。
ㅤ
セルフチェック
1. Supabaseで新しいテーブルを作った直後の状態として正しいのはどれ?
2. RLSを有効化した直後にアプリがデータを読めなくなった。正しい対応は?
ㅤ
次のレッスン
受付係は立ちました。次回は鍵そのものの話です。見られてもよい鍵(anon key)と絶対に見られてはいけない鍵(service_role key)の違い、そして環境変数という「サーバー側の金庫」の使い方を整理します。
ㅤ
参考・出典
- Supabase公式. "Row Level Security". https://supabase.com/docs/guides/database/postgres/row-level-security
- Supabase公式. "Production Checklist". https://supabase.com/docs/guides/deployment/going-into-prod
- Vibe App Scanner. "Supabase RLS Issues in Vibe Coded Apps"(CVE-2025-48757解説). https://vibeappscanner.com/issues/supabase