メインコンテンツへスキップ

データベースに鍵をかける(RLS)

テーブルは作った瞬間、全世界公開。Supabaseの行レベルセキュリティ(RLS)を有効にし、鍵がかかったことを自分でテストする。

  • レッスン 3 / 15
  • 11分

このレッスンで

終わる頃には、次ができるようになります

  • RLSが行ごとの受付係でテーブルは作成直後は無防備であることを説明できる
  • RLSを有効化しただけでは全拒否になるためポリシーを書いて許可すると判断できる
  • シークレットウィンドウと別アカウントで他人のデータが見えないことをテストできる

データベースのテーブルは、作った直後は守られていない。

今回は、この開いたドアに自分の手で鍵をかけます。

対象はSupabase(Vibe Coding実装編で使ったデータベース)ですが、考え方はFirebaseなど他のサービスでも同じです。名前が「セキュリティルール」に変わるだけで、「初期状態は開いている。閉め方を知っているかどうか」という構図は変わりません。

  • RLSって、結局なにをしてくれるの?
  • 有効にすると、なぜ自分のアプリまで動かなくなるの?
  • 鍵がかかったことは、どうやって確かめるの?

今日はこの3つに答えます。

ㅤ

RLSは「行ごとの受付係」

RLS(Row Level Security、行レベルセキュリティ)は、データベースの行ひとつひとつに受付係を立てる仕組みです。

病院の受付を思い浮かべてください。診察券を出すと、受付係はその人のカルテだけを出してきます。「全患者のカルテを全部ください」と言っても、渡しません。

RLSが無効なテーブルは、受付係のいない棚です。来た人が自由に棚を開けられます。

RLSを有効にして「ポリシー」という規則を書くと、受付係が立ちます。

ポリシー(規則)の例

1

本人だけ

作った本人だけが読める

2

ログイン済み全員

誰でも読めるが、書き換えは本人だけ

3

誰でも

読める(公開データ)

注意

RLSを有効にしただけでは、まだ何も許可されていない

RLSを有効化した直後のテーブルは「全部拒否」になります。アプリが急にデータを読めなくなったら、それは壊れたのではなく、受付係が立ったのに規則をまだ渡していない状態です。ここで慌ててRLSをオフに戻すのが、いちばん危険な逆走です。戻すのではなく、規則(ポリシー)を書きます。

ㅤ

手を動かす: 鍵をかける3ステップ

自分のSupabaseプロジェクトで、次の3ステップをやってみます。SQLはAIに書かせて構いません。ただし、何を頼んでいるのかは自分で分かって頼みます。

01

現状を確認する

Table EditorでRLS disabled警告の有無を見る

02

RLSを有効化しポリシーを書く

自分の行だけ読み書きできる規則をAIと一緒に書く

03

鍵がかかったことをテストする

シークレットウィンドウと別アカウントで確認する

鍵をかける3ステップ

ステップ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点セット

  1. Supabaseの全テーブルで「RLS disabled」警告が出ていないか確認する
  2. 警告が出たテーブルにRLSを有効化し、ポリシーをAIと一緒に書く
  3. シークレットウィンドウと別アカウントで「見えないこと」をテストする

ㅤ

「あとでやる」が通用しない理由

第1回で見たとおり、公開されたURLは数時間で自動スキャンに見つかります。「まず動くものを公開して、セキュリティはあとで」の「あとで」が来る前に、ドアノブを回す機械のほうが先に来ます。

公開する前に、RLS。

これは標語ではなく、Supabase公式の本番移行チェックリストの最上段に書かれている要件です。

ㅤ

セルフチェック

1. Supabaseで新しいテーブルを作った直後の状態として正しいのはどれ?

2. RLSを有効化した直後にアプリがデータを読めなくなった。正しい対応は?

ㅤ

次のレッスン

受付係は立ちました。次回は鍵そのものの話です。見られてもよい鍵(anon key)と絶対に見られてはいけない鍵(service_role key)の違い、そして環境変数という「サーバー側の金庫」の使い方を整理します。

ㅤ

参考・出典

このレッスンは役に立ちましたか?