本文へ移動
Signalcraft
English

← Signalcraft一覧へ戻る

SupabaseのAPIキーとDB接続を経路から整理する

SupabaseのAPIキーとDB接続を経路から整理する

Supabaseの接続で迷ったら、最初にアプリからData APIを呼ぶのか、PostgreSQLへ直接つなぐのかを分けます。

API keyとデータベースパスワードは、どちらも接続設定に登場します。

しかし、用途、権限、保管場所は別です。

用語を接続経路へ対応させる

用語 役割 置く場所の原則
Publishable key クライアントからData APIへ送る公開前提のkey Webやモバイルの公開コード
Secret key RLSを迂回し得る高権限のkey 管理下のサーバーだけ
Data API HTTP経由でデータへアクセスする経路 アプリケーションのAPI呼び出し
Direct connection PostgreSQLプロトコルで直接接続する経路 DB clientや長時間接続
Session Pooler Supavisor経由でsession単位に接続を再利用する経路 IPv4や永続的な接続
Transaction Pooler transaction単位で接続を再利用する経路 serverlessや短い処理

API keyを取得しても、psqlがDBへログインできるとは限りません。

DBパスワードを知っていても、ブラウザへ埋め込んでよいとは限りません。

先に利用目的を決める

目的 主な経路 認証と権限
ブラウザやモバイルから読み書きする Data APIとSupabase client Publishable key、ユーザー認証、RLS
サーバーで管理処理を行う Data APIまたはDB接続 Secret keyまたはサーバー用DB資格情報
psql、DBeaver、Metabaseから接続する PostgreSQL接続文字列 DB user、password、host、port
serverlessから短いqueryを実行する Transaction PoolerまたはData API clientの接続制約を確認

この表の経路を決めてから、必要なcredentialを発行します。

「API keyがあるからDB GUIへ接続する」という順番にしません。

Publishable keyは公開前提だが無制限ではない

SupabaseのPublishable keyは、利用者が値を取得できるWebページやモバイルアプリで使える設計です。

公開前提という意味は、keyだけで全行を読めるという意味ではありません。

Data APIでは、リクエストへ適用されるPostgres roleとRow Level Security(RLS)が実際の境界になります。

未ログインの要求は通常anonとして評価され、Supabase Authでログインした要求はauthenticatedとして評価されます。

Browser
  └─ Publishable key + user JWT
       └─ Data API
            └─ RLS policyで行単位のアクセスを制御

Publishable keyを隠すためだけに、すべての要求を自分のserverへ中継する必要はありません。

公開経路へ出すテーブル、view、RLS policyを先に設計します。

Secret keyはバックエンド専用にする

SupabaseのSecret keyは高い権限を持ち、RLSを迂回してデータへアクセスし得ます。

管理下のserver、Edge Functions、admin backend、batch、data pipelineに限定します。

次の場所へ置きません。

  • ブラウザへ返すJavaScript
  • モバイルやdesktop appへ埋め込む
  • Git repository、README、Issue、chat
  • URLのquery parameter
  • ログへ残る可能性がある入力欄

Secret keyを使うserverが、そのまま安全なadmin画面になるわけではありません。

admin authentication、操作ごとのauthorization、入力検証、audit logを別に設計します。

旧形式のkeyは移行対象として扱う

Supabaseには、従来のanonservice_roleも残っています。

公式のAPI key資料では、新しいPublishable keyとSecret keyに対応する旧形式として説明されています。

新しいkeyを作っただけで、旧keyが自動的に無効になるとは限りません。

移行時は、環境変数、CI、Edge Functions、local設定がどのkeyを参照するかを一覧にします。

置き換えを確認した後で、旧keyを明示的に無効化する計画を作ります。

旧形式と新形式では、JWT、Authorization: Bearer、Edge Functionsの検証方法に差があり得ます。

clientや構成を変えるときは、利用中のkey形式に対応する公式資料を確認します。

Data APIとPostgreSQL接続を混ぜない

Data APIはHTTP経由でtableやviewへアクセスします。

Supabase client libraryは、認証とHTTP requestの組み立てを扱いやすくします。

DBeaverやpgcliはPostgreSQL protocolで接続します。

必要なのは、Connect画面に表示されたhost、port、database、user、passwordです。

host: db.<project-ref>.supabase.co または <region>.pooler.supabase.com
port: 5432 または 6543
database: postgres
user: Connect画面に表示された値
password: データベースのパスワード

Direct connectionとPoolerではhostやuserの形式が異なります。

例から接続文字列を推測せず、プロジェクトのConnect画面から値を取得します。

SSLの設定も公式の接続手順に合わせます。

接続文字列、DB password、secretはrepository、shell history、logへ残しません。

DirectとPoolerを接続寿命で選ぶ

方式 特徴 主な用途
Direct connection PostgreSQLへ直接接続。通常はIPv6 pg_dump、migration、DB GUI、長時間動くserver
Shared Pooler Session Supavisor経由。通常はport 5432 IPv4のみの永続backend、GUIの代替
Shared Pooler Transaction Supavisor経由。通常はport 6543 serverless、Edge Functions、短いquery
Dedicated Pooler 専用resourceのPooler 高い性能や分離が必要な用途

Transaction modeでは、transactionをまたいでconnectionを保持しません。

prepared statementも扱えないため、client設定で無効化が必要になる場合があります。

port 5432だからDirectとは限りません。

host名とConnect画面の説明を組み合わせて判断します。

read-onlyはkey名ではなく権限で作る

「read-only key」という名前だけで読み取り専用になると考えません。

Data APIでは、Publishable key、公開するtableやview、RLS policyで読み取り可能な範囲を作ります。

PostgreSQL clientでは、専用roleへ必要なschemaとtableのSELECTだけを付与します。

GUIのread-only settingは追加の安全策であり、DB側の権限を代替しません。

Secret keyを使ってからGUIの編集ボタンを隠す設計は、credentialが強すぎます。

事故時の影響を小さくするには、RLSまたはDB roleを先に絞ります。

用途別の選び方

Browser app

Publishable keyをクライアントへ渡し、user authenticationとRLSで制御します。

秘密keyが必要な管理処理はserver-side APIへ分離します。

Admin backendとbatch

server側でSecret keyを使うか、目的に合わせた専用DB roleを使います。

Secret keyを使う場合でも、操作を限定するauthorizationを実装します。

psqlとDB GUI

まずDirect connectionを試します。

IPv6へ接続できない場合はSession Poolerを検討します。

長時間の対話操作ではTransaction Poolerを第一候補にしません。

閲覧専用の分析tool

read-only DB roleを作り、必要なschemaとtableへだけSELECTを付与します。

PostgreSQLで接続するtoolでは、この方法がData APIより境界を説明しやすいです。

まとめ

Supabaseの用語を1つの「接続方法」として覚えません。

ブラウザとモバイルはData API、keyはPublishable key、行の境界はRLSで作ります。

サーバーの高権限処理はSecret keyまたは専用DB roleで行い、admin認証を別に設計します。

DB GUIとpgcliはPostgreSQL接続文字列を使います。

Direct、Session Pooler、Transaction Poolerは、clientの寿命とnetwork条件で選びます。

read-onlyはkey名ではなく、RLSまたはPostgreSQL権限で作ります。

参考資料