Lovable × Supabase の公開前チェック:RLS は「設定済み」より「他人の行が見えないか」
少人数チーム向けに、ログイン、Supabase RLS、サービス側の権限と Lovable の公開前スキャンを分けて確認する判断基準を整理する。

表紙:編集部がGPT Imageで生成した概念イラスト。実際の事件写真や製品画面ではありません。
Lovable と Supabase で作ったアプリを公開するとき、RLS の項目が存在し、公開時のスキャンが終わっただけでは合格にしない。先に「ログイン前の人」「データの本人」「別のログイン済み利用者」「権限の強いサービス処理」の期待結果を決め、自社の許可された環境でそれぞれ確認する。ある調査が不適切なデータ公開の事例を報告しているが、調査対象は Lovable 全体を代表せず、当編集部も対象アプリを再調査していない。
11月14日に注目された調査は、11月2日には報じられていた
Crissy Field の調査報告は、関連する新聞記事が 2026年11月2日に出たと記し、掲載する数値は記事より新しいと説明する。調査ページそのものの公開日・更新日は明記されていない。11月3日の二次報道も先行記事の日付を示す。一方、Hacker News の記録で調査ページへの投稿が確認できるのは11月14日だ。「11月14日に初めて発覚」と書くより、既存の調査がコミュニティで再注目された、と捉えるほうが正確だ。
調査者は、2025年12月から2026年9月までの Common Crawl の記録から 159,041件の Lovable プロジェクトを特定した。そのうち 34,545件が Supabase を利用し、24,664サイトでログイン前に何らかのデータベースのレコードが返されたという。しかし公開予定の商品一覧と非公開の会話は同列にはできない。この数をそのまま「24,664件の個人情報漏えい」と読み替えてはいけない。
調査者は追加の読み取り専用リクエストによって、上記の24,664サイトのうち 7,403サイト、計10,560テーブルからメールアドレスを含むレコードを実際に取得したと報告する。約30%という比率の分母は24,664であり、全159,041件でも Lovable 全アプリでもない。報告自身が標本は全体を代表せず、30%は確定した漏えい率ではないと注意している。一つのフォーラムに20万件超の私的メッセージ、ある事業者に身分証情報を含む1,000件超のレコードという記述も、それぞれ単一事例についての調査者の主張だ。全サイトの件数やパスポートの冊数に置き換えない。
小さなチームに必要なのは業界全体の割合の推測ではなく、自分たちの公開判断だ。調査対象のアプリが現在どこまで修正されたかも、公開資料だけでは確定できない。だからこそ手元の製品で、期待するアクセス権を先に言葉にしておく。
ログインした人と、その行を読める人は同じではない
例として、架空の予約アプリを考える。利用者AとBはどちらもログインできる。Aの予約情報をBに見せてはいけないが、公開された店舗案内は誰でも読める。ログイン画面だけ確認すると「AもBも認証済み」で検査が終わる。ところが必要な判定は、Aの予約を読む操作の主体がA本人か、共有相手として明示的に許可されているか、という行単位の問いだ。
Supabase の RLS 公式文書では、authenticated はログイン済みという役割を示すにすぎない。どの操作を許すかに加え、「どの行」まで操作できるかをポリシーで決める。Lovable のデータベースアクセス文書も、要求した人と行の所有者を結び付けることを重視する。認証、操作権限、行ごとの所有関係は、連続した確認項目だが同じ項目ではない。
画面上で予約が非表示でも、ブラウザーに私的なデータが渡っていれば設計上の失敗は残る。逆に、公開すべき店舗案内まで全て拒否すると、守れているのではなく機能が壊れている。拒否される結果だけでなく、許可される結果も試す理由はそこにある。実際の第三者アプリを調べる必要はない。以下の手順は自社、または明確に許可を得た環境で架空データを使うためのものだ。
少人数なら、一枚の権限表を公開前の合否基準にする
専任のセキュリティ担当者を置けないチームほど、関係者が同じ表を見て判断できるようにしたい。まずデータを「誰でも見られる案内」「本人だけの予約」「明示された相手と共有する予約」に分類する。次に閲覧と変更を分け、未ログイン、本人、別利用者、サービス側処理の各立場で、許可と拒否を書く。曖昧な「チームに見せる」ではなく、どの関係の人に何を見せるかを決める。
| 要求者(AとBに共有権限はない) | Aの予約を読む | Aの予約を変更する | Bの予約を読む |
|---|---|---|---|
| 未ログイン | 拒否 | 拒否 | 拒否 |
| 利用者A | 許可 | 業務ルールの範囲で許可 | 拒否 |
| 利用者B | 拒否 | 拒否 | 許可 |
| 権限の強いサービス処理 | 別途権限・目的を確認 | 別途権限を確認し記録 | 別途権限・目的を確認 |
これは説明用の架空製品の表であり、両サービスの初期設定を表すものではない。共有機能が必要なら、誰にどの予約を共有するかを具体化し、共有解除後の結果まで決める。予約以外の新しい私的データを追加したときも、この表を更新しないまま公開しない。判断に迷うセルがあれば、その曖昧さ自体が公開前に解くべき仕様上の問題になる。
自社ステージングで二つのテスト用アカウントに区別できる架空の予約を用意し、本人は自分の記録を読めること、もう一人は読めないこと、未ログインでは保護対象を読めないことを確認する。変更操作も同じ考え方で見る。単に「空の結果が返った」だけでは成功と言えない。元々そのアカウントに記録がない場合、正しい拒否と機能不全が同じ空結果に見えるからだ。期待する正例と拒否する反例を組にして判定する。
Lovable の文書によれば、ポリシー画面は閲覧用で、変更には別の作業が必要だ。また service_role の要求には RLS が適用されない。管理操作やバックグラウンド処理を持つなら、ブラウザーからの通常の経路とは別に、サービス側が何の目的で誰の記録を扱うかを確認しなければならない。これを「RLSを有効にしたから完了」と片付けると、最も強い権限の経路が検査から抜ける。
サービス処理にも具体的な合否を置く。架空の予約通知ジョブなら、当日の通知対象について必要な項目だけを読み、送信結果を記録する動作を許可する。一方、一般利用者が同じ経路を使って任意の人の予約を一括取得する操作は、サービス側の認可で拒否する必要がある。バックエンド担当者が両方の結果を記録し、公開担当者が確認する、という分担まで決める。これは業務ルールの例であり、強い権限の要求をRLSだけで止められるという意味ではない。
Lovable の自動スキャンを、公開許可と取り違えない
Lovable の Security view 文書には、Quick scan は毎回の公開時に自動で走る、とある。同社の11月10日付の公式説明は、重大な所見が残る場合に公開を止められる制御も紹介する。検出の入口があるのは有益だが、「検出した」「判断した」「公開を止めた」は別の動作だ。
確認した文書からは、公開停止機能が初期状態で有効か無効かは判断できない。機能が存在するという説明も、あなたのワークスペースで現在作動している証拠にはならない。自分たちの設定と実際の公開フローを、権限のある担当者が確認しよう。重大な所見の扱いが不明なまま個人データを本番に出すのではなく、まずチームの公開保留基準に従う。

