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 する工程だけで、リクエストの処理には入りません。判定はアプリケーション自身のプロセスで走ります。
いつ判定を呼ぶか、どのリソースについて聞くか、入力をどう組み立てるか、返ってきた答えをどう扱うか。 これらは引き続きアプリケーションの責任です。
次に読む
- クイックスタート:最初の認可判定を動かす。
- 手形 (Tegata):人間がレビューする認可仕様。
- 認可をレビューする:変更を受け入れる前に何を見るか。
- 認可コンパイラ:手形が動くバイト列になるまで。