メインコンテンツへスキップ

SupabaseをPostgreSQLと認証基盤(IDaaS)として安全に使うための初期設定

SupabaseをPostgreSQLと認証基盤(IDaaS)に絞って安全に利用するための初期設定ガイド。Prisma等のORM利用時に意図しないデータ露出を防ぐ「Data APIの無効化」やリージョン選択、接続設計を解説します。

Supabaseは、マネージドなPostgreSQL環境としても、Firebase AuthやAuth0のような認証基盤(IDaaS)としても、非常に優れたサービスです。

一方で、バックエンドサーバー(Node.js、Next.js等)からPrismaなどのORMを使って直接PostgreSQLに接続し、認可制御もサーバー側で完結させるアーキテクチャを採用する場合、初期設定で必ず確認しておきたいポイントがあります。それが 「利用しないData APIを無効化する」 ことです。

自前のアプリケーションAPI側でどれだけ厳密に認可処理を実装していても、SupabaseのData APIが有効なままになっていると、バックエンドサーバーを経由せずにデータベースへ直接アクセスできる裏の経路が開いたままになってしまいます。この経路を使用しないのであれば、あらかじめ無効化しておくことでセキュリティリスクを最小限に抑えられます。

本記事では、Supabaseを「PostgreSQL」と「認証(Auth)」に絞って安全に運用するための推奨セットアップ手順を解説します。

※本記事の内容および料金・仕様は2026年10月16日時点の情報に基づいています。掲載している画面は執筆時点のダッシュボードUIです。

PostgreSQLと認証に絞っても十分に利用価値がある

Supabaseの無料枠(Freeプラン)には、1プロジェクトあたり500MBのデータベース容量と、月間50,000人までのアクティブ認証ユーザー枠(MAU)が含まれており、最大2プロジェクトまでアクティブに利用できます。小規模なサービスやプロトタイプの開発、検証環境としては十分なリソースが提供されています。公式料金表

ただし、無料枠では「1週間アクセスがないとプロジェクトが一時停止(スリープ)する」「自動バックアップが含まれない」といった制約があります。そのため、本番環境で運用する際は、可用性やデータ保護の要件に応じてProプラン以上の利用を検討してください。

SupabaseにはStorageやRealtimeなどの豊富な機能が用意されていますが、必ずしもすべての機能を使う必要はありません。公式ドキュメントのアーキテクチャ解説でも、各コンポーネントは独立して利用できるように設計されていることが示されています。Architecture

本記事で想定するシステム構成は以下のとおりです。

ブラウザ ── ログイン・トークン更新 ──→ Supabase Auth
    │
    └── アプリケーションへのリクエスト ──→ 自前のバックエンドサーバー
                                             │
                                      認証トークンの検証・認可
                                             │
                                      PrismaなどのORM
                                             │
                                      Supabase PostgreSQL

この構成では、ユーザー認証をSupabase Authに任せ、ビジネスロジックや認可判定は自前のバックエンドサーバーで処理し、データベースへの読み書きはPrisma等のORMを介してPostgreSQLに直接接続します。 なお、認証機能のみをSupabase Authに任せて業務データは別の外部データベースに保存する構成も可能ですが、Supabase Auth自体がプロジェクト内のPostgreSQLにユーザー情報を保持する仕組みのため、Supabase側のデータベースを完全に排除できるわけではありません。Users

Data APIを開いたままにするリスク

SupabaseのData APIは、PostgRESTを利用してデータベースへHTTP経由でアクセスできるようにする機能です。クライアント(ブラウザやモバイルアプリ)にPostgreSQLの接続情報を渡すことなくデータを操作できる便利な仕組みですが、バックエンドサーバーを介さずにデータベースを直接操作できる経路にもなります。Architecture

たとえば、自前のバックエンドサーバーで以下のような認可ルールを実装していたとします。

請求書データを取得する際は、ログインユーザーがその請求書の発行元組織に所属しているかを確認する。

この認可チェックは、自前のサーバーを経由したリクエストに対してのみ機能します。もしSupabaseのData APIが有効なまま放置されていれば、悪意のあるユーザーや外部のリクエストがData APIを経由して直接データを読み書きできてしまう可能性があります。サーバー側の認可ロジックが、Data API側に自動で適用されることはありません。

Data APIをフロントエンドから直接利用するアーキテクチャであれば、PostgreSQLのRow Level Security(RLS)を用いてData API側でも適切にアクセス制御を設計・設定すれば問題ありません。しかし、サーバー側のORMから直接PostgreSQLへ接続する構成であれば、使わないData API側のアクセス制御まで二重に保守・管理し続けるのは不要な運用リスクとなります。

