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 code | In a Tegata |
|---|---|
| The kind of thing being protected | resource.type |
| Who the caller is / their roles | subject.roles |
| What they're trying to do | actions |
| Attribute comparisons against a value | conditions |
| 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
opaon yourPATH; for an air-gapped or existing toolchain, setNINKA_OPA_PATHto 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.