A Rego policy defines the rules Kosli evaluates trail data against. You pass aDocumentation Index
Fetch the complete documentation index at: https://kosli-kosli-next.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
.rego file to kosli evaluate trail or kosli evaluate trails via the --policy flag. Kosli includes a built-in evaluator with no OPA installation required.
Policy contract
These rules are Kosli-specific conventions, not OPA built-ins. Kosli queriesdata.policy.* to find them.
Every policy must declare
package policy. Kosli queries data.policy.allow and data.policy.violations to read the result.Must evaluate to a boolean. Kosli exits with code
0 when true, code 1 when false.Always define allow with a fail-safe default and drive it through a positive assertion, not through the absence of violations. See Safe policy design.Optional but recommended. A set of human-readable strings explaining why the policy denied. Kosli displays these when
allow is false. Each message should identify the offending resource and the reason.Violations are diagnostics only. They must not drive the allow decision. See Safe policy design.Safe policy design
Three rules prevent a policy from incorrectly reporting a non-compliant trail as compliant.Rule 1: use a fail-safe default
Always start withdefault allow := false. A trail must be explicitly approved rather than allowed by the absence of evidence against it.
Use parameter aliases at the top of the policy file rather than hardcoding threshold values. If a required param is absent from the params file, any rule that references its alias will fail to evaluate, and allow will correctly remain false.
Rule 2: drive allow through positive assertions
Drive the allow decision through a condition that must be true for the trail to be compliant. Do not write:
violations rule body encounters an undefined reference, such as a missing param or an absent attestation field, OPA silently skips that rule body and adds no message to the set. The set is then empty, count(violations) == 0 evaluates to true, and allow fires even though the policy never verified compliance. This produces a false-positive compliant result.
The safe pattern makes compliance explicit:
trail_is_compliant is undefined, the rule body fails to evaluate and allow remains false.
See Evaluate trails with OPA policies for a detailed walkthrough.
Rule 3: violations are diagnostics only
In aviolations rule, an undefined reference causes the rule body to fail silently: no message is added. This is the safe failure mode for diagnostics. Violations explain a denial determined by the allow rule and must not determine it themselves.
See Evaluate trails with OPA policies for a detailed walkthrough.
Params
Policies can read external configuration via the--params flag. Params are available in the policy as data.params.*. This separates policy logic from the thresholds it enforces, so one .rego file can cover multiple environments with different params files.
max_high is absent, max_high is undefined and any rule that references it fails to evaluate, leaving allow at its false default.
Input data
The data structure passed to the policy asinput depends on which command you use.
Single trail (kosli evaluate trail)
The policy receives input.trail, a single trail object.
The trail being evaluated.
Multiple trails (kosli evaluate trails)
The policy receives input.trails, an array of trail objects with the same structure as input.trail above.
Array of trail objects. Each element has the same structure as
input.trail described above.Use
--show-input with --output json to print the full input structure for a given trail. Pipe through jq to explore specific fields:Local testing
Usekosli evaluate input to test a policy against captured trail data without making live Kosli API calls:
Exit codes
| Code | Meaning |
|---|---|
0 | Policy allowed (allow = true) |
1 | Policy denied (allow = false) or command error (network failure, invalid Rego, policy file not found) |
1 is used for both denial and failure. To distinguish between them in CI, use --output json and read the allow field directly from the output rather than relying on the exit code.
Examples
Check pull request approvals across multiple trails
Allows only when every trail ininput.trails has at least one pull request with at least one approver. The attestation name is read from params so the same policy works across orgs that use different naming conventions.
Check Snyk scan results on a single trail
Allows only when every artifact in the trail has a Snyk scan where the high-severity vulnerability count does not exceedmax_high. Both the attestation name and the threshold are read from params.
Further reading
- Rego Style Guide: naming, rule structure, and test conventions
- OPA Annotations: including
entrypoint: truefor use withopa build - Tutorial: Evaluate trails with OPA policies