Supabaseの公式ドキュメントでも、クライアントSDKによるデータ操作機能やREST/GraphQLのエンドポイントを使用しない場合は、Data APIを明示的に無効化するよう推奨されています。Securing your API

「公開キーの露出」と「アクセス権限の不備」を混同しない

セキュリティを検討する際、「公開キーが見えること」と「不正にデータが取得できること」の違いを正確に理解しておく必要があります。

Supabaseのpublishable key(従来のanon key)は、クライアントサイド(ブラウザやアプリ)のコードに含めて配布することが前提のキーです。したがって、ブラウザの通信やHTMLソースからこのキーが見えること自体は、秘密情報の漏洩やセキュリティインシデントではありません。また、公開キーを入手しただけでPostgreSQLの管理者権限が奪われることもありません。API keys

Data API経由でどこまで操作できるかは、PostgreSQLの権限設定(GRANT)や、行単位のアクセス制御を行うRLS(Row Level Security)のポリシーによって決定されます(RLSはSupabase独自のものではなく、PostgreSQL標準のセキュリティ機能です)。Row Level Security

PostgreSQLにおけるテーブルアクセス権限とRLSの組み合わせによる挙動は以下のとおりです。

設定状態

Data API(anon/authenticatedロール)からのアクセス動作

対象ロールに権限(GRANT)がない

テーブルへのアクセス(SELECT/INSERT等)は拒否されます

権限(GRANT)があり、RLSが無効

行単位の制限がなく、許可された操作がテーブル全体の全行に対して可能になります

権限(GRANT)があり、RLSが有効でポリシー未設定

RLSのデフォルト拒否により、行へのアクセスはすべて拒否されます

権限(GRANT)があり、RLSのポリシーが不完全・広すぎる

設定されたポリシーの条件に合致する範囲でデータにアクセスできてしまいます

※上記は通常のテーブルとRLS適用対象ロールにおける基本動作です。テーブル所有者(Owner)やRLSをバイパスするロール、SECURITY DEFINER関数やビューを経由する場合は挙動が異なるため別途注意が必要です。Row Level Security

このように、真の問題は「公開キーが知られたこと」ではなく、 「外部に開いているアクセス経路に対して、適切なアクセス制御(権限剥奪やRLSポリシー)が設定されていないこと」 です。参照権限が空いていれば情報漏洩につながり、更新・削除権限まで開いていればデータの改ざんや消失のリスクが生じます。

なお、管理者用のsecret key(従来のservice_role key)は絶対に公開してはいけない秘密鍵です。これはRLSをバイパスしてすべての操作が可能な強力な権限を持っているため、フロントエンドのコードや環境変数に含めてはいけません。また、データベースの直接接続パスワードやJWT署名用の秘密鍵も同様に、バックエンドサーバーの安全な環境変数でのみ管理する必要があります。API keys、JWT Signing Keys

設定ミスによるデータ露出のリスクと対策

アクセス制御の不備によるデータ露出は、机上の空論ではなく実際に数多くの調査研究で報告されています。

サイバーセキュリティ企業のUpGuardが公開した調査報告(2026年9月)によると、Supabaseの利用形跡がある約30万ドメインを調査した結果、外部から読み取り可能なテーブルが存在するデータベースが16,326件特定されたと報告されています。さらにスキーマの分析から、そのうち半数以上のテーブルに個人情報(PII)が含まれている可能性が指摘されています。UpGuardの調査報告

ただし、これはSupabaseのプラットフォーム自体がハッキングされたわけではなく、利用者側のRLS設定ミスや無効化によって意図せずデータが公開状態になっていたことが原因です。

コミュニティでも、「公開キー(anon key)を入手した第三者が容易にデータを閲覧できてしまうため、ダッシュボードの警告をより明確にすべきだ」という意見と、「アクセス権限を正しく設定するのは開発者自身の責任である」という議論が交わされています。r/Supabaseでの議論

ここで最も警戒すべき状況は、「自前のサーバー側に認可処理を書いたから、データへの入口はそこしかないはずだ」と思い込んだまま本番運用してしまうことです。バックエンドサーバー経由でのみアクセスするアーキテクチャであれば、不要なData APIという入口そのものをプロジェクト作成時に閉じておくことが、最も確実で安全な対策となります。

デフォルト設定の改善と、Data API無効化の意義

