Browse documentation

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_FAILEDDecisions SignedUpdated October 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. Evaluation is deterministic and isolated, with no network access. Policies follow the Open Policy Agent deny-rule convention: each deny (or warn, audit and similar) rule that matches adds a message explaining why.

# Block reachable critical findings on internet-facing workloads.
# Field names are illustrative; the builder's field picker lists the
# fields available to your policy.
package esos.policies.block_reachable_critical

import future.keywords.if

deny contains msg if {
  input.finding.severity == "critical"
  input.finding.reachability == "reachable"
  input.asset.internet_exposed == true
  msg := "Reachable critical finding on an internet-facing workload"
}

Create a policy

  1. In the console, open the policy builder and start a new policy.
  2. Add rules (field, operator, value) and group them with AND or OR.
  3. Choose the action — such as deny, warn, audit, open a ticket or notify — and review the generated Rego.
  4. Run it in advisory mode on pull requests first, then enforce it at the gate.

The visual builder

For teams that do not write Rego, the builder models a policy as rules (field, operator, value), grouped with AND or OR, plus an action and 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 reason OPA_EVALUATION_FAILED. There is no configuration that turns an evaluation error into an allow.

Signed decisions and the audit chain

Every control decision is digitally signed together with the control, the outcome, a hash of the exact input evaluated, the organisation and a timestamp. Auditors receive a public key to verify decisions independently. The audit log is append-only and hash-chained, so tampering is evident.

Exceptions and overrides

When authoring an exception, specify its owner, expiry and approver chain; enable dual control where required. 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.

Next steps