GateKeeper, Conftestと組み合わせて使う

https://www.openpolicyagent.org/docs/latest/policy-language/ Playground もある

わかりやすいページ Policy as Codeを実現する Open Policy Agent / Rego の紹介 - ISID テックブログ

Open Policy Agent (OPA)は、ポリシーベースのアクセス制御を提供するオープンソースのツールです。OPAは、REST APIやgRPCなどの形式でアプリケーションに統合され、アクセス制御の判断を行います。 OPAは、自由なポリシーの表現力を持ち、柔軟で拡張性の高い設計が特徴です。OPAのポリシーは、Regoという言語で記述されます。Regoは、JSONを基にしたデータ構造を扱いやすい形式で表現することができ、複雑なポリシーの表現が可能です。 様々なサービスのポリシー設定を同じ言語(Rego)で表現することができます。

Gatekeeper は、KubernetesにおけるOPAの実装の1つで、Kubernetesのポリシー管理を自動化するためのコントローラです。Gatekeeperは、OPAを使用して、Kubernetesのリソースやマニフェストを検証し、ポリシーに従わない場合は拒否することができます。

Conftestは、OPAのツールの1つで、設定ファイルやマニフェストなどの構成ファイルの検証を行うことができます。Conftestは、OPAの言語であるRegoを使用して、構成ファイルに対するポリシーを記述します。

書き方

package example
 
deny {
    input.user == "admin"
}

input は、Rego言語で用意されている予約語の一つで、アクセス制御の評価時に与えられる入力オブジェクトを表します。入力オブジェクトの構文は決まっておらず、アプリケーションによって異なります。つまり、inputオブジェクトは、アプリケーションの入力に応じて、動的に構築されることが多いです。

このルールは、input.user が”admin”である場合に、denyを返します。このルールを実行するためには、inputオブジェクトが与えられる必要があります。例えば、以下のような入力を与えることができます。

{
    "user": "admin",
    "resource": "some-resource"
}

OPAの言語仕様において、denyallowは予約語ではなく、ルールの名前として使用されます。これらのルール名には、アクセス制御の判断を行うために、denyallowが一般的に使用されますが、任意の名前を付けることができます。

package example
 
allow {
    input.user == "admin"
}
package example
 
deny_my_rule {
    input.user == "admin"
}

Conftestでは、アサーションの結果をdenyallowで表現することができますが、これらはOPAのルールの名前として定義されているわけではなく、便宜的に使われているものです。Conftestは、Regoの言語仕様に基づいてルールを記述するため、denyallowの他にも任意のルール名を使用することができます。ただし、アサーションの結果をdenyallowで表現することが一般的であり、よりわかりやすいコードを書くことができます。

OR条件

Conftestで || みたいにOR条件を書けないか調べたが、簡単にできなかった。 同名の関数を複数用意することで、OR条件とできるらしい


deny[msg] {
    inRange(input.index)
    msg := sprintf("indexは1~99の範囲を指定する %v", [input.index])
}

inRange(v) {
    v >= 1
}
inRange(v) {
    v < 100
}