従来のSupabaseでは、PostgreSQLのpublicスキーマに作成されたテーブルに対して、Data API用のロールへ操作権限が自動付与される仕様になっていました。そのため、PrismaなどのORMマイグレーションでテーブルを追加した際、Data API向けのRLSや権限設定を失念すると、意図せずデータが外部からアクセス可能になってしまうリスクがありました。

この課題に対し、Supabase公式もデフォルト設定の安全性強化を進めています。2026年4月の公式発表では、新規テーブル作成時にData API用ロールへ自動で権限を付与しない仕様への段階的な移行(新規プロジェクトから既存プロジェクトへの順次適用)がアナウンスされました。自動公開設定の変更に関する公式発表

しかし、「新規テーブルへの自動権限付与をオフにする設定」と「Data APIそのものを無効化する設定」は異なります。プラットフォーム側のデフォルト設定が改善されたとしても、ORMからの直接接続しか使わないシステム構成であれば、Data APIそのものを完全に無効化しておくことが最もシンプルで確実な防御策となります。

プロジェクト作成時の初期設定手順

プロジェクトを作成する際は、以下のステップで「リージョンの指定」と「Data APIの無効化」を行います。

1. 組織のプランと追加コストを確認する

プロジェクト作成画面を開くと、デフォルトでリージョンが広域指定のAsia-Pacific、またEnable Data APIやAutomatically expose new tablesにチェックが入った状態になっている場合があります。

なお、添付の画面例は有料のProプラン組織で撮影されたものであり、下部に追加費用(Computeサイズに応じた料金など)が表示されています。無料枠で利用したい場合は、対象組織がFreeプランになっていることや、無料プロジェクト数(最大2つ)の上限を超えていないかを確認してください。公式料金表

2. リージョンは「Northeast Asia (Tokyo)」を明示して選択する

リージョン選択ドロップダウンを開き、Northeast Asia (Tokyo)(リージョンコード: ap-northeast-1)を明示的に選択します。

初期状態で表示されるAsia-Pacificは東京をピンポイントで指すものではなく、アジア太平洋地域のインフラ空き容量に応じて自動配置される広域指定です(シンガポール等に配置される場合もあります)。Available regions

ORMからPostgreSQLへ接続する場合、アプリケーションサーバーとデータベース間のネットワークレイテンシ(RTT)がクエリパフォーマンスに直結します。自前のサーバーが国内(東京リージョンなど)にある場合は、必ずTokyoを明示して作成してください。

プロジェクト作成後にリージョンを変更する場合、プロジェクトの再作成とデータの移行が必要となり、接続先や認証プロバイダーの設定変更など大きな手間が発生します。必ず初期作成時に正しいリージョンを選択しておきましょう。Change Project Region

3. 「Enable Data API」のチェックを外す

続いて、Enable Data APIのチェックを外してオフにします。リージョンがTokyoになっていることを再確認した上でプロジェクトを作成します。

チェックを外すと「クライアントライブラリからデータを読み書きできなくなる」旨の警告が表示されますが、今回の構成ではデータベース操作をすべてバックエンドのPrisma等で行うため問題ありません。

既存プロジェクトでData APIを無効化する場合

すでに作成済みのプロジェクトでも、ダッシュボードの「Project Settings」>「API」設定からEnable Data APIをいつでもオフにできます。無効化すると、自動生成されたRESTエンドポイントはGRANTやRLSの設定内容にかかわらず完全にリクエストを受け付けなくなります。Securing your API

既存プロジェクトで無効化する際は、フロントエンドやバックエンドコード内でsupabase.from(...)やsupabase.rpc(...)などのData API経由のアクセスを行っている箇所がないかを必ず事前に確認してください。

Data APIを無効化してもSupabase Authは利用可能

Supabase AuthはData APIとは独立したサービス(GoTrue)として稼働しているため、Data APIを無効化してもユーザー登録やログインなどの認証機能は通常どおり利用できます。@supabase/supabase-jsクライアントを利用する場合でも、データ操作(supabase.from)と認証操作(supabase.auth)は別系統として扱われます。 ただし、StorageやRealtimeなど他の機能を利用する場合は、Data APIをオフにしてもそれぞれの機能専用のエンドポイントが開いているため、機能ごとに個別のアクセス制御が必要になる点には留意してください。Architecture

データベース接続の構成とベストプラクティス

プロジェクトの作成が完了したら、ダッシュボード上部の「Connect」ボタンからPostgreSQL接続文字列を取得します。ここで取得するのはデータベース接続情報(URI)であり、APIキーとは異なります。

実行環境に応じた接続方式の選択

