「RLS」と「マルチテナント」は、この主題に関してすでに公開されているほぼすべてのコンテンツで隣り合って見られます。これは、多くの SaaS アーキテクチャにとって正当な選択ですが、Aurabase が独自のクライアントを互いに分離するために選択したものではありません。この投稿では、簡略化したマーケティングの説明ではなく、実際のプロビジョニング エンジンと実際に適用される RLS ポリシーとの違いについて説明します。 Aurabase のマネージド Postgres エンジンが分離を超えてカバーする内容の概要については、データベースドキュメントを参照してください。
必需品
- プロジェクト間では、Aurabase は RLS 単独ではなく、専用の Postgres ベースによって分離します。各プロジェクトは、専用の CNPG クラスター (企業レベル) または独自の組織 (フリー/プロ/チーム) の CNPG クラスター上に独自の物理ベースを持ち、他の組織と共有されることはありません。
- RLS (
auth.uid()、auth.role()、auth.jwt()) はアクティブなままであり、独自のユーザーを分離するために、 の ベース内に置くことをお勧めします (Supabase と同じ規則)。 service_roleおよびプロジェクト ベースの管理ロールは、設計により RLS をバイパスします (BYPASSRLS)。これは、サーバー操作のための想定されるアーキテクチャ上の選択であり、欠陥ではありません。- このリポジトリですでに修正されている回帰 (古い共有スキーマで誤って付与された
PUBLIC権限) は、ベース レベルの境界が純粋なアプリケーション境界よりも耐性がある理由を具体的に示しています。
ほとんどのマルチテナント RLS ガイドが使用するショートカット
マルチテナント Postgres の最も文書化されたパターンは、単一のベース、各テーブルの tenant_id 列、この列を JWT から抽出された値と比較する RLS ポリシー の 3 行で構成されます。これは経済的であり、接続のプール、ダイアグラム、実行する単一のインスタンスが必要であり、テナントが多数で小規模で、個々のステークが低い場合にうまく機能します。
この妥協は現実のものです。2 つのクライアント間の境界は、テーブルごとに評価される SQL 式になります。新しいテーブルで忘れられたポリシー、スーパーユーザー ロールで実行されている接続、ライブで起動されたデバッグ スクリプト。これらの各インシデントは、操作上はどんなに些細なものであっても、すべてのテナントの行を同時にサイレントに公開する可能性があります。したがって、セキュリティ境界と技術境界 (基礎) はまったく同じものになります。
これ自体は悪い選択ではありません。多くの製品にとっては正しい妥協策です。この投稿の要点は別のところにあります。これは、Aurabase が独自のクライアント (異なるコンプライアンス要件を持つ可能性のあるプロジェクト全体) を相互に分離するために行った妥協ではありません。
2 つのアーキテクチャ、プロジェクト間でベースが共有されることはありません
最近のプロビジョナーの統合 (コード内で「タスク 12」としてマークされている) 以降、Aurabase のアクティブな Postgres プロジェクトは、正確に 2 つのアーキテクチャに分類されます。実際に複数のプロジェクト間でベースを共有する古いモデルは、プロビジョニング パスから削除されました。
プロジェクト レベルによって、2 つのどちらが適用されるかが決まります。そして、それを決定するのはコードであり、ダッシュボードでチェックされたボックスではありません。
| 寸法 | 完全専用(企業) | SharedClusterD dedicated (無料/プロ/チーム) |
|---|---|---|
| CNPGクラスター | この一つのプロジェクトに捧げます | 共有されますが、2 つの組織間では共有されません |
| Postgresデータベース | アプリ、それに投影するだけ | project_<uuid>、クラスター上のプロジェクトごとに 1 つ |
| PostgreSQL ログイン | クラスター上の単一プロジェクト: クロスメンバーシップのリスクなし | プロジェクトごとにログイン (F-013)、その唯一のロールのメンバー tenant_<uuid> |
どちらのアーキテクチャでも、ベースまたはクラスターが 2 つの異なる組織をホストすることはありません。したがって、問題は「データが分離されているか」ではなく、「プロジェクトが CloudNativePG をすべて単独で計算しているか、それとも同じ組織内の他のプロジェクトと共有しているか」です。
この 2 つのアーキテクチャの統合は最近行われたものです。コードには、以前は 2 つの追加パスが含まれていました。それは、複数のプロジェクトが同じデータベース内に共存し、図によってのみ分離されている「共有マスター」と、postgrest_dedicated_shared_dbバリアントです。専用の移行によりこれらが削除され、projects テーブルの制約が残りの 2 つの値のみに強化されました。これは、まさに共有スキーマ モデルが以下で説明するバグの原因であったためです。
専用ベースが顧客間で共有される EPIRB に勝る理由
別個の Postgres データベースは、行レベルの境界ではなく、接続レベルの境界です。プロジェクト A のデータベースに接続されているアプリケーション ロールは、プロジェクト B のテーブルにクエリを実行することはできません。プロジェクト B に対して開いているセッションがありません。この特性は、RLS ポリシーの記述が不十分である場合、テーブルにない場合、または上位ロールによってバイパスされた場合でも当てはまります。最悪のケースは単一データベース内に限定されます。
この堆積物には実際のバグの痕跡もあり、これは逆のリスクを示しています。古い共有スキーマ モデル (廃止以降) では、provision_postgres_schema が誤って各プロジェクト スキーマに GRANT ALL ... TO PUBLIC 権限を付与しました。PUBLIC はメンバーシップ条件なしでデータベース内のすべてのロールに適用され、プロジェクトごとに分離されたログインが別のスキーマで読み書きできる可能性がありました。修正移行 (066) により、これらの権利が既存の権利から削除されました。
このパッチでは、リークを塞ぐための RLS ポリシーがもう 1 つ追加されませんでした。2 つのプロジェクトがデータベースを共有する可能性自体が排除されました。現在の 2 つのアーキテクチャについては、provisioning.rs からのコメントが白黒はっきりと文書化しています。「各プロジェクトにはすでに独自の物理 Postgres データベースがあります。」基本レベルの境界により、すべてのポリシーが常に正しく記述されていることに依存するのではなく、そのようなバグのクラス全体が単純に到達不能になります。
2026 年 8 月 23 日のパッチも同じ方向です。プロビジョナーによって無条件に配置された REVOKE ALL ON SCHEMA public は、古い共有データベース モデルで実際の分離のみを提供するため、トポロジに条件付きになりました。現在の 2 つのアーキテクチャでは、 public.<table>を明示的に参照する SQL ダンプのインポートを利益なしにブロックしました。
EPIRB はユーザーのためにデータベース内に常駐します
上記のいずれによっても EPIRB は役に立たなくなります。単にフロアが変更されるだけです。 プロジェクトデータベースに入ると、Aurabase は、 Supabaseによって採用された PostgREST 規約を正確に公開します。 request.jwt.claimsのゲートウェイによって設定された JWT クレームを読み取る 3 つの SQL 関数です。
これらのヘルパーは、単に文書化されているだけではなく、Aurabase 自体の実際のポリシーで使用されます。リポジトリに配置される storage_objectsを保護するポリシーを次に示します (読み取り用に数行に再フォーマットされます)。
アプリケーションテーブルを運ぶ独自の project_<uuid>スキーマでは、Aurabase はユーザーに代わってポリシーを意図的に配置しません。コードはそれを「Supabase モデル」として文書化します。テーブルの RLS は、同じ関数、同じ構文を使用して、引き続きユーザーの責任になります。
service_role は RLS をバイパスします — 偶然ではなく仕様です
Postgres はネイティブで ロール属性、 BYPASSRLSを提供しますが、これはすべてのポリシーを無視します。 Aurabase は、これを 2 つのロールファミリーで自発的に使用します。 aura_service_role (サーバーロール、ブラウザ側では公開されません) と、 ALTER SCHEMA ... OWNER TOなどの DDL 操作中に使用される、各プロジェクトに固有の管理ロールです。
リクエストを処理するロール anon/authenticated — tenant_<uuid> — には BYPASSRLSがありません。RLS は例外なく通常どおり適用されます。ボーナスとして、各プロジェクトに固有のシステム ダイアグラム (_auth、 _storage、 _platform) は、ポリシーなしでアクティブ化された RLS を受け取ります。 したがって、バイパス以外のロールはデフォルトで完全に拒否され、アプリケーション パスがある日誤ってアクセスした場合に備えて多層防御になります。
昇格されたサーバーロールによる RLS のバイパスは、Aurabase に固有のものではありません。これは、Supabase 側の service_role と同じ構造です。重要なのは、 BYPASSRLSを避けることではなく、クライアントからアクセスできるロールには決して付与せず、単一のプロジェクトに限定することです。
このサーバーの役割は、事前定義された役割、カスタム RBAC、監査ログなど、より広範な体制の一部であり、セキュリティと RBACページで詳しく説明されています。
共有クラスターでは、データベースがすべての作業を単独で実行するわけではありません
SharedClusterDedicatedレベルでは、同じ組織の複数のプロジェクトが単一の CNPG クラスター上に共存します。物理データベースはすでにプロジェクトを相互に分離していますが、PostgreSQL ロール (それら) はデータベースではなくクラスターにとってグローバル オブジェクトです。したがって、Aurabase はレイヤー、つまりプロジェクトごとに個別の PostgreSQL ログインを追加します。
各プロジェクトは独自のログインで接続し、その独自の tenant_<uuid> / tenant_<uuid>_admin ロールのメンバーのみを使用します。同じクラスター内の別のプロジェクトのメンバーではありません。データベースはすでにデータを分離しています。このプロジェクトごとのログインでは、プロジェクトに接続する ID も分離されるため、プロジェクト上のインシデントによってそのログインに別のメンバーに継承されるメンバーシップが付与されることはありません。
RLS 単独か専用ベース: 独自の SaaS を決定する方法
Aurabase の選択は普遍的なルールではありません。これは、クライアントが制御できないプラットフォーム上で、潜在的に異なるコンプライアンス要件を持つクライアントを相互に隔離するという、特定のケースに対する妥協です。独自の SaaS を構築している場合、異なるスケールで同じ疑問が生じます。
- 共有ベース内の
tenant_idを使用した RLS — テナントが多数で、個々のステークが低く、テナントごとのベースのコストが不釣り合いになる場合に関連します。例外なく、各テーブルでpg_proveを使用して各ポリシーをテストします。 - 専用のベースまたは図 — テナントに独自のコンプライアンス問題 (健康、人事、公共部門) がある場合、パフォーマンスの分離を正当化するボリュームがある場合、または 2 つの特定のクライアント間のリークのコストが追加のインフラストラクチャのコストと不釣り合いな場合に関連します。
Aurabase の価格レベルは、これと同じ裁定を独自のクライアントに適用します。デフォルトでは組織によってベースが共有され、プロジェクトの課題が正当化される場合は専用クラスターが適用されます。独自のデータベース内の RLS パターン (所有権、組織別のマルチテナント、ロール階層) については、運用環境の RLS ガイド で、pgTAPテストを使用する 3 つのケースが詳しく説明されています。また、ダイアグラム上の自動生成された API が REST 以外にも興味がある場合は、pg_graphql と Hasura および PostGraphile の比較 は、Aurabase によって公開される Postgres サーフェスの残りの半分をカバーしています。