Skip to main content
ctrlrun verify runs the kernel’s own failure scenarios against your policy, in a scratch store, with fake executors and nothing reached outside the runner. It reports what passed, what failed, and what it could not check. The badge it writes means one thing: the declared guarantees pass. Prerequisites: a repository with a ctrlrun.yaml, and GitHub Actions.
1

Run it locally first

runnable
runnable
The first line is on stderr, from G7’s own scenario: an action with no principal is refused and the refusal logs, which is the guarantee passing. Every row names k8s.delete_namespace because verify takes the first action that fits, in alphabetical order.Four guarantees are not applicable: no authority: section (G8, G9), no second clock in a scratch store (G13), no max_attempts to refuse past (G15). Each is reported with its reason and excluded from the denominator. Never 16/16, and no flag folds them in.
2

Add the action

The action installs ctrlrun, runs ctrlrun verify --json --junit, renders the job summary and the badge JSON from that one report, and uploads the three as an artifact. It fails the job when a guarantee failed or the configuration was refused, and succeeds when guarantees are N/A: green means nothing that could be checked was wrong.
3

Read the outputs

Outputs: passed, failed, applicable, not-applicable, badge-message, report-path. The ref pins the action’s steps and not the package they install: install is unpinned by default, so @v0.6.1 still takes whatever PyPI serves on the day. Pin both — install: ctrlrun==0.6.1 — where the run has to be reproducible, and pin the action by commit rather than by tag where the ref has to be immovable.
4

Publish the badge, if you want it

The action writes the badge JSON and never publishes it, because publishing needs contents: write and asking every user for that is a bad trade for a tool about least privilege. Publish it yourself from a job that runs only on pushes to your default branch, with contents: write on that job alone, and point Shields’ endpoint badge at the raw file. Get the badge has the copy-paste workflow.

What verify cannot see

Your executors, your reconcile hooks, where you put the decorator, your deployment, and whether your policy is the right policy. An executor that raises NotExecuted after the remote acted is invisible to it. The badge does not mean secure, safe, compliant, certified or audited.

If it didn’t work

  • Exit 2, mode: observe: verify refuses an observed configuration, because observe mode executes what enforce mode would refuse and nothing can be proved about it.
  • Exit 2, nothing was checked and nothing is claimed: no guarantee was applicable, so 0/0 — which is never a pass. In practice that means an actions: map with nothing in it; a policy with one allow action still exercises the fail-closed and unknown-outcome guarantees.
  • Exit 1: a guarantee failed. The report names the scenario and the action; that is a bug report, not a configuration problem.

Next