Docs/Build/Policy authoring

Policy authoring.

Policy is Open Policy Agent Rego. Author it by hand, or compose rules, AND/OR groups and an action in the visual builder and let it compile to Rego you can review.

Engine OPA · RegoFailure DENY · OPA_EVALUATION_FAILEDSigning Ed25519Updated September 2026

Anatomy of a policy

A policy receives a structured input — the finding, its entity context, reachability and exposure, the environment — and returns a decision. The evaluator runs OPA as a subprocess over that input and parses the result. There is no network access during evaluation.

# policy: block reachable critical dependencies on internet-facing workloads
package securityvault.gate

default allow := false

allow if {
  count(deny) == 0
}

deny[msg] if {
  f := input.findings[_]
  f.severity == "critical"
  f.reachability.verdict == "reachable"
  input.subject.exposed == true
  msg := sprintf("reachable critical %s on exposed workload", [f.id])
}

The visual builder

For teams that do not write Rego, the builder models a policy as PolicyRule (field, operator, value) → PolicyGroup (AND / OR) → PolicySpec (groups, action, metadata) and renders valid Rego. Field paths are allow-listed — each segment must be an identifier — so a rule can never break out of the generated expression. The generated Rego is stored and shown, so engineers review exactly what will run.

Fail closed

Any evaluator error — invalid policy, timeout, missing input — yields DENY with reasonOPA_EVALUATION_FAILED. There is no configuration that turns an evaluation error into an allow.

Signed decisions and the audit chain

Control decisions are signed with Ed25519 over a canonical, sorted-key payload: control_id, decision, framework_control_id, input_hash, organization_id, public_key_fingerprint, schema_version, timestamp. The private key is held by the evaluation service; the public half can be handed to auditors. The audit log appends each event with the HMAC of its predecessor.

Exceptions and overrides

Exceptions carry an owner, an expiry, an approver chain and optional dual control. Gate overrides (break-glass) require an authorised principal and are recorded as audited events; they never rewrite the original decision.

Patterns we recommend

  • Gate on reachable and exposed, not on raw severity alone — the ontology gives you both.
  • Start policies in advisory mode on pull requests; enforce once the false-positive rate is understood.
  • Prefer one policy per gate with named deny messages over a single monolithic policy.
  • Treat a rising count of OPA_EVALUATION_FAILED as an incident: it means gates are denying for the wrong reason.