ランタイム API
Ninka ランタイムの完全なリファレンスです。ランタイムは、コンパイル済みポリシーを読み込み、認可判断を
行うためにアプリケーションが使用する API です。判断は WASM によりインプロセスで実行されます。ネット
ワークも、リクエスト経路上の opa バイナリも、クラウドもありません。
インポート
import { Ninka, type AuthzInput, type DecisionLogEntry } from "ninka-authz/runtime";
ninka-authz/runtime からエクスポートされるもの: クラス Ninka と、インターフェース AuthzInput、
InputValidationError、DecisionLogEntry、DecisionLogOptions、NinkaLoadOptions。
唯一のランタイム依存は @open-policy-agent/opa-wasm です。
class Ninka
コンストラクタは private です。インスタンスは Ninka.load で生成します。
static load(dir?, options?)
static async load(dir = "authz/out", options: NinkaLoadOptions = {}): Promise<Ninka>
dir 内のすべての *.build.json を読み込み、準備済みの Ninka インスタンスを返します。
フェイルクローズドな読み込み時整合性検査。 次の場合に load は例外をスローします。
dirが存在しない場合、- ポリシーが 1 つもない場合、または
- ある WASM の SHA-256 が
build.jsonのwasm_sha256、あるいは manifest のrego_sha256系譜と 一致しない場合。
エラーメッセージは npx ninka build を案内します。改ざんや古くなった authz/out/ は、使用される
前に読み込みに失敗します。
check(policy, input)
check は、生成される lib/authz.ts 境界を通して呼び出します。第 1 引数には、生成された policies
テーブルの型付きポリシー参照を渡します(素の文字列は渡しません)。
import { check, policies } from "@/lib/authz";
const allowed = await check(policies.invoiceAccess, {
subject: { properties: { roles: ["accountant"], user_id: "user-123" } },
action: { name: "view" },
resource: { type: "invoice", properties: { amount: 1200, submitted_by: "user-123" } },
});
境界の型は次のとおりです。
check<In extends AuthzInput>(policy: PolicyRef<string, In>, input: In): Promise<boolean>
policies.invoiceAccess(types.gen.ts由来)は生成された型付きのPolicyRefです。- その型はポリシーが要求する入力の形(
InvoiceAccessInput)を保持しています。 - TypeScript は第 2 引数をその型に照合します。形が違ったり未知のアクションを渡すとコンパイルエラーに なります。
- 実行時の id は文字列ですが、呼び出し側は常に
policies.<id>を渡し、任意の文字列は渡しません。
戻り値は true(許可)または false(拒否)です。未知のポリシーは例外をスローします
(フェイルクローズド)。deny-overrides はコンパイル済みポリシー内部で解決されます。必須入力の欠落が
一因で DENY になった場合は onInputError を発火しますが、判断は変わりません。
ロギングが有効なら決定ログを 1 件出力します。
Ninka インスタンス自体のメソッドは check(policyId: string, input: AuthzInput): boolean(同期)です。
生成された境界が PolicyRef の型付けを加え、メモ化された load を await
するため、アプリケーションコードからは Promise<boolean> に見えます。
get policyIds()
get policyIds(): string[]
実行時のイントロスペクション(読み込み済みの文字列 id 一覧)です。これは型安全なアプリケーション
API ではありません。判定を行うには、policyIds の文字列ではなく、生成された policies テーブルの
型付き PolicyRef を渡してください(check を参照)。
interface AuthzInput
check への入力です。
export interface AuthzInput {
subject: { properties: Record<string, unknown> };
action: { name: string };
resource: { type: string; properties?: Record<string, unknown> };
context?: Record<string, unknown>;
}
Tegata の属性キーは、この形状に次のように対応します。
| Tegata キー | 入力上の位置 |
|---|---|
action | action.name |
resource_type | resource.type |
subject.* | subject.properties.* |
resource.* | resource.properties.* |
environment.* | context.* |
custom.* | context.custom.* |
生成される types.gen.ts は、この形状を正確に固定するポリシー固有の型を提供します。
生成ファイル と Tegata スキーマ を参照してください。
interface NinkaLoadOptions
export interface NinkaLoadOptions {
onInputError?: (error: InputValidationError) => void; // { policyId, missing: string[] }
decisionLog?: DecisionLogOptions; // { enable?: boolean; sink?: (e) => void }
}
onInputError
必須入力の欠落が一因となって DENY になったときに呼ばれます。これにより、データ起因 の拒否と 判断起因 の拒否を区別できます。判断を変えることはありません。デフォルトは stderr への 1 行出力です。
decisionLog
デフォルトでは無効です。有効にすると、check は OPA の Decision Log 互換のエントリを出力します。
ログされる input はマスクされます。 語彙で audit: true とマークされた属性だけが素のまま
現れ、その他の値はすべて "***" になります。デフォルトの sink は JSON を 1 行 stdout に書き出します。
export interface DecisionLogOptions {
enable?: boolean;
sink?: (entry: DecisionLogEntry) => void;
}
interface DecisionLogEntry
OPA 互換の決定ログエントリです。Ninka 固有のデータは ninka の下に入ります。
| フィールド | 値 |
|---|---|
decision_id | 判断ごとの一意 id。 |
timestamp | 判断が行われた時刻。 |
path | "ninka/result"。 |
result | boolean — 判断結果。 |
input | マスク済みの入力(audit: true の属性のみ素で表示)。 |
bundles | ポリシー → { revision }。revision は tegata_hash。 |
labels | ログのラベル。 |
ninka | { schema: 1, policies: [{ id, verdict, missing? }] }。 |
interface InputValidationError
export interface InputValidationError {
policyId: string;
missing: string[];
}
onInputError に渡されます。どのポリシーが拒否したか、どの必須入力キーが欠落していたかを示します。
関連ページ
- クイックスタート —
checkをアプリに組み込む。 - 生成ファイル —
loadが読み込む成果物。 - Tegata スキーマ — ポリシーの属性がどう入力形状になるか。