Supabaseでは、直接接続(Direct connection)とコネクションプーラー(Supavisor)経由の接続が提供されています。サーバーの実行環境に合わせて最適な方式を選択します。

実行環境・用途

推奨される接続方式

接続ポート

主な注意点

IPv6に対応した常駐型サーバー(EC2、コンテナ等)

Direct connection

5432

IPv6ネットワークが必須。接続制限数に注意

IPv4のみの常駐型サーバー

コネクションプーラー(Session mode)

5432

IPv4から接続可能。セッション単位で接続を維持

サーバーレス環境(AWS Lambda、Vercel等)

コネクションプーラー(Transaction mode)

6543

短時間の大量接続を効率化。Prepared Statementsの制約あり

DBマイグレーション(Prisma Migrate等)

Direct connection(またはSession mode)

5432

DDL実行やアドバイザリロックを伴うためTransaction modeは不可

※Direct connectionはIPv6接続が基本となります。接続エラーが発生する場合は、利用しているサーバー環境のIPv6対応状況を確認してください。プーラーの接続先ホスト名は自身で組み立てず、「Connect」ダイアログに表示される正規の値をコピーして使用します。Connect to your database

Prismaを利用する場合、サーバーレス環境では実行時のクエリ用にTransaction modeのURL(ポート6543)を指定し、マイグレーション用にdirectUrl(Direct connectionまたはSession mode、ポート5432)を別個に設定する構成が公式に案内されています。また、Transaction mode利用時は接続文字列にpgbouncer=trueパラメーターを付与するなどの調整が必要です。利用するPrismaのバージョンやドライバーの最新仕様を公式ガイドで確認してください。SupabaseのPrismaガイド

アプリケーション実行用とマイグレーション用でDBロールを分離する

データベース接続の初期設定では、管理者ロール(postgresなど)の接続情報をそのまま本番アプリケーションに流用してしまいがちですが、セキュリティの観点から権限を分離することが推奨されます。

SupabaseのPrisma導入ガイド等に記載されている初期接続ロールには、セットアップを簡略化するためにBYPASSRLSやCREATEDBなどの強力な特権が付与されている場合があります。SupabaseのPrismaガイド

本番運用では、以下の2つのロールを切り分けて運用するのが安全です。

  1. マイグレーション用ロール(CI/CDやデプロイ時に使用) : テーブル定義の変更(DDL)、作成・削除、インデックス操作などが可能な権限を持つロール。
  2. アプリケーション実行用ロール(通常のAPIサーバーが使用) : 日常的なデータのCRUD操作(DML: SELECT、INSERT、UPDATE、DELETE)および必要なシーケンスの利用権限のみを付与し、テーブル定義の改変や管理者権限は持たせないロール。

また、業務用のテーブルをPostgreSQL標準のpublicスキーマではなく専用の業務スキーマ(例: appスキーマなど)に分離して管理することも、誤ってData APIなどの公開対象に含まれてしまうリスクを低減する有効な手段となります。

認証・認可の実装ポイント

Data APIを無効化した場合、データのアクセス制御は自前のバックエンドサーバー側で責任を持って実装する必要があります。PrismaなどのORMはデータベースクエリを安全かつ効率的に構築するためのツールであり、ユーザーごとの認可(アクセス権限の判定)を自動で処理してくれるわけではありません。

バックエンドサーバーでは、以下のステップでリクエストを処理します。

  1. 認証トークンの検証 : クライアントから送られたアクセストークン(JWT)の正当性を検証する。
  2. 認可制御の実行 : 検証済みのユーザーIDに基づいて、リクエストされたリソースに対する操作権限があるかを確認する。
  3. データアクセスの実行 : 認可された操作のみをORM経由でPostgreSQLに対して実行する。

JWTの正当な検証

Supabase SDKを使用する場合、supabase.auth.getClaims()等を利用してJWTの署名検証とクレーム取得を行います。非対称鍵を使用しているプロジェクトではJWKS(公開鍵セット)を用いてローカルで高速に検証され、それ以外の場合はSupabase Authサーバーへの問い合わせによって検証されます。署名の検証を行わずにJWTのペイロードをBase64デコードしただけでユーザーを認証済みとみなしてはいけません。getClaims

Supabase SDKを使わず一般的なJWTライブラリで検証を行う場合も、電子署名の正当性、有効期限(exp)、発行元(iss)、対象者(aud)を厳密に検証し、署名鍵のキャッシュやローテーションに対応した実装が必要です。JSON Web Token、JWT Signing Keys

アプリケーション側での認可判定

