Skip to content

kitelogik compile

Compile a YAML policy file to Rego. The YAML format is the high-level edit surface most users work in; the generated Rego is what OPA actually evaluates against governance events.

Synopsis

bash
kitelogik compile <INPUT> [-o OUTPUT] [--check]
Argument / FlagDefaultMeaning
INPUTrequiredPath to a YAML policy file (must be a file, not a directory)
-o OUTPUT, --output OUTPUT<input>.regoOutput path for the generated Rego file
--checkoffValidate the YAML without writing any output

Behaviour

Default output path

Without -o, the compiled Rego is written next to the input with the same stem and a .rego suffix:

bash
$ kitelogik compile policies/policy.yaml
Compiled policies/policy.yaml -> policies/policy.rego

The output's parent directory is created if missing.

Custom output path

bash
$ kitelogik compile rules.yaml -o build/policies/rules.rego
Compiled rules.yaml -> build/policies/rules.rego

Check mode (CI-friendly)

--check validates the YAML structure without producing output — useful as a CI step that fails the build on bad YAML before merging:

bash
$ kitelogik compile policies/policy.yaml --check
Valid YAML policy: policies/policy.yaml

Exit code is 0 on a clean parse, 1 on a YAML structure error.

Refuses directories

compile operates on a single file. Pointing it at a directory exits with code 1 and a usage hint:

bash
$ kitelogik compile policies/
Error: policies/ is a directory. Compile individual .yaml files.
Example: kitelogik compile policies/rules.yaml

If you have several .yaml files, drive a loop yourself (for f in policies/*.yaml; do kitelogik compile "$f"; done) — the deliberate single-file scope avoids surprising bulk overwrites.

What gets compiled

The YAML format supports the rule shape:

yaml
version: 1

rules:
  - name: allow_small_refund
    when:
      action: approve_refund
      role: support_agent
      args:
        amount: { lte: 100 }
    then: allow

  - name: block_large_refund
    when:
      action: approve_refund
      args:
        amount: { gt: 100 }
    then: deny
    reason: "Refunds over $100 require manager approval"

The compiler emits a Rego file in the kitelogik.userpolicy package with one rule per YAML rule — then: allow → an allow rule, then: hitl → a set-valued hitl[reason] rule, then: deny → a set-valued deny[reason] rule. main.rego aggregates that package alongside the built-in policies, so you never name a package yourself. The full grammar — operators, scope checks, the three then: outcomes — lives in the Your first policy guide.

Where the file goes in OPA

OPA reads policies/ recursively at startup (and on --watch reload). As long as the compiled .rego is somewhere under the policies mount, it gets loaded. Keep the YAML alongside the Rego in version control; the compile step is deterministic, so the diff stays reviewable.

  • validate — syntax-check a generated .rego file via opa check
  • test — run unit tests against the policies directory
  • Your first policy — full YAML grammar with worked examples

Released under the Apache 2.0 License.