iKonekt
コンソールを開く

分離

コードではなくデータベースが守る境界線

すべてのCRMがマルチテナントを標榜しています。その主張は安価です。重要なのは、どの層が境界を守っているかです。答えが「アプリケーションが常に正しいフィルタを追加する」であれば、その保証は、クエリを書いたことのある最も疲れていない開発者と同じ程度の強さしかありません。

iKonektは最初のマイグレーションからマルチテナントであり、後から付け加えたものではありません。自慢のように聞こえますが、実際は告白です。後付けで納得できる形にするのはほぼ不可能であり、試みた人全員がそれ相応の話を持っています。

分離はデータベース内にあります。26個のテーブルすべてが、属するテナントを保持しており、それを検証するポリシーは、アプリケーションより完全に下の層で、すべての読み取りと書き込みのたびに実行されます。境界を忘れたクエリは、他人の顧客を返しません。何も返しません。

行レベルセキュリティ、強制適用

慣習でも、コードレビューのルールでもありません。データベースが拒否します。72個のポリシーは、生成ではなく一つずつ手で書き出されています。生成されたポリシーは、誰も読んでいないポリシーだからです。

複合キー

子レコードはテナントと親をペアとして一緒に参照します。別の会社の迷い込んだ識別子は解決されません。単に無効な参照として扱われます。

デフォルトテナントは、決して存在しない

スコープのないリクエストが、静かにテナントゼロへのリクエストに変わることはありません。データベースに到達する前に例外を投げます。「スコープなし」モードは存在せず、付け忘れることもできません。

自分を主張できなかったバグ

テナント分離の作業を進めていた間、ほとんどのミスは大きな音を立てました。二つの会社に同じ顧客ドメインを与えれば、データベースはエラーコードとスタックトレース付きで即座に拒否します。昼食前には修正が終わります。

一つだけは、拒否しませんでした。編集可能なプロンプト上書きのテーブルが、プロンプトの種類だけをキーにしており、種類とテナントではなかったのです。二つ目の会社が自分のコピーを編集すると、完全に有効なSQLを通じて、エラーも警告も失敗するテストもなしに、静かに一つ目の会社のものを上書きしていました。キーを変更した後、残りのすべての一意インデックスを一つずつ読んで確認したことで発見されました。大きな音を立てるものに仲間がいるのではないかという疑いからでした。

これを述べるのは、これがこの仕事の正直な姿だからです。分離はスイッチを入れる機能ではありません。スキーマの退屈な部分を、そこに自分と食い違う何かがあるという前提で読み続ける習慣なのです。

念のため、テストの話を:942件あり、変更のたびにゼロから再構築されたデータベースに対して実行されます。設計の賢さを証明するためのものではありません。この設計の失敗モードは静かであり、静かな失敗には代わりに叫んでくれる人が必要だからです。

分離が普通の人にもたらすもの

  • 一つのグループが一つのインストールで複数の会社を運営でき、ある会社の営業担当が別の会社の顧客を見ることは決してありません。ポリシーによってではなく、構造によって。
  • パートナープログラム、プロンプトのセット、顧客への請求権。すべて会社ごとにスコープされるため、あるテナントの設定が全員のものになることはありません。
  • 消去要求は共有の山を横断するのではなく、境界の中で履行されます。それが正直に答えることを可能にするのです。
  • そして誰も何も覚えておく必要がありません。それこそが要点です。覚えていられることに依存する保証は、保証ではありません。

データベースとは関係ない、もう一行

ファミリー内のすべての兄弟サービスは、それぞれ固有の名前付き認証情報を持ちます。共有の認証情報で通信するものはなく、あるサービスが誤って別のサービスとして振る舞うことはできません。かつて共有トークンを使って苦労した経験から直接生まれた、小さな規律です。

これはデータベースのルールと同じ発想です。間違ったことを禁止し、単に推奨しないのではなく不可能にする。そうすれば、警戒心ではなく顧客に注意を向けられます。

境界線アプリケーションの下に
  • 126テーブルすべてがテナントを持ち、チェックは強制されています。
  • 272ポリシー一つずつ手で書き出されているため、すべて人が読んでいます。
  • 3942件のテスト変更のたびにゼロから再構築されるデータベースに対して。
  • 4デフォルトテナント0スコープのないリクエストがデータに到達することはありません。

本番ビルドで測定

「うちのアプリは常に会社でフィルタしています。」

その文の「常に」は、かなり重い荷物を背負っています。

境界線をデータベースまで下げれば、書き忘れたWHERE句は他人の顧客ではなく何も返しません。空の画面は、気まずい自己紹介より良い失敗です。

複数ブランドを運営するグループへ →