認可では、「ログインしているか」だけでなく、「そのユーザーが指定されたテナントや組織に所属しているか」「そのリソースを変更する権限(ロール)を持っているか」までチェックします。クライアントからリクエストボディ等で送られてきたuserIdやorganizationIdを無検証で信用せず、必ずJWTから取り出した検証済みのユーザー識別子をもとにデータベース上で権限を照合してください。

なお、バックエンドサーバー側でJWTを検証しても、そのユーザー情報がPrismaを介したPostgreSQL接続のセッションに自動で引き継がれるわけではありません。Data API向けに書かれたauth.uid()を参照するRLSポリシーは、通常のORM直接接続では機能しない点に注意してください。

本番運用に向けたAuth関連の設定

Supabase AuthをIDaaSとして本番運用するにあたっては、以下の設定も不可欠です。

  • カスタムSMTPの設定 : メールアドレス確認やパスワードリセット、Magic Linkなどで送信されるメールについて、Supabase標準の内蔵メールサービスは検証用途向けにレートリミットが非常に厳しく制限されています(1時間に数通程度)。本番公開前に、ResendやSendGrid、Amazon SESなどの外部メール配信サービスを「Custom SMTP」として必ず登録してください。Send emails with custom SMTP
  • Site URLとリダイレクトURLの制限 : 本番環境のドメイン(Site URL)を設定し、認証後のリダイレクト先(Redirect URLs)は必要なURLのみに厳密に制限します。開発環境やプレビュー環境で使用した広範なワイルドカード(*)設定を本番環境に残さないように注意してください。Redirect URLs

設定完了後の動作確認チェックリスト

初期設定および実装が完了したら、想定どおりのアクセス制御が効いているかをテスト環境等で実際に確認します。

  • Data APIが無効化されていること : publishable key(またはanon key)を用いてRESTエンドポイント(https://<project-ref>.supabase.co/rest/v1/<table_name>)へHTTPリクエストを送信した際、リクエストが拒否されること(APIが無効化されているレスポンスが返ること)。 ※単に空配列([])が返ってくるだけの場合は、Data API自体は有効でRLSにより0件になっているだけの可能性があるため、ステータスコードやエラーメッセージまで確認してください。
  • バックエンドからのDB接続が正常であること : バックエンドサーバーからPrisma等のORMを介してPostgreSQLへ接続し、必要なテーブルの読み書きが正常に行えること。
  • Supabase Authが正常に動作すること : ユーザー登録、ログイン、セッション更新(トークンリフレッシュ)が正常に完了すること。
  • 自前APIの認可制御が機能していること : 未認証のリクエストや、他ユーザー・他組織のリソースに対する不正な操作リクエストを、自前のバックエンドAPIが適切に遮断(401 Unauthorized / 403 Forbidden)できること。

まとめ:データアクセス経路を集約して堅牢に運用する

自前のバックエンドサーバーで認可を行い、ORM経由でデータベースにアクセスする構成において、データへのアクセス経路を自前サーバーへ一元化することには大きなメリットがあります。

もっとも大きな利点は、 認可ロジックと業務監査ログの一元管理 です。 「誰が、いつ、どの組織のデータを、どのような業務目的で変更したのか」という業務レベルの監査ログは、アプリケーションサーバー側のビジネスロジックで記録するのが最も自然で確実です。もしData APIとサーバー側APIの双方が開いていると、アクセス制御ポリシーだけでなく監査ログの収集ルールも二重に設計・管理しなければならず、実装漏れや設定ミスの温床になります。Logs in Studio

また、データアクセスを標準的なPostgreSQL接続とPrismaなどのORMに集約しておくことで、Supabase独自のAPIへの過度なロックインを避け、将来的なインフラ移行や構成変更に対する柔軟性を維持できるという利点もあります。

もちろん、Data APIとRLSを徹底的に作り込み、クライアントから直接データベースを活用するBaaS(Backend-as-a-Service)としての設計パターンも強力です。しかし、すでにバックエンドサーバーを構築してORMを利用するアーキテクチャを選択しているなら、不要なData APIを開いたままにしておく理由はありません。

Supabaseは、用意された機能をすべて一括で採用しなければならないサービスではありません。「信頼性の高いPostgreSQLホスティング」と「洗練された認証基盤(IDaaS)」という強力なパーツだけを活用し、業務データの門番は自前でしっかりと統制する――こうした設計を採用する際は、プロジェクト初期作成時に適切なリージョン(Tokyo等)を選び、不要なData APIを無効化しておくことをおすすめします。