インフラ・クラウド

Supabase Authとは:非対称JWT鍵とRLS連携で組む認証実装の設計判断

AIの活用によるセキュリティの向上

Supabase Auth は、Supabase のプロジェクトに最初から入っている認証サーバーです。ユーザーは Postgres の auth スキーマに置かれ、サインインが成功すると JWT が返り、その JWT をそのまま行レベルセキュリティの判定材料に使えます。認証と認可が同じデータベースの上で地続きになっている点が、他の認証サービスとの構造差です。この記事では、JWT 発行の実処理、ES256 の非対称署名鍵への移行と getClaims() によるローカル検証、auth.uid() 前提の権限設計、セッションの既定値、MAU 課金とレート制限、外部 IdP へ寄せるべき場面を、2026年9月時点の公式ドキュメントに沿って並べます。

まとめ:Supabase Authで着手前に決める4つの設定

後戻りが大きいのは機能の選択ではなく初期設定の4点です。1点目は署名鍵で、新規プロジェクトなら最初から ES256 の非対称鍵で始めます。レガシーの共有秘密(HS256)のままだと、鍵の入れ替えのたびにユーザーが強制サインアウトされる構造から抜け出せません。2点目はメール送信。組み込みの送信枠は2通/時しかないため、公開前にカスタム SMTP を挿します。

3点目はセッションの期限です。time-box と非アクティブ切断は Pro プラン以上の機能なので、無料プランのまま設計を固めると作り直しになります。4点目が RLS で、テーブルを作った直後にポリシーを書き、有効化漏れの検知まで用意してください。逆に差し替えやすいのは認証方式そのもの。auth.users のレコードは方式をまたいで同じ主キーで残るため、パスワード認証で作ってから他方式を足す順序で構いません。

Supabase Authの構成要素とJWT発行までの実処理の流れ

公式ドキュメントは「Auth uses your project’s Postgres database under the hood」と書いており、ユーザーデータは専用スキーマに保存されます。

authスキーマとauth.usersテーブルが保持する列の役割

サインアップすると auth.users に1行が入ります。並ぶのは UUID の主キー、メールアドレス、確認済みかどうかのタイムスタンプ、暗号化済みパスワード、そしてアプリ側が使える2つの JSON 列。片方はユーザー自身が書き換えられるプロフィール的な値、もう片方はサーバー側からのみ書き込む権限や所属の値です。この使い分けを最初に決めないと「フロントから権限を書き換えられる」構造ができあがります。

実務では auth.users を直接 SELECT せず、public 側にプロフィール用のテーブルを作って主キーを外部キーで揃えるのが定石です。理由は2つ。auth スキーマの列構成は Supabase 側の変更対象で、将来の変更でクエリが引っかかること。認証情報のテーブルに業務データを足すと、権限の境界が引きづらくなることです。

アクセストークンに含まれるsubとroleクレームの実務的な意味

サインインが成功すると、アクセストークン(JWT)とリフレッシュトークンのペアが返ります。実装上の意味を持つクレームは sub・role・exp の3つ。sub には auth.users の UUID、role には Postgres のロール名が入ります。

この role が権限モデルの中心です。未サインインなら anon、サインイン後は authenticated、サーバー側の特権処理では service_role が入り、Postgres はこのロールで接続したものとしてクエリを実行します。JWT のクレームがそのままデータベースの実行主体になる、という一段の飛躍がここにある。ロールと鍵の対応関係はSupabase APIキーの管理とpublishable・secret鍵への移行で整理しました。

パスワード・OTP・OAuth・MFAの実装差と選択基準の置き方

公式が挙げる方式は、パスワード、マジックリンク、ワンタイムパスワード、電話認証、そして18種類のソーシャルプロバイダです。

メール・パスワード・マジックリンク・OTPの使い分けの判断基準

