Regoの基礎(PolicyとData)
この記事はOPA/Regoアドベントカレンダーの4日目です。
今回はOPA内で利用される "Policy" と "Data" の概念について説明します。
OPAのドキュメントモデル
OPAは一部の説明において、内部であつかう構造化データのことを抽象化して "Document" と呼んでいます。 "Document" はいわゆるDocument oriented database(例: mongo DB)が由来で、スキーマレスな構造化データという意味で利用されています。OPAの説明ではこの "Document" が "Data" とほぼ同義として扱われています。
ドキュメントの種類
Documentも2種類あり、"base document" と "virtual document" に分類されます。
base document
最初からデータの形でOPAに入力されたドキュメントです。base documentはAPIで事前にOPAへ渡されていたり、OPAサーバが起動時に渡されているデータセットになります。位置づけとしてはOPAでなんらかの判定をする際、利活用できるデータであることが期待されます。例えばユーザのロールをベースに認可の判定をしたい場合、どのユーザがどのようなロールを持っているか? というリストをbase documentとしてOPAサーバ内で管理します。
base documentとしてもう一つ重要なのは input
という特殊なドキュメントがあることです。先程の例のbase documentは頻繁に変更しないことを想定していますが、 input
は判定を行うたびに異なるデータが入ってくるという想定で利用されます。
input
とその他のbase documentはどちらもAPIから操作可能であるため、似たような使い方はできてしまいます。ただし処理に違いがあり、OPAサーバ内でinput
は同期的に、その他のbase documentは非同期的に読み込まれる、という特徴があります[1]。そのため、判定の都度異なる入力(例えば認可の判定をしたいリクエストの詳細)は input
で渡すほうが望ましく、使い分けが必要になります。
virtual document
一方、virtual documentについて一言で説明すると「base documentおよびPolicyによって生成されたdocument」となります。ここで言うPolicyとは、Regoで書かれた判定のためのロジックになります。Policyはパッケージという概念で分割され、OPAは同時に複数のパッケージを読み込んで動作できます。
Policyもbase document同様に(API経由などでadhocに変更は可能なものの)頻繁に更新されることは想定されていません。そのため、base documentが変更されなければ常に同じvirtual documentが生成されますが、 input
によって都度異なるデータが入力されそれをPolicyが参照することで、都度異なるvirtual documentが生成されます。
したがって、OPAの基本的な使い方としては、
- 利用者が
input
によって判定したいデータ(リクエスト、イベント、何かの結果、等)をOPAにわたす - OPAが
input
を含むbase document + Policy をもとに virtual document を計算する - 利用者が計算結果として得られた virtual document を参照する
という流れになります。
ドキュメントの関係
ここまでの説明を図に表すと、以下のようになります。
Policy は base document および他の Policy が生成した virtual document を参照することができます。Document (data) は input
を除いたすべての base および virtual document が data.*
という接頭語で扱えるようになっています。base documentの命名規則については追って解説しますが、パッケージに関しては data.<パッケージ名>
となります。これによって Policy はパッケージとして分割した管理をしつつ、互いを組み合わせて利用することができます。
ただし循環するようなルールは使えません。上記例だと data.example.mypolicy2
を example.policy1
パッケージが参照しようとするとエラー扱いになるので、Policy 間の依存関係については注意が必要です。
まとめ
PolicyとDataはそこまで複雑な概念ではありませんが、最初はPolicyの結果がどのように扱われるのかがわからずやや混乱をきたすため、解説をまとめてみました。次回以降はより具体的な記述の方法について紹介していきたいと思います。
Discussion