Skip to Content
ReferencePolicy in force

Policy in force

A rule set you cannot see the provenance of is a claim, not a control. Your runner records exactly which constitution it loaded, from where, and whether it checked the signature, and reports that to the control plane when it starts.

What happens at start

The runner pod’s load-policy-bundle init container runs before the runner:

  1. Resolve. It resolves policyBundle.bundleRef (on hosted, ghcr.io/trustacks/policy/constitution:1) to a digest, once.
  2. Pull. It pulls that exact digest, so a tag that moves mid-start cannot swap in different bytes.
  3. Verify. It runs cosign verify against the publishing workflow’s Sigstore identity. See Supply-chain verification.
  4. Load or fall back. On success the runner loads the pulled bundle. On any failure it deletes what it pulled and the runner loads the copy of the constitution baked into the runner image.
  5. Record. It writes the outcome, which the runner reports to the control plane after enrolling.
⚠️

Runner versions. Steps 1 to 3 run on hosted runners 0.2.14 and later (and pre-releases from 0.2.14-rc24). Earlier runners, including 0.2.13, try to pull from a development registry that does not exist in your cluster, fall back, and enforce the baked copy without a signature check.

The fallback keeps proposals flowing when the registry is unreachable. It is never silent: the runner reports that it fell back, and why.

Reading the state

Each of the constitution and the overlay gets three fields.

source

ValueMeans
bundleThe runner loaded the bundle it pulled at start.
imageThe runner is enforcing the copy baked into its image. For the constitution, that is the version current when the runner image was built.
noneOverlay only: no overlay is configured.

verified

true only when a signature was checked and passed. A bundle loaded with verification switched off reports verified: false. A bundle that was simply present is not reported as verified.

reason

ReasonMeansWhat to do
okPulled and verifiedNothing
pull_failedThe reference did not resolve, or the pull failedCheck egress to ghcr.io; check policyBundle.bundleRef
verify_failedPulled, but the signature did not match the expected identityCheck egress to Sigstore; check the identity values. If both are right, treat it as a possible tampering event and report it to security@trustacks.com
pubkey_missingKey-based verification, but no public key was mountedLocal development setups only
verification_disabledpolicyBundle.verify is falseTurn it back on unless you have a reason
not_configuredOverlay only: no overlay referenceNothing
unknownThe runner’s chart predates this reporting, or the record was unreadableUpgrade the runner

unknown is never read as success or as failure. It means the runner cannot tell us.

⚠️

A rejected overlay does not show here. These fields describe whether the overlay was pulled and verified at start. From runner 0.2.14 the runner also checks, before it evaluates, that the overlay only adds to data.overlay (see your own rules). An overlay that fails that check can still read bundle, verified: true, ok. The signs are elsewhere: proposals and gap analyses fail with overlay rejected, and the runner logs policy.overlay_rejected with each violation.

Where to see it

In your cluster. The init container prints its decision and a status line (NAMESPACE is the namespace you installed the runner in):

kubectl -n "$NAMESPACE" logs deploy/trustacks-runner-runner -c load-policy-bundle
[load-policy-bundle] constitution cosign keyless verify OK (ghcr.io/trustacks/policy/constitution@sha256:…) [load-policy-bundle] status: {"constitution":{"source":"bundle","verified":true,"reason":"ok",...},"overlay":{"source":"none",...}}

The runner logs what it reported, once per start:

kubectl -n "$NAMESPACE" logs deploy/trustacks-runner-runner | grep policy_state.reported

which includes rules, constitution_source, constitution_verified, and constitution_reason.

In the app. The Rules page lists the rules your runner reports, including Rego source from 0.2.14 (and pre-releases from 0.2.14-rc24). Runners 0.2.14-rc21 to rc23 report rule IDs and descriptions without source, and the page says so. Older runners report no rules.

A card on the Overview showing constitution source and verification is planned, not built. Today the Overview’s Policy in force section shows how many proposals were checked and which rules refused work over a window.

The rules in force

Whatever the source, a runner 0.2.14-rc21 or later reports the full rule inventory it loaded: each rule’s ID, description, package, tooling categories, practice dimensions, and kind. That inventory drives the Rules page and makes every row of the maturity score verifiable. If you run several runners on different versions, each one’s report is kept, so a disagreement is visible rather than averaged away.

Where to go next

Last updated on