fix(release): align verify gate to emitted collection name + native attestor types#270
Merged
Merged
Conversation
…ttestor types
The release verify gate has never passed because `cilock verify` could not
select the build collection as a policy candidate. Two independent bugs, both
masked behind the same misleading ErrNoCollections message ("no subjects
matched ... supply inclusion-proof sidecar", which blames the Merkle bridge):
1. Collection-name / step-name mismatch. The dogfood ran with
`--step "release-build-<os>-<arch>"`, naming the attestation collection
`release-build-linux-amd64`, but the policy has a single step `release-build`.
`source.Search` keys on `referencesByCollectionName[stepName]` (exact match),
so the search for step `release-build` found zero collections. Fixed by
naming the collection `release-build` for every platform; per-arch
distinction stays in the `-o` outfile, not the step. (This is the failure
that fired first in rc1-rc6: the error literally said "for step release-build".)
2. Required attestation-type mismatch. The policy required
`witness.dev/attestations/commandrun/v0.1` — but the attestor is spelled
`command-run` (hyphenated) in BOTH namespaces, so `commandrun` aliases to
nothing and `MemorySource.matchesAttestations` (exact lookup over the emitted
type and its LegacyAlternate) filtered the collection out even once names
matched. All required types are now the aflock.ai-native URIs the binary
actually emits (git, github, command-run, product/v0.3), removing all
dependency on the legacy alias bridge.
Also fix the github-step rego, which had never run (rc1-6 failed before rego
eval) and was silently vacuous: it read top-level `input.repository` /
`input.reftype`, which do not exist on the github attestor — the real fields
are `input.jwt.claims.repository` / `input.jwt.claims.ref_type`. Rewritten to
read those, fail-closed on missing fields, and kept in v0 rego syntax because
cilock evaluates via the legacy github.com/open-policy-agent/opa/ast path
(RegoV0); the v1 `deny contains msg if` form would fail to parse.
Verified end-to-end against the real rc6 platform-signed attestation: candidate
selection goes 0 -> 1 with the combined fix, the signer cert's Fulcio extensions
(Issuer / SourceRepositoryURI / BuildConfigURI) match the functionary
constraint, and the rego passes the legitimate release while denying wrong-repo,
non-tag, and missing-field inputs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
colek42
added a commit
that referenced
this pull request
Jun 4, 2026
Brings rookery up to date with the judge monorepo's subtrees/rookery (origin/main) — commandrun v0.2 producer + signed key-guard evidence + all-env eBPF sentinel, evidence-based SLSA verdict, policy verify/validate UX, attestor skip-hints, and the consolidated keyless/auth work. Preserves rookery's cilock.dev release pipeline (the #270/#272 fixes judge had not yet synced): release.yml uses --step release-build (collection name matches the policy step), install.sh uses 'cilock version', and release.policy.json uses native aflock.ai types + jwt.claims rego — with command-run bumped v0.1 to v0.2 to match what cilock now emits. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The release verify gate has never passed because
cilock verifycould not select the build collection as a policy candidate. Two independent bugs, both hidden behind the same misleadingErrNoCollectionsmessage ("no subjects matched ... supply inclusion-proof sidecar", which wrongly blames the Merkle bridge):Bug 1 — collection-name / step-name mismatch
The dogfood ran with
--step "release-build-<os>-<arch>", naming the collectionrelease-build-linux-amd64, but the policy has a single steprelease-build.source.Searchkeys onreferencesByCollectionName[stepName](exact match), so searching for steprelease-buildreturned zero collections. This is the failure that fired first in rc1–rc6 — the error literally said "for step release-build". Fixed by naming the collectionrelease-buildfor every platform; per-arch distinction stays in the-ooutfile.Bug 2 — required attestation-type mismatch
The policy required
witness.dev/attestations/commandrun/v0.1, but the attestor is spelledcommand-run(hyphenated) in both namespaces —commandrunaliases to nothing, soMemorySource.matchesAttestationsfiltered the collection out even once names matched. All required types are now the aflock.ai-native URIs the binary actually emits (git,github,command-run,product/v0.3), removing all dependency on the legacy alias bridge.Also: github-step rego was silently vacuous
It read top-level
input.repository/input.reftype, which do not exist on the github attestor — the real fields areinput.jwt.claims.repository/input.jwt.claims.ref_type. (It never ran before because rc1–6 failed earlier.) Rewritten to read those, fail-closed on missing fields, kept in v0 rego syntax (cilock evaluates via the legacyopa/astpath = RegoV0; v1deny contains msg ifwould fail to parse).Verification (against the real rc6 platform-signed attestation)
command-run→ 1 candidate,commandrun→ 0; real step namerelease-build→ 1 only after both fixes).opa evaland a cilock-legacy-ast parse probe).🤖 Generated with Claude Code