モジュール XX — マルチテナンシーと組織管理
モジュール XX はエンジンにぶら下がるサービスではない。それはエンジンそのものの 特性である。アタッチするための独立したテナンシーモジュールは存在しない。代わりに、 コアのデータモデルがあらゆるエンティティにテナント境界を持ち、ストアがすべての クエリの下でそれを強制する。このページは、その境界が今日保証していること、および 組織管理のうちまだ設計段階にある部分のリファレンスである。
マルチテナンシーは、プラットフォーム自身の API(モジュール XIX)と並んで Engine 層
(層 0)に存在する。なぜなら、稼働中のデータモデルに分離を後付けすることは、後から
安全に行えない類いの変更だからである。すべてのコアエンティティは tenant_id を
持ち、呼び出し側がそれを自由なパラメータとして渡すことは決してない。呼び出し側は
テナントを一度固定し、そのリポジトリがすでにそれにバインドされたスコープを
受け取る。テナントをまたぐための語彙は API に存在しない — その不在こそが、
いかなるデータベース機構よりも前にある最初の分離障壁である。特権的なクロステナント
スコープ(組織の作成、組織の一覧、テナントの削除)は、モジュールからではなく
エンジン自身の起動処理からのみ到達できる。
コントラクトとエンティティ
Section titled “コントラクトとエンティティ”テナントモデルは、モジュールごとのスキーマではなく、データモデルのコントラクトが
所有する。ルートエンティティは Org であり、これがテナントそのものである。
エンジンが組織をシードすると、その識別子がテナント識別子となり、組織自身の監査
チェーンが同じ瞬間に確立される。それ以外のすべてのコアエンティティ —
エージェント、セッション、リソース、アイデンティティ、ポリシー、コスト記録、
検出結果、デプロイメント、access map、audit ledger — は、テナントスコープの内側で
作成され、書き込み時にそのテナントが刻印される。呼び出し側はそれを上書きできない。
分離はクエリ層で、デプロイメントごとに強制される:
- PostgreSQL では、
tenant_idを持つ各テーブルがFORCE ROW LEVEL SECURITYの下で動作し、トランザクションごとにバインドされるtenant_isolationポリシーを持つ。テナントのバインドに失敗したトランザクションは、サイレントに ゼロ行を返すのではなくエラーを発生させる(フェイルクローズ)。また、 アプリケーションロールは非スーパーユーザーであり、BYPASSRLSを決して 持たない。そしてFORCEはテーブルのオーナーに対してもポリシーを拘束する。 オーナーシップはデプロイメントの選択である: デフォルトのシングルロール インストールでは、アプリケーションロールがデータベースのオーナーのままとなる — RLS は依然としてそれを拘束するが、オーナーは自身のテーブルを変更できるため、 このポスチャは owner-proof ではなく**改竄検知可能(tamper-evident)**にとどまる。 強い権限境界 — アプリケーションロールが非オーナーでもあること — は、オーナーと アプリを分割したトポロジーから得られる。分離された owner ロールが プロビジョニングを行い、アプリケーションロールは必要な DML のみを受け取る。 - SQLite(シングルノードのデプロイメント)には行レベルセキュリティがない。 同等の保証は次の 2 つの事実から得られる — データベースへの唯一の経路は、 常にテナント述語を付加するディスクリプタ生成 SQL であること、そしてトリップ ワイヤートリガーが、固定されたスコープと一致しないテナントへの書き込みを すべて中止することである。
起動時のセルフテストは、マイグレーション後にライブの分離ガードを問い合わせ、
tenant_id を持つテーブルのいずれかが保護されていない場合は、ストアを開くことを
拒否する — そのため、新しいテーブルのガードを忘れることは、サイレントな
漏洩ではなくブート失敗となる。
消費するものと生成するもの
Section titled “消費するものと生成するもの”モジュール XX はイベントバスの表面を持たず、アクチュエーションも持たない。
edge.observed を消費せず、検出結果を発行せず、いかなるプロバイダも呼び出さない —
それは他のモジュールが書き込みを通す基盤である。その唯一の観測可能な効果は構造的な
ものである。どのモジュールが永続化するエンティティもすでにテナントスコープ化されて
おり、監査対象エンティティへのすべての変更は、同一トランザクション内でそのテナントの
ハッシュチェーン化された audit ledger に追記される。
- モジュールカタログ — モジュール XX の位置と、その正直なアクチュエーション状態。
- アイデンティティ、権限とガバナンス — テナント内のロールと委譲された権限。
- アーキテクチャ概要 — エンジン層と一般的なデータモデル。
- イベントバスリファレンス — すべての変更が追記するテナントごとの audit ledger。
- 正直さと制約 — 今日構築されているものと設計段階のもの。