ログオフ
開発2026-06-04

Supabase の RLS 無効化は本当に危険か?anon key の露出リスクと現実的な対処フロー

「Your project has security issues」というRLS警告メール。anon key公開 × RLS無効で何が起きるか、構成別の対処。

Supabaseから「Row Level Security (RLS) が無効なテーブルがあります」という警告メールが届く。これが実際に危険なのか、構成別に整理する。

事象

  • Supabaseから件名「Your project has security issues」のメールが届く
  • 内容は「RLSが無効になっているテーブルがある」という警告
  • 即座にデータが漏れているわけではないが、放置してデプロイすると問題になる

原因

危険になるのは anon key の公開RLS無効 が重なったときだ。

RLS(Row Level Security)はPostgreSQLの行単位アクセス制御。無効にすると、テーブルへのアクセス制御はAPIキーのレベルだけに依存する。

一方、フロントから直接Supabaseを叩く構成では NEXT_PUBLIC_SUPABASE_ANON_KEY に anon key を置く。NEXT_PUBLIC_ 付きの環境変数はブラウザに露出するので、サイトを開いた人なら誰でも anon key を取得できる

anon key 自体は公開前提で設計されているので、それだけなら問題ない。問題は組み合わせだ。

  • anon key が公開されている(誰でも取得できる)
  • RLS が無効(行レベルの制御がない)

この2つが重なると、anon key を入手した人が service_role キーなしでテーブルを自由に読み書きできる。

# anon keyだけあれば誰でもこれが動く
curl 'https://xxxxxxxxx.supabase.co/rest/v1/users?select=*' \
  -H "apikey: eyJxxxxxx" \
  -H "Authorization: Bearer eyJxxxxxx"

解決策

構成によって対処が変わる。

パターンA:フロントから直接Supabaseにアクセスしている

RLSを有効化し、ポリシーを設定する。

-- 認証済みユーザーは自分のデータだけ読める
CREATE POLICY "Users can read own data"
ON public.users
FOR SELECT
USING (auth.uid() = id);

⚠️ ポリシーを設定せずRLSだけ有効にすると全アクセスが拒否されるので注意。

パターンB:サーバーサイドのみでアクセスしている

Server ComponentsやRoute Handlerからのみアクセスし、フロントにキーを置かない。NEXT_PUBLIC_ を使わず service_role キーで操作する。

// server-side only
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  process.env.SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY! // NEXT_PUBLIC_ なし
)

anon key がブラウザに露出しないので、RLS無効でも実害は小さい。

パターンC:開発専用で外部公開しない

ローカル検証専用なら警告は無視して進めてよい。ただし本番公開前に必ずRLS設計を見直す。

補足:問題になるケースの見分け

危険問題なし
本番でユーザーデータ等を保持開発・実験用で非公開
書き込み想定外のデータに誰でも書ける内容が本来パブリックなデータのみ
公開されると困る内容を持つサーバーサイドのみでanon keyを露出していない

要点:anon keyの公開そのものは設計通り。直すべきはRLS無効の方。フロント直アクセスならRLSは必須、サーバー経由なら service_role で完結させる方が設計として明快。

関連記事

開発 一覧へ