Demesne

Fóirが動作する基盤となる認可エンジンです。アクセスルールは1つの仕様ファイルに一度だけ記述し、DemesneがそれをPostgresの行レベルセキュリティにコンパイルするため、データベースがすべてのクエリにルールを適用します。Fóirのために開発し、Apache 2.0ライセンスで公開しています。

できること

Demesneの仕様は4つの事柄を記述します。テナンシーの構造、操作を行うユーザーと認証情報の種類、操作の対象となるテーブル、そしてそれらをつなぐリレーション(所有権、ロール、共有、グループメンバーシップなど)です。

コンパイラはこのファイルから、行レベルセキュリティのポリシーと、そのポリシーが呼び出すデータベース関数を生成します。あわせて、行に関するものではない問い(「このユーザーは公開できるか」など)のためのGoとTypeScript向けの権限マップと、セッションが持つべきクレームも生成します。仕様を変更して再生成すれば、データベースとアプリケーションのコードが一緒に更新されます。

ルールがデータベースにある理由

認可は通常アプリケーションのコードにあります。呼び出すサービスであったり、リクエストハンドラーに散らばったチェックであったりします。いずれの場合も、守られるのは確認を忘れなかった経路だけです。バックグラウンドジョブ、新しいエンドポイント、データベースのコンソールに入力したクエリは、それを迂回します。

Demesneは判断をデータそのものに置きます。同じポリシーが、どのコードが送ったかにかかわらずすべてのクエリを絞り込むため、確認を忘れた経路でも、呼び出し元に許可された行だけが返ります。

コンパイラを書いた理由

行レベルセキュリティはルールを置くのに適した場所ですが、手で書くには厄介です。マルチテナントのプロダクトには、所有権、ロール、入れ子のグループ、共有がすべてのテーブルにわたって必要で、これらのパターンは微妙な間違いを起こしやすいものです。

Demesneと同じモデルを共有するエンジン、つまりGoogleのZanzibarやそれに続くオープンソースのプロジェクトは、別のサービスとして動作します。アプリケーションは判断のたびにそのサービスを呼び出し、リレーションシップのコピーをデータと同期させ続ける必要があります。私たちはサービスなしでモデルを使いたいと考え、Demesneのルールがクエリと同じトランザクション内で既存のテーブルを読むようにしました。

出力の検証方法

Demesneのビルドは、生成されたすべてのファイルを、コミット済みのコピーとバイト単位で比較します。アプリケーション側の各権限チェックには、対応するポリシーの条件がそのまま含まれているため、コードがデータベースからずれるとビルドが失敗します。テストスイートは実際のPostgresに対して実行され、生成された関数をインストールして、SQLがGoとTypeScriptの版とケースごとに一致することを確認します。

すでにデプロイ済みのデータベースでは、demesne diffが、仕様と稼働中のポリシーとの差分をすべて報告します。

オープンソースである理由

誰がデータを読めるかを決めるコンポーネントは、自分で確認できるべきものです。どのプラットフォームでも、テナントは分離されていると言えます。Demesneでは、私たちのポリシーを書き出すコンパイラ、それが通らなければならないテスト、生成されるSQLを読むことができ、そのすべてを自分で実行できます。

Demesneには、Fóir固有のものは何もありません。任意のPostgresデータベースで動作し、お使いのサインインプロバイダーが発行するセッションを読み取ります。リポジトリのガイドでは、既存のスキーマに導入する手順を説明しています。私たちのプラットフォームに関心のないチームでも使えます。これは、このモデルが通用するかどうかを確かめる、私たちの知る最良の方法です。

Fóirでの位置づけ

FóirのアクセスモデルはDemesneの仕様1つで構成され、執筆時点で約100のテーブルを管理しています。テストが私たちのスキーマ内のすべてのテーブルを列挙し、保護方法の決定が記録されないまま追加されたテーブルがあれば失敗します。

レコードの所有者や、どのロールがどのモデルを読めるかといった、プロジェクトに設定するルールは、これらのポリシーが読み取るデータです。そのためデータベース内でも有効になります。データベースでの強制では、ポリシーがどのように生成され、強制され、テストされるかを説明しています。

手元に残るもの

プロジェクトのPostgresエクスポートには、各ユーザーがどの行を読めたかを再現する行レベルセキュリティのポリシーが含まれており、お客様が所有することになるデータベースにそのまま適用できます。モデル全体を自社のインフラで動かしたい場合は、利用を認めるライセンスの下でエンジンを使えます。

向かない場面

DemesneはPostgres専用です。ライブラリとコマンドラインツールであり、呼び出すホスト型サービスはありません。すべてのルールをSQLの条件として表現できる必要があり、逆向きの問い(「このレコードを見られるのは誰か」)には保守的に答えます。リポジトリには、Zanzibar、Ory Keto、OpenFGA、Cerbos、Osoとの比較が含まれており、それぞれがより適している場面を示しています。

自分で確かめる

仕様言語、生成されるSQL、テストスイートはすべてリポジトリにあります。