🐷

supabaseに「new row violates row-level security policy for table」と怒られた件

に公開

ReactアプリからSupabaseのテーブルにデータをINSERTしてみようとしたら、以下のエラーが出てできなかった。
supabase-rsl-01.png

new row violates row-level security policy for table "study_record"

追加しようとしているデータがRow-Level Security (RLS)に違反しているということらしい。
https://supabase.com/docs/guides/database/postgres/row-level-security

RLS(Row Level Security)ってなんぞや

詳しくは以下を参照
https://supabase.com/docs/guides/database/postgres/row-level-security

元々はPostgreSQLの機能らしく、名前の通りテーブル内のデータを行単位でアクセス制御をかけられる機能らしい。
Supabase Authと組み合わせて、行データに対するSQL実行ルールを設定できる。
サイバー攻撃からユーザーデータを守る「多重防御(defence in depth)」を実現している。

PostgreSQLでの実装については以下の記事が参考になりそう(ざっとしか読んでない)
https://zenn.dev/taxin/articles/postgresql-row-level-security-policy

RLS ポリシーを設定してみる

このRLSにはポリシーというものがあるらし、作成したポリシーをテーブルにアタッチすることで、テーブルにアクセスする度にポリシールールが適用される。

というわけでINSERTに対するポリシールールを作成してみる。

create policy "public can insert study_record"
on public.study_record for insert
to anon
with check(true);

これで外部からもアクセスできるようになった。

正式に本番リリースさせるならto anonとかwith check(true)の部分はもっと厳密に設定する必要があるのだが、今回はお試し作成なのでガバガバ設定で。
https://supabase.com/docs/guides/database/postgres/row-level-security#insert-policies

(補足)テーブル単位でRLS有効化しておく必要があるので注意!

ダッシュボード上のTable Editorで作成する場合はRLSがデフォルトで有効化される。
SLQ Editorや外部からSQL実行で作成する場合は、ユーザーが明示的にRLSを有効化する必要がある。

alter table <schema_name>.<table_name>
enable row level security;

とりあえずSQLでテーブル作成した場合は以下の感じのセットアップをすれば良いので参考にはっておく。

--Enable RLS
alter table study_record enable row level security;

-- Adding an RLS policy
create policy "public can read study_record"
on public.study_record
for SELECT to anon
using (true);

-- Adding an RLS policy for INSERT
create policy "public can insert study_record"
on public.study_record for insert
to anon
with check(true);

Discussion