An open language for explainable policies.
Ergo is an open source language for writing policies that explain themselves. Instead of a yes or no, every decision returns an audit report of what was checked, and why it passed or failed. Run your policies on Open Policy Agent with ergo.rego, or with the ergo CLI.
Latest release: ergo.rego 0.6.0, ergo CLI 0.4.0, spec 0.6
Ergo the policy
ergo_spec: v0.6
subjects:
deployment:
from: deployments whose environment is "prod"
identified_by: id
requirements:
prod_deploy:
subject: deployment
checks:
approved:
description: Someone approved the deployment
assert: approved_by is a non-empty stringErgo the evaluation, reading this input
{
"deployments": [
{"id": "d-1", "environment": "prod",
"approved_by": "alice"},
{"id": "d-2", "environment": "prod"},
{"id": "d-3", "environment": "staging"}
]
}Three deployments. d-2 has no approved_by field at all, and d-3 is in staging.
Ergo the report
d-3 is out of scope. d-2 was never approved… and the report says so.
Ergo the policy
ergo_spec: v0.6
subjects:
pull request:
from: pull_requests
identified_by: number
requirements:
peer_reviewed:
subject: pull request
checks:
peer:
description: Someone other than the author approved it
for: some approvers as approver
assert: approver.username does not equal authorErgo the evaluation, reading this input
{
"pull_requests": [
{"number": 1, "author": "ann",
"approvers": [{"username": "ann"}, {"username": "bob"}]},
{"number": 2, "author": "bob",
"approvers": [{"username": "bob"}]},
{"number": 3,
"approvers": [{"username": "bob"}]}
]
}Three pull requests. PR 2 was approved only by its author, and PR 3 has no author recorded.
Ergo the report
approvers: ann, bobtruesatisfied
approvers: bobfalsevalue
approvers: bobfalseabsent
PR 2 was only approved by its author. PR 3 has no author recorded. Different problems, different fixes.
Ergo the policy
ergo_spec: v0.6
subjects:
expense:
from: expenses
identified_by: id
requirements:
expense_policy:
subject: expense
checks:
within_limit:
description: The meal costs at most €50
assert: amount is at most 50
receipt:
description: A receipt is attached
assert: receipt is a non-empty stringErgo the evaluation, reading this input
{
"expenses": [
{"id": "e-1", "amount": 42,
"receipt": "r-881.pdf"},
{"id": "e-2", "amount": 68,
"receipt": "r-902.pdf"},
{"id": "e-3", "amount": 35}
]
}Three meal expenses. e-2 is over the €50 limit, and e-3 has no receipt.
Ergo the report
e-2 costs too much and e-3 has no receipt, so whoever claimed them knows exactly what to fix.
A decision nobody can inspect
isn't evidence.
With Rego you can block a deployment, but you can't show later why. When you write policies with Ergo you have records of why decisions were made.
When a decision matters, someone else has to be able to check that the policy behaved as it should. A yes or no can't be validated. You don't just tell an auditor, a customer or a colleague the decision. You hand over the workings.
Rego provides decisions
{
"allow": false
}Useful. But why was it false?
With Ergo you get explanations
subject check value read passed cause
d-1 approved approved_by = "alice" true satisfied
d-2 approved approved_by = null false absent
d-3 $applies environment = "staging" false value (out of scope, recorded)Same decision. Now you can see why.
Write the policy.
Not the sorcery.
Defined in YAML or Rego
Write the policy as a YAML file or as a Rego object. Ergo reads both the same way and gives the same report.
- 1
Define the subjects
Each subject gets a name.
fromsays where the subjects are in the input, andidentified_bynames the field that tells them apart. - 2
Filter the scope
whosekeeps only the subjects the policy is about, here the production deployments. The rest are recorded, not dropped. - 3
Test the values
A requirement names its subject, and its
checksare the rules each one must pass, each written as a sentence. Ergo does the looping, the evaluation and the report.
# policy/policy.yaml
ergo_spec: v0.6
subjects:
deployment:
from: deployments whose environment is "prod"
identified_by: id
requirements:
prod_deploy:
subject: deployment
checks:
approved:
description: Someone approved the deployment
assert: approved_by is a non-empty stringOne report format.
Every policy.
A deployment policy. An expense policy. A loan eligibility policy. Different checks, same evidence: one row per subject and check. Passing and failing rows have the same fields.
- requirement
Which requirement produced the row.
- subject
The thing that was judged, with its type and id.
- check
The rule that ran.
- inputs
The values the check actually read.
- passed
The result. Always
trueorfalse. - cause
Why it reached that result.
Same policy + same input = the same report, byte for byte. Hash it. Diff it. Store it.
- Nothing disappears.
- Nothing is implied.
- Everything is reproducible.
- Everything has a reason.
One language.
Two engines.
Two engines can run your policies, and both follow the same spec. ergo.rego runs on Open Policy Agent, so it runs wherever OPA does. The Rust engine runs in the ergo CLI and in the playground in your browser, and is still experimental. Both pass every case in the spec.
- inputs
- inputdeployments.json
- policypolicy.yaml
-
one engine, following the Ergo spec
- engineergo.regoruns on OPA 1.20
- or
- engineRust engine (experimental)runs in the ergo CLI and the playground
- outputs
- decisioncompliant
- evidence report
Auditor says why
Computer says Ergo
Learn how to write self-explaining automated policies in this tutorial, in your browser:
No lock-in.
- 01
Write a policy
Say what you're judging, what's in scope and what must hold, in
policy.yaml.ergo_spec: v0.6subjects: deployment: from: deployments whose environment is "prod" identified_by: idrequirements: prod_deploy: subject: deployment checks: approved: description: Someone approved the deployment assert: approved_by is a non-empty string - 02
Pick an engine
Either one runs the same policy.
- 03
Read the report
Every check, with what it read and why it passed or failed.
Or try it in the browser, with nothing to install: the playground (opens in a new tab) (experimental)
Ergo /ˈɜː.ɡəʊ/
Therefore. As a result. A conclusion that comes with its premises.
Not computer says no. Here is the decision, and here is what produced it.