分かれ目は認証そのものの強度より「メールと SMS を誰が送るか」にあります。組み込みのメール送信はプロジェクト全体で2通/時に絞られ、サインアップ確認とパスワードリセットもこの枠を共有します。公開初日に数十人が登録すると即座に詰まる。カスタム SMTP は無料プランでも設定できるため、公開前の必須作業として扱ってください。

認証方式 追加費用 実装でつまずく点
メール+パスワード なし 組み込み送信は2通/時
マジックリンク なし ユーザー単位で60秒間隔
OTP(メール) なし 既定30通/時の枠
OTP(SMS) SMS事業者へ従量 MFA検証は15回/時
ソーシャル(OAuth) なし リダイレクト先の登録

SMS を伴う方式は MessageBird・Twilio・Vonage のいずれかと契約する前提になり、Supabase の料金とは別に通信費が乗ります。まずメール系で組み、SMS は多要素認証の2段目に限定する構成が扱いやすい。

OAuthプロバイダとMFA・SSOで追加になる設定と課金の境界

ソーシャルログインは Google・GitHub・Apple・Azure・Slack・Notion・Figma・Zoom など18種類が第一級サポートに入り、カスタムの OIDC プロバイダも登録できます。設定はプロバイダ側でクライアント ID とシークレットを取得し、Supabase に登録してリダイレクト先を合わせるだけ。手数がかかるのは Apple で、審査と鍵の期限管理が別途要ります。

課金の境界はここから先です。多要素認証のうち TOTP は標準機能に含まれますが、電話を使う Advanced MFA は最初のプロジェクトで月額75ドル、追加プロジェクトで月額10ドルのアドオンになります。SAML 2.0 のシングルサインオンは Pro 以上で50ユーザーまで無料枠があり、超過分は1 MAU あたり0.015ドル。企業向けに SSO を売り物にするなら、この単価を見積りへ入れます。Firebase 側の同等機能との比較はSupabaseとFirebaseの違いを徹底比較で扱っています。

JWT署名鍵の非対称化とgetClaims()によるローカル検証

Supabase の JWT 署名は、単一の共有秘密からライフサイクル管理された署名鍵の仕組みへ切り替わりました。これに合わせるかどうかで、検証コストと障害時の挙動が変わります。

レガシーJWT secretからES256の非対称鍵へ移行する手順

選べるアルゴリズムは4種類です。NIST P-256 曲線の ES256、RSA 2048 の RS256、Ed25519 の EdDSA(公式に「Coming soon」と記載)、そして共有秘密の HS256。公式は HS256 を「Not recommended for production applications」と明記し、RSA より計算コストが軽く署名も短い ES256 を推しています。移行はダッシュボード上の操作で完結します。

  1. JWT 署名鍵のページで「Migrate JWT secret」を押し、既存の共有秘密を新しい仕組みへ取り込む
  2. 自動生成される非対称鍵が standby 状態で並ぶことを確認する
  3. 「Rotate keys」で standby を in use に切り替える
  4. アクセストークンの有効期限が一巡してから、レガシーの共有秘密を revoke する

切り替えで既存ユーザーが弾かれる心配はありません。公式も「Non-expired access tokens will remain to be accepted, so no users will be forcefully signed out」と説明しています。鍵の状態は standby・in use・previously used・revoked の4つで、永久削除以外の操作は巻き戻せる。ただし状態変更には約5分のスロットリングがかかります。なお Supabase Edge Functionsとは:Deno実行環境とデプロイ・シークレット・課金単位で挙げた「Verify JWT」設定が有効なままだと、移行後に関数側で検証が通らないことがあります。

getClaims()でのローカル検証とJWKSキャッシュの注意点

非対称鍵に移すと、JWT の検証をアプリ側だけで完結させられます。公開鍵はプロジェクトの JWKS エンドポイント(パスは auth/v1/.well-known/jwks.json)から取得でき、クライアントライブラリの getClaims() がこの鍵で署名を検証します。認証サーバーへの往復が消えるためレイテンシが下がり、Auth サーバーが不調なときでも既存トークンの検証は続く。

