Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Supabase Meetup Tokyo #1 リードレプリカを利用した社内分析用リモー...

Avatar for TakashiAsanuma TakashiAsanuma
August 04, 2026
64

Supabase Meetup Tokyo #1 リードレプリカを利用した社内分析用リモートMCPを作ってみた

Supabase Meetup Tokyo #1 2026年8月5日 LTの資料です

Avatar for TakashiAsanuma

TakashiAsanuma

August 04, 2026

More Decks by TakashiAsanuma

Transcript

  1. やりたかったこと — 本番 DB(Supabase) を AI に読ませる Claude Code /

    Claude Desktop から、自然言語でデータを分析したい SQLを喋る MCP サーバを 1 本立てればいい話ですが… 本番 DB に AI を繋ぐのが怖い理由は 3 つ 1 書き込み事故 2 本番への負荷 AI が UPDATE / DELETE を 重い分析クエリが 撃たない保証をどう作るか サービスに影響しないか 3 誰でも繋がる URL を知られたら誰でも叩ける 社員でも見てよい範囲は違う → 1・2 は Read Replica で、3 は Supabase の OAuth App で解決 © Berry, Inc. 3
  2. アーキテクチャ全体像 ① 認証 — 誰が呼べるか(OAuth 2.1) Supabase(自社アプリ)= IdP Supabase Auth

    OAuth 2.1 Server・非対称(ES256) Claude Desktop / Code MCP クライアント OAuth 同意画面 メールドメインで社員限定 Access Token Hook 許可されたユーザーにだけ発行 ② クエリ実行 — 何を読むか AWS AgentCore Gateway inbound JWT を検証 MCP エンドポイント Supabase(分析対象 DB) Lambda(コンテナ) run_query / list_tables / describe_table 接続情報は Secrets Manager から取得、実行ログは CloudWatch へ Read Replica 読み取り専用ロールで SELECT のみ 本番 DB からレプリケーション OAuth 層と DB 接続層を完全に分離 → IdP は自社 Supabase 固定のまま、接続先だけ差し替えられる © Berry, Inc. 4
  3. レプリカと読み取り専⽤ロール — 書き込みを構造的に不可能にする 本番 DB は触らせない。 レプリカに、権限を削り切ったロールで繋ぐ ロールは強い属性を全部落として作る CREATE ROLE

    analytics_role LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOBYPASSRLS NOREPLICATION CONNECTION LIMIT 5; ALTER ROLE analytics_role SET statement_timeout = '120s'; GRANT USAGE ON SCHEMA public TO analytics_role; SUPERUSER / BYPASSRLS / REPLICATION を持つ逸脱状態は、マイグレーション で RAISE EXCEPTION して落とす( fail-loud) 実際の効き方 1 レプリカは物理 read-only cannot execute UPDATE in a read-only transaction 2 GRANT は SELECT だけ permission denied for table (SQLSTATE 42501 ) 3 接続数と実行時間に上限 CONNECTION LIMIT 5 / statement_timeout 120s 肝は BYPASSRLS を付けないこと。 付けた瞬間、この後の RLS 設計が全部むだになる。 © Berry, Inc. 5
  4. RLS はロール束縛で分ける — 既存ポリシーを 1 ⾏も触らない 既存の RLS を 1

    行も触らずに、分析ロールにだけ別の可視性を与える なぜ既存に影響しないのか -- 既存(アプリ用): 1 行も触らない CREATE POLICY "members can read" FOR SELECT TO authenticated USING (has_role(...)); • Postgres は current_user に一致するロールのポリ シーだけを評価する → 既存 authenticated のポリシーもクエリプランも不変 • auth.uid() 前提のヘルパーは分析ロールでは使えない -- 追加(分析用):ロール束縛で別ポリシー CREATE POLICY "analytics can read all" AS PERMISSIVE FOR SELECT TO analytics_role USING (true); → ロール名そのものを安全境界にする • USING (true) は定数畳み込みされる → RLS の性能鉄則(サブクエリでラップ)の対象外 新規テーブルは GRANT だけ自動で付く ポリシーは手動なので、付け忘れても 0 行が返るだけ(エラーではない)。 ただし fail-safe が成立するのは、そのテーブルで RLS が有効な場合に限る © Berry, Inc. 6
  5. 列レベル GRANT — テーブル単位では⾜りなかった 「AI に SELECT * を打たせない」ではなく、 「打っても返らない」ようにする

    テーブルごと落とす 列だけ落とす 機微な情報を持つテーブルは、GRANT もポリシーも付けずにループから 除外する。 読ませたいテーブルの中に利用させたくない列がある場合は、列レベル GRANT に分岐する。 SELECT * FROM secrets; GRANT SELECT (id, name, created_at) ON organizations TO analytics_role; ERROR: permission denied for table secrets SELECT * FROM organizations; -- 拒否 SELECT id, name FROM organizations; -- OK → そもそも存在を意識させない。忘れても安全側 → 除外列を含む SELECT * は、テーブルごと拒否される テーブル単位 GRANT のテーブル 列限定 GRANT のテーブル 新しい列はその瞬間から見える。機微な列を足すときは要注意 新しい列は見えない。安全側だが、分析で使うなら GRANT の追従が必要 © Berry, Inc. 7
  6. IdP としての Supabase OAuth — 外部 IdP は要らなかった 思い込んでいたこと 実際どうだったか

    リモート MCP を OAuth で守るなら、 IdP 自社アプリの Supabase Auth が、そのま を用意しないといけない ま IdP になった • Auth0 を契約する? Supabase Auth の OAuth 2.1 Server • Cognito を立てる? 有効化するだけ • Okta? Keycloak? MCP 1 本のために、 IdP を 1 つ増やすのか … © Berry, Inc. • 外部 IdP の契約・構築コストがゼロ • 利用者は既存の 自社アプリ用 アカウントでログイン • Claude Desktop からログイン → 同意 → 接続完了 8
  7. Supabase OAuth App の設定は 4 ステップ Supabase 側でやることは 4 つだけ

    1 2 3 4 OAuth 2.1 Server を有効化 JWT 署名鍵を 非対称鍵に切替 Claude を OAuth App 登録 MCP ホスト側に 設定を渡す Dashboard → Authentication。 ES256 / RS256 へ。 redirect URI は完全一致。 discovery URL と audience を ベータ機能・全プラン無償 ここを忘れると検証が通らない DCR でも手動でも可 JWT オーソライザへ MCP ホストに渡すのは、この 2 本の URL だけ discovery : https://<project-ref>.supabase.co/auth/v1/.well-known/openid-configuration jwks : https://<project-ref>.supabase.co/auth/v1/.well-known/jwks.json ※ 外部 IdP を使う場合と設定項目は同じ。IdP が自分のプロジェクトになるだけ © Berry, Inc. 9
  8. まとめ レプリカ + RLS はロール束縛 IdP は Supabase の 権限を削ったロール

    機微は列レベル GRANT OAuth 2.1 Server 書き込みは物理と権限の二重で不可能 既存ポリシーを 1 行も触らずに、分析専 外部 IdP なしでリモート MCP を OAuth BYPASSRLS を付けないのが肝 用の可視性だけを足せる 化できる 権限は Supabase、実行は AWS 誰に出すか( OAuth・同意画面・Access Token Hook)と、何を見せるか(レプリカ・ロール・ RLS・列 GRANT)は、すべて Supabase 側で決まる。 AWS (Gateway / Lambda / Secrets Manager)は、それを検証して実行する器で、載せ替えが効く。 © Berry, Inc. 10