Skip to main content
ctrlrun verify runs the kernel’s own failure scenarios against your policy, in a scratch store, with fake executors and no network, and reports what passed, what failed, and what it could not check. In CI that is one step, and 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
Two guarantees are not applicable: this policy has no authority: section, so nothing about grants can be exercised. They are reported with the reason, excluded from the denominator and listed separately. Never 11/11, 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. Pin the action to a release tag or a commit rather than @main once you rely on it.
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 could be exercised: the policy has no approve rule, no effect: template and no grants, so 0/0, which is never a pass.
  • Exit 1: a guarantee failed. The report names the scenario and the action; that is a bug report, not a configuration problem.

Next