気をつけるのはキャッシュの層です。Supabase のエッジ側で10分、クライアントライブラリのメモリ上でさらに10分、合わせて最大20分ほど古い鍵セットが参照されます。鍵を revoke した直後に「まだ通る」と見えるのはこの遅延によるもの。自前の検証コードでは、失効を即時反映させたいならキャッシュ期間を短く保つ判断が要ります。

RLSポリシーとauth.uid()を噛み合わせる権限設計の手順

認可の実装が Postgres 側に寄る構造のため、アプリのコード量は減る一方で、ポリシーを書き忘れたテーブルがそのまま露出します。

auth.uid()を前提にしたポリシー記述と有効化漏れの検知

ポリシーの中では auth.uid() が現在のユーザーの UUID を返し、auth.jwt() が JWT のペイロード全体を返します。所有者だけが自分の行を読める、という基本形はこの2つで書けます。落とし穴は「ポリシーを書いたのに効かない」ケースで、原因はほぼテーブル側で行レベルセキュリティを有効化していないこと。有効化されていないテーブルのポリシーは単に無視されます。

テーブル追加のたびに有効化とポリシーの有無を機械的に確認する手順を、運用へ組み込んでください。具体的な記述例、SELECT と INSERT で分ける書き方、有効化漏れの検知クエリはSupabase RLSの設定手順とAuth連携ポリシー設計に分けて置きました。

Custom Access Token Hookでロールを載せる判断の線引き

ポリシーの中で毎回「このユーザーはどの組織に属するか」を別テーブルへ問い合わせると、行数が増えるにつれて効いてきます。避ける手段が Custom Access Token Hook で、JWT が作られるたびに走り、任意のクレームを載せられる。組織 ID や業務ロールを埋めておけば、ポリシー側は auth.jwt() を見るだけで済みます。

ただし無条件に使う機能ではありません。JWT に載せた値は有効期限が切れるまで古いまま残るため、権限を剥がしても最大1時間は効いてしまう。即時反映が要る業務なら、テーブル参照のままにするか有効期限を詰めます。実行時間の上限も設計条件で、Postgres 実装のフックは2秒、HTTP 実装は5秒でタイムアウトします。なお MFA Verification Attempt と Password Verification Attempt の2つは Teams と Enterprise 限定。パスワード検証フックで不正検知を組む計画なら、プラン要件を先に確認してください。

セッション運用で決める設定値:有効期限・ローテーション・強制終了

セッションまわりは既定値のままでも動きますが、業務要件に合わない項目が混じります。

アクセストークンの1時間とリフレッシュ再利用10秒という既定値

アクセストークンの既定有効期限は1時間で、公式も「Most applications should use the default expiration time of 1 hour」と書いています。ダッシュボードのセッション設定から変更でき、推奨される下限は5分。短くすれば漏洩時の被害窓は狭まりますが、そのぶんリフレッシュの頻度が上がります。

リフレッシュトークンは原則1回しか使えず、使用時に新しいペアへ交換されます。ここに10秒の再利用インターバルが設けられ、この窓の内側なら同じリフレッシュトークンを複数回使えます。サーバーサイドレンダリングで同じトークンが並行して使われる状況への緩和策です。逆に、10秒を超えて古いリフレッシュトークンを使い回す実装はサインアウト扱いになる。複数タブでセッションが落ちる症状は、ここを疑うと当たりやすい。Cookie へ載せ替える実装はSupabase Next.js連携の実装とApp Router構成にまとめました。

time-box・非アクティブ切断・単一セッションのプラン制約

明示的なセッション終了は3種類あります。固定期間で必ず切る time-box、更新のない期間で切る非アクティブタイムアウト、そして最後にサインインしたセッションだけを残す単一セッション強制。公式は単一セッションを「only keeps the most recently active session」と説明しています。

