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

ランタイム API

Ninka ランタイムの完全なリファレンスです。ランタイムは、コンパイル済みポリシーを読み込み、認可判断を 行うためにアプリケーションが使用する API です。判断は WASM によりインプロセスで実行されます。ネット ワークも、リクエスト経路上の opa バイナリも、クラウドもありません。

インポート

import { Ninka, type AuthzInput, type DecisionLogEntry } from "ninka-authz/runtime";

ninka-authz/runtime からエクスポートされるもの: クラス Ninka と、インターフェース AuthzInputInputValidationErrorDecisionLogEntryDecisionLogOptionsNinkaLoadOptions

唯一のランタイム依存は @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.jsonwasm_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.invoiceAccesstypes.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 キー入力上の位置
actionaction.name
resource_typeresource.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"
resultboolean — 判断結果。
inputマスク済みの入力(audit: true の属性のみ素で表示)。
bundlesポリシー → { revision }revisiontegata_hash
labelsログのラベル。
ninka{ schema: 1, policies: [{ id, verdict, missing? }] }

interface InputValidationError

export interface InputValidationError {
policyId: string;
missing: string[];
}

onInputError に渡されます。どのポリシーが拒否したか、どの必須入力キーが欠落していたかを示します。


関連ページ