supabase の API 認証を理解する
これはなに?
supabase を使う際に避けては通れない、API キーと認証周りのはなし。
いままで anon
キー(最も弱い権限の鍵)のみを使用して、アクセスできない部分はセキュリティ解除して~といった運用をしていたため、セキュリティを固めるためにも学びなおす。
参照
API URL
すべての supabase プロジェクトには、固有の URL が発行される。これは supabase の各機能へアクセスするために使われる。(参照)
https://<project_ref>.supabase.co
API Key
すべての supabase プロジェクトには、anon
キーと service_role
キーが発行される。
これら二つの違いは、後述する RLS (Row Level Security、行レベルセキュリティ) と対応しており、内部的には Postgres のユーザーに対応しているらしい。(参照)
また、これも後述する ポリシー によって、各キーのアクセス範囲を設定できる。
anon
デフォルトで、ほとんど権限を持たないキー。(おそらく "anonymous" の略)
クライアント側からの限定的なアクセスを行うために用意されている。
service_role
サービス内のさまざまなタスクを実行するためのキー。
こちらは RLS を迂回できるため、取り扱いには十分に注意する 必要がある。
GitHubに誤って`service_role`キーを公開してしまった場合
公式が GitHub と連携し、自動的に無効化してくれるらしいです。ありがとう。(参照)
URL と API キーさえあれば、 HTTP リクエストを介して API にアクセスできるようになっている。
ただし、ほとんどのプロジェクトでは、公式が提供するクライアントライブラリを使用することが多い。
セキュリティ保護
ここからは、supabase(厳密には Postgres )のセキュリティ機能について見ていく。
RLS (Row Level Security, 行レベルセキュリティ)
文字通り テーブルの一行レベルでアクセス制限を行う 機能のこと。うまく利用すれば、データベースレベルでリソースのアクセス管理ができ、サービス内でのセキュリティが高まる。
この機能は、テーブルを作成した時点で自動的に有効になる。(参照)
逆に言えば、この機能をオフにすることによって、 anon
キーからのアクセスであってもすべてのリソースにアクセスすることができる。が、これはセキュリティ的にとてもまずいので(プロダクトでは絶対に)おすすめしない。
ポリシー
RLS を有効にしているとき、テーブルに対して ポリシー を適用できる。
これは各ユーザーに対するアクセス制限を表すルールで、開発者は必要なポリシーを必要なだけ設定することで、不必要なアクセス許可を防ぐ(=予期しないリソースの流出を防ぐ)ことができる。
公式ドキュメントでは、以下のような例が挙げられている。
todo アプリの中で、ユーザーは他人の todo にアクセスする必要はない(できたら問題である)。そのため、ユーザーが todo を取得するときは、自身の uid
に合致する行しかアクセスできないようにする。
-- ユーザーが自分の todo にだけアクセスできるようにする
create policy "Individuals can view their own todos."
on todos for select
using ( (select auth.uid()) = user_id );
これは、言い換えると 「SELECT句を使用したとき、自動的にWHERE句を追加する」 ということ。
select *
from todos
where auth.uid() = todos.user_id;
-- ↑ポリシーによって追加された行
このように、ユーザーによってアクセスできるリソースの範囲を制限することができる。