この3つはいずれも Pro プラン以上の機能です。「同時ログインは1端末まで」「8時間で必ず切る」といった要件を無料プランのまま実装しようとすると、アプリ側で疑似的に作り込むことになり、二重管理になります。この種の項目が要件表に並ぶ案件は、見積りの段階で Pro 前提(月額25ドル)として扱ってください。なお設定変更後のセッション削除は段階的に進み、反映まで24時間ほど要します。

MAU課金とレート制限から逆算する本番運用のコストと上限の設計

認証は利用者数に比例して費用が動きます。単価と上限を先に押さえておくと、規模が伸びたときの説明がしやすくなります。

MAU 5万・10万の無料枠と超過単価から逆算する月額の見積り

月間アクティブユーザーの無料枠は、Free で50,000、Pro と Team で100,000です。Pro と Team は超過分が1 MAU あたり0.00325ドルで、Free の枠を超える規模は上位プランへの移行が前提になります。

プラン 月額 MAU無料枠 超過単価
Free 0ドル 50,000 Pro以上へ移行
Pro 25ドル 100,000 0.00325ドル
Team 599ドル 100,000 0.00325ドル
Enterprise 個別 個別 個別

数字を入れると規模感がつかめます。MAU が15万まで伸びた Pro 環境なら、超過は5万人ぶんで月額162.5ドル、基本料と合わせて190ドル弱。外部 IdP を併用する場合もサードパーティ MAU として同じ0.00325ドルが乗ります。会員数十万規模でも数百ドル台に収まるため、費用面が採用の障害になる場面は限られます。

組み込みメール2通/時とトークン更新1800回/時という上限への対策

レート制限は既定値を把握しておかないと、原因不明の失敗として現れます。主なものは、組み込みメール送信がプロジェクト全体で2通/時(カスタム SMTP で緩和)、OTP 送信が30通/時、同一ユーザーへのマジックリンク・サインアップ確認・パスワードリセットが60秒間隔、トークン更新が IP あたり1,800回/時、検証エンドポイントが360回/時、MFA のチャレンジと検証が15回/時、匿名サインインが30回/時です。

このうちトークン更新・検証・MFA・匿名サインインは IP 単位の固定値で、変更できません。多数の利用者が同一の出口 IP からアクセスする社内システムでは、1,800回/時の更新上限が現実的な天井になる。有効期限を1時間より短くする設計はこの上限と衝突しやすいため、利用者数と更新頻度の積を先に見積もってください。既存の社内システムと認証を接続する構成の設計は、API開発・システム連携のご相談としてお引き受けしています。

Supabase Authを採用しない場面と外部IdPへ寄せる判断条件

ここは言い切ります。Supabase Auth は「データベースが Supabase であること」に強く依存した認証で、そこから外れる要件では外部 IdP を選ぶほうが安く済みます。

Supabase Authを採用してよい3つの条件と前提の確認

採用して良いのは次の条件が揃うときです。第一に、業務データの本体が同じ Supabase の Postgres にあること。認証と認可が同じデータベースで閉じるからこそ、auth.uid() を使ったポリシーで済みます。第二に、利用者が自社サービスのエンドユーザーであること。第三に、認証要件がパスワード・ソーシャルログイン・TOTP による多要素認証・SAML の SSO という標準機能の範囲に収まることです。

典型は、会員向けの Web サービスや社内向けの業務アプリ。逆に、Postgres が別のクラウドにあって Supabase を認証だけに使う構成は、RLS 連携という最大の利点を捨てることになり、素の認証サービスとして比較されて選ぶ理由が薄くなる。検証環境の立て方はSupabase CLIとローカル開発環境を参照してください。

Clerk・Auth0などのサードパーティ認証へ寄せる判断の場面

