Skip to main content

Migration from OPA

Ninka emits the Rego/WASM you already run on OPA. Migration reframes hand-written policy as a declarative Tegata (手形).

1. Map your rules onto Tegata fields

In your current codeIn a Tegata
The kind of thing being protectedresource.type
Who the caller is / their rolessubject.roles
What they're trying to doactions
Attribute comparisons against a valueconditions
Subject-vs-resource comparisons (ownership)relationships

An inline check or its hand-written Rego:

allow if {
input.action == "approve"
input.subject.roles[_] == "manager"
input.resource.amount <= 500000
}

becomes one rule:

{
"id": "allow-manager-approve-invoice-within-limit",
"effect": "allow",
"subject": { "roles": ["manager"] },
"actions": ["approve"],
"resource": { "type": "invoice" },
"conditions": [ { "key": "resource.amount", "op": "lte", "value": 500000 } ]
}

Ownership checks (input.subject.id == input.resource.owner) become a relationship:

"relationships": [
{ "label": "ownership", "subject_attribute": "user_id", "op": "eq", "resource_attribute": "submitted_by" }
]

2. Compile

npx ninka compile

See Add a Policy for the full write → compile → integrate loop.

Toolchain and scope

  • Ninka pins OPA 0.65.0. It never uses a stray opa on your PATH; for an air-gapped or existing toolchain, set NINKA_OPA_PATH to your vetted 0.65.0 binary. Supported platforms: darwin-x64, darwin-arm64, linux-x64, linux-arm64, win32-x64.
  • v0.1 expresses roles, actions, resource types, relationships, the listed condition operators, and integers only (no floats). Delegate logic Ninka can't express to a Policy Information Point via a custom.* key, or keep that slice in OPA directly.

See also