調査で指摘された問題と製品側のスキャンを同時に考えると、役割分担がはっきりする。スキャンは疑わしい権限を見つける手段。権限表は「このデータが誰に見えてよいか」という業務の基準。公開停止設定は未解決の問題を本番へ持ち込まない手続き上の歯止めだ。緑色の結果が出ても想定した本人・他人の動作を確認し、修正を自動適用したら許可側も拒否側も再確認する。ツールは公開承認の責任者にはならない。
公開見送りと再確認を、次の変更にも残す
私的データの受け手が決まっていない、二つのアカウント間の分離が確認できない、サービス側の高権限経路に担当者がいない。この三つのいずれかが残るなら、公開を見送りたい。重大な所見が出た場合も「誰が対応し、何を直し、どの許可・拒否ケースを再確認したか」を残す。実際の利用者データをチケットに貼らず、データの種類と期待結果、架空データによる確認結果で共有できる。
修正後はスキャンを再実行するだけでなく、本人に必要な機能が動くか、別利用者には拒否されるかを確かめる。共有機能やサービス処理を追加したら、以前の合格をそのまま流用しない。調査で挙がったサイトが全て修正済みかどうかは分からない。しかし自分たちのアプリについては、次の公開でも同じ合否基準を使うかどうかを今日決められる。