Supabase は Clerk・Firebase Auth・Auth0・AWS Cognito・WorkOS の5社を第一級のサードパーティ認証としてサポートします。これらが発行した JWT を Supabase Auth 発行の JWT と同じように信頼させられるため、認証は外に置いたまま Data API・Storage・Realtime・Functions を使える。次の要件が出たら、迷わず外側へ寄せてください。

  • 既存の会員基盤が別システムにあり、そちらを正とし続ける必要がある
  • 組織・招待・権限管理の画面まで作り込みたい(Clerk や Auth0 が既製で持つ領域)
  • Teams 以上でしか使えないパスワード検証フックに依存した不正検知を、下位プランで実装したい

併用時の制約は3点あります。非対称署名の JWT で、ヘッダーに kid が入っていることが必須で、対称署名は受け付けません。鍵のローテーションは定期的に確認される仕組みのため、反映に最大30分かかる。そして「It is not possible to disable Supabase Auth at this time」と明記されている通り、Supabase Auth 自体は止められません。外部 IdP を主にしてもエンドポイントは開いたままになる前提で、公開設定を見直してください。

よくある質問

実装の入口でつまずきやすい点を、公式ドキュメントと料金ページの記載に沿って答えます。

Supabase Authだけで会員管理システムを作れますか?

サインアップ・サインイン・パスワード再設定・多要素認証までは標準機能で足ります。ただし会員一覧の検索、退会の履歴管理、権限の付与画面といった管理側の作り込みは自前です。auth.users は認証情報のテーブルなので、業務上のプロフィールや権限は public 側へ持たせ、主キーで紐づける設計が前提になります。

anon keyをフロントに置いても安全ですか?

行レベルセキュリティを正しく有効化している限り、フロントに置く前提の鍵です。anon ロールとして接続するため、ポリシーで許可した範囲しか見えません。危険なのは service_role 側で、こちらは行レベルセキュリティを迂回します。フロントのバンドルや公開リポジトリに混ざると、全テーブルが読み書きできる状態になる。鍵ごとの露出範囲と移行手順は、APIキー管理の記事へ分けました。

レガシーJWT secretは今すぐ止めるべきですか?

本番運用しているプロジェクトなら移行を優先してください。公式が共有秘密を「Not recommended for production applications」としている理由は、秘密が漏れた時点でユーザーのなりすましと特権操作が可能になるうえ、入れ替えるとユーザーが強制サインアウトされる点にあります。非対称鍵に移せば、鍵の切り替えでサインアウトは起きません。

auth.usersを直接参照してもよいですか?

ポリシーの中で auth.uid() を通して照合するのは通常の使い方です。一方、アプリのクエリから auth.users を JOIN して表示用の値を取り出す設計は避けてください。列構成は Supabase 側の変更対象であり、将来の変更でクエリが壊れる可能性があります。表示名やアイコンは public のプロフィールテーブルへ複製し、サインアップ時に Before User Created フックかトリガーで同期させる形が扱いやすいです。

無料プランのまま本番公開しても問題ありませんか?

MAU 50,000 までの無料枠とカスタム SMTP は Free でも使えるため、小規模なら成立します。ただしセッションの time-box・非アクティブタイムアウト・単一セッション強制はいずれも Pro 以上で、これらが要件に入るなら満たせません。加えて Free にはプロジェクトの一時停止条件があるため、業務システムとして常時稼働させるなら Pro(月額25ドル)を前提に見積もる判断になります。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.15 テックブログ リゾートトラスト不正アクセス:会員2.6万件・カハラ横浜3.6万件の対象確認と窓口
  2. 2025.09.03 コラム ストループ効果とは?原典1935年の実測値と年齢別の平均・テストのやり方
  3. 2026.01.20 テックブログ PineDramaとは?TikTokショートドラマアプリの料金・安全性とTikTok内ミニドラマの課金
  4. 2026.04.13 コラム ゴルフ賞金の税金はいくら?1,000万円で源泉194万円・確定申告での精算と副賞の車、海外賞金【令和8年分】
  5. 2026.10.16 テックブログ バーガーキング情報漏洩どうしたらいい?約1,118万件の対象確認・補償・退会とメールの真偽

RELATED POSTS 関連記事

目次