メインコンテンツまでスキップ

ポリシーを書く

新しいリソースの認可を追加する流れは、手形を書く、必要な語彙を宣言する、コンパイルする、生成された policy reference をアプリケーションから使う、の 4 段階です。

1. 手形を作成する

ninka/document-access.tegata.json を作ります。

{
"tegata": "0.1",
"policy": { "id": "document-access" },
"attributes": {
"subject.user_id": "string",
"resource.owner_id": "string"
},
"rules": [
{
"id": "allow-member-access-own-document",
"effect": "allow",
"subject": { "roles": ["member"] },
"actions": ["view", "edit"],
"resource": { "type": "document" },
"relationships": [
{
"label": "ownership",
"subject_attribute": "user_id",
"op": "eq",
"resource_attribute": "owner_id"
}
]
}
]
}

この relationship は subject.user_idresource.owner_id を比較します。relationship には型を推論できるリテラル値が無いため、この例では両方の属性型を attributes で明示しています。

手形全体の構造と評価規則は 手形スキーマ を参照してください。

2. 語彙を使っているプロジェクトでは、新しい語を追加する

ninka/vocabulary.json がある場合、そのプロジェクトの語彙は閉世界として扱われます。未宣言の role・action・resource type や、語彙で管理している属性を使うと、黙って新しい語として受け入れるのではなくコンパイルエラーになります。

この例なら、次のように宣言します。

{
"roles": ["member"],
"actions": ["view", "edit"],
"resource_types": ["document"],
"attributes": {
"subject.user_id": "string",
"resource.owner_id": "string"
},
"decision_log": { "unmasked": [] }
}

これにより、新しい role や resource type の追加が vocabulary.json の明示的な diff としてレビューに現れます。属性型や Decision Log の開示設定を含む詳しい仕様は 語彙 を参照してください。

3. コンパイルする

npx ninka-authz compile

スキーマと関所の検査に通ると、Ninka は手形から導かれる成果物を ninka/out/ に書き出します。OPA toolchain を利用できる場合は、実行用の WASM も build し、その WASM に対して生成された validation を実行したうえで Consumer Projection を生成します。新しいポリシーは、この Consumer Projection の policies に現れます。

OPA を利用できない場合でも、通常の compile は WASM を必要としない成果物までは生成し、bundle の build をスキップしたことを報告します。実行 bundle の生成を必須にしたい CI などでは ninka-authz build を使います。

生成されるファイルの詳細は 生成ファイル を参照してください。

また、次を実行すると現在のポリシーを読み取り専用の Authorization Reference で確認できます。

npx ninka-authz docs

4. 生成された policy reference を使う

ポリシーを別途登録する作業はありません。Consumer Projection が生成されると、policies からpolicy idを導出した名前(ハイフンを取り除いたcamelCase)で参照できます。

authz.check(policies.documentAccess, input);

生成された reference は policy id とそのポリシーの入力契約を結び付けます。TypeScript では、存在しない id を指定したり、別ポリシー用に生成された入力型を渡したりする誤りを、手書きの認可ロジックへ持ち込む前に型チェックで検出できます。

一方、Ninka インスタンスをどこで作るか、具体的な入力をどう組み立てるか、どこで認可判定を呼ぶか、返された判定をどう適用するかはアプリケーション側の責任です。詳しくは ランタイム API を参照してください。

関連項目