SAG / ARCHITECTURE NOTE
マルチテナンシーとRLS:顧客データの境界を設計する方法
複数の組織が1つのサービスを利用しながら、データや権限が混在しないように、テナント境界、サーバー権限、RLSを組み合わせて設計する原則を解説します。
マルチテナンシーは画面の区分ではなく、データに関する契約です
サブスクリプション型サービスでは、複数の顧客組織が同じアプリケーションとデータベースを利用します。このとき、画面に組織名を表示するだけでは、分離は実現できません。すべての読み取りと変更について、どのテナントからのリクエストなのかを確認し、権限のない行にはデータベースの段階でもアクセスできないようにする必要があります。
SAGでは、組織を表すテナントとユーザーの役割を分けて扱います。ユーザーがログインすると、サーバーがセッションとメンバーシップを確認し、リクエストされたリソースがそのテナントに属しているかを検証します。ブラウザーから送信された組織識別子を、そのまま信頼することはありません。
サーバー権限とRLSを併用する理由
サーバーでの権限チェックでは、業務ルールを理解しやすく、明示的に表現できます。RLS(Row Level Security)は、クエリに誤りがあっても他の組織の行が露出しないよう、データベース側でもう一段境界を設けます。両方の層を併用することで、一方のチェック漏れが直ちに顧客データの露出につながる可能性を抑えられます。
主な原則は次のとおりです。
- テナントが必要なテーブルには、明確なテナント識別子を設けます。
- 読み取りと書き込みの両方に、同じ所有権の検証を適用します。
- プラットフォーム管理者と顧客運用担当者の権限を分離します。
- 監査ログには、誰がどのリソースを変更したかを記録します。
- APIキーやパスワードなどの秘密値は、通常の運用レコードに保存しません。
共有データと顧客専用データを区別する
競合他社のドメインのように、複数の顧客が観測できる対象もあれば、顧客からの質問・改善案・承認記録のように、組織ごとに保護すべきデータもあります。前者を無条件に複製すると運用コストが増大し、後者を安易に共有するとセキュリティ上の問題につながります。SAGでは、まずデータの所有権と公開範囲を定義し、その後に保存構造を決定します。
検証すべき失敗シナリオ
正常な読み取りが成功することを確認するだけでは不十分です。他のテナントのIDを指定したときに404または権限エラーになるか、権限の低いユーザーが変更APIを呼び出せないか、古いバージョンで上書きしようとした際に競合を検知できるかまで確認する必要があります。データ境界は文書に記された約束ではなく、繰り返し実行できるテストによって証明される運用上の条件です。
RLSが適用される実行ロールまで確認する
RLSポリシーがあっても、テーブル所有者やBYPASSRLSロールはポリシーを回避できます。SAGでは、これとは別にサーバー側のメンバーシップとテナント条件のチェックを維持します。分離の範囲を判断するには、データベース接続ロールとポリシーの適用状況をあわせて確認する必要があります。
トピック別の技術資料
この技術についてさらに読む
テナント権限、ジョブの再試行、キャッシュ、承認履歴について確認します。
SAG / KNOWLEDGE LINKS
