Skip to content

feat(policyimport): OPA Rego + Cedar → CEL translation layer (closes #282) - #284

Merged
telleroutlook merged 1 commit into
mainfrom
feat/opa-cedar-compat
Jul 30, 2026
Merged

feat(policyimport): OPA Rego + Cedar → CEL translation layer (closes #282)#284
telleroutlook merged 1 commit into
mainfrom
feat/opa-cedar-compat

Conversation

@telleroutlook

Copy link
Copy Markdown
Contributor

Positions symkernel as a Z3-proof backend for teams already using OPA or Cedar — keep your existing Rego/Cedar policies, gain formal verification, no migration to a new policy language.

What

New internal/policyimport package with two entry points:

  • TranslateRego(src, ruleName) — parses Rego (opa/v1/ast, Rego v1 syntax), combines allow rules as a disjunction of conjoined body expressions, handles the default allow := false deny-by-default idiom, emits CEL over input.
  • TranslateCedar(src) — parses Cedar (cedar-go), walks the x/exp/ast node tree (scope constraints + when/unless), emits CEL over principal/action/resource/context, carries the permit/forbid Effect.

Both emit into the existing internal/cel substrate — no new evaluation path, and coordinated with the criterion IR (no duplication of internal/cel/constraint work).

Fail-closed by design

A silent mistranslation is worse than no translation: it would let symkernel prove a property about a policy that does not match the source. So every construct the translator does not explicitly understand yields an *UnsupportedError with a precise Construct slug (e.g. rego.builtin:count, cedar.node:like) — never a best-effort guess. See docs/opa-cedar-compat.md for the full supported-subset / rejected-construct matrix.

Provable — the point of the PR

worked_example_test.go carries a Rego and a Cedar policy through CEL to a Z3-verified safety invariant: encode the policy guard + the negation of the invariant and check unsat (no input both satisfies the policy and violates the property). e.g. allow if { input.age >= 18 } is proven to never admit an under-18 principal. Skips automatically when the z3 binary is absent.

Verification

go build ./..., go vet, go test ./internal/policyimport/ (equivalence on the real cel.Evaluate + fail-closed rejections + Z3 worked examples), golangci-lint (0 issues), staticcheck (clean), gofmt clean.

Closes #282.

…282)

Positions symkernel as a Z3-proof backend for teams already using OPA or
Cedar: keep your existing Rego/Cedar policies, gain formal verification —
no migration to a new policy language.

New package internal/policyimport:
- TranslateRego(src, ruleName) — parses a Rego module (opa/v1/ast, Rego v1
  syntax), combines `allow` rules as a disjunction of conjoined body
  expressions, handles the default-deny idiom, emits CEL over `input`.
- TranslateCedar(src) — parses a Cedar policy (cedar-go), walks the
  x/exp/ast node tree (scope constraints + when/unless conditions), emits
  CEL over principal/action/resource/context, carries permit/forbid Effect.
- Both emit into the existing internal/cel substrate.

Fail-closed by design: any construct not explicitly supported yields an
*UnsupportedError with a precise Construct slug, never a best-effort guess —
a silent mistranslation would let symkernel "prove" a property about a policy
that does not match the source. Rejected: Rego user/unknown builtins, with,
some/every, else, partial sets, non-input roots, default-true; Cedar like,
extension calls, tags, isEmpty, is-in-condition, multi-policy docs.

Tests prove semantic equivalence by evaluating the emitted CEL on symkernel's
own cel.Evaluate across input matrices, plus fail-closed rejections. The
worked example (worked_example_test.go) carries a Rego and a Cedar policy
through CEL to a Z3-verified safety invariant (guard ∧ ¬invariant = unsat),
skipping when z3 is absent.

Docs: docs/opa-cedar-compat.md frames the position, the supported subset, the
fail-closed boundary, and the Rego/Cedar → CEL → Z3 worked example.

Verified: go build ./... , go vet, go test ./internal/policyimport/,
golangci-lint (0 issues), staticcheck (clean), gofmt clean.
@telleroutlook
telleroutlook merged commit 1ce5b52 into main Jul 30, 2026
1 check passed
@telleroutlook
telleroutlook deleted the feat/opa-cedar-compat branch July 30, 2026 06:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add OPA/Cedar compatibility layer — position symkernel as a Z3-proof plugin for existing policy languages

1 participant