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

Ninka

Ninka を使うと、認可をコードではなく仕様として扱えます。

いま何が起きているか

AI にアプリケーションを書かせると、認可の決まりは条件文になって出てきます。 if (user.role === "admin") のような行が、いくつものハンドラに散らばります。 一つずつを見れば、どれも正しく見えます。それが 40 箇所になった時点で、 「このアプリは今どこまで許可しているのか」を言い切れる人がいなくなります。

これはコードの品質の問題ではありません。レビューの対象がコードである以上、こうなります。

代わりに何を書くのか

Ninka では、1 つの認可ポリシーを 1 つの小さな JSON にします。これを 手形 (Tegata) と呼びます。

{
"tegata": "0.1",
"policy": { "id": "invoice-access" },
"rules": [
{
"id": "allow-employee-view-invoice",
"effect": "allow",
"subject": { "roles": ["employee"] },
"actions": ["view"],
"resource": { "type": "invoice" }
}
]
}

「従業員は請求書を閲覧できる」。ルールはこれだけです。人間がレビューするのはこの JSON で、 生成されたコードではありません。

これをコンパイルすると、アプリケーションからは 1 行で呼べます。

const allowed = authz.check(policies.invoiceAccess, input);

決まりの中身は、アプリケーションのコードのどこにも現れません。

Ninka が保証すること

承認したものが動きます。 人がレビューした手形と、実際に動くバイト列は、ハッシュの連鎖で つながっています。同じ手形を同じ Ninka のリリースでコンパイルすれば、Rego は毎回バイト単位で 同じものが出ます。

勝手に補いません。 コンパイラは推測しません。AI エージェントが要件を解釈した箇所は手形の 中に記録されますし、新しい role は diff に現れないままポリシー集合へ入れません。

分からないときは閉じます。 入力が欠けても、許可が広がることはありません。値が欠けた allow ルールは成立せず、値が欠けた deny ルールは発火します。属性を送らないでおけば禁止をすり抜け られる、という抜け道はありません。入力が欠けているとき を参照してください。

どこからがアプリケーションの仕事か

Ninka は認可サーバではありませんし、承認ワークフローの製品でもありません。OPA を使うのは WASM を build する工程だけで、リクエストの処理には入りません。判定はアプリケーション自身のプロセスで走ります。

いつ判定を呼ぶか、どのリソースについて聞くか、入力をどう組み立てるか、返ってきた答えをどう扱うか。 これらは引き続きアプリケーションの責任です。

次に読む