Skip to content

fix(release): align verify gate to emitted collection name + native attestor types#270

Merged
colek42 merged 1 commit into
mainfrom
fix/release-policy-attestation-types
Jun 2, 2026
Merged

fix(release): align verify gate to emitted collection name + native attestor types#270
colek42 merged 1 commit into
mainfrom
fix/release-policy-attestation-types

Conversation

@colek42
Copy link
Copy Markdown
Contributor

@colek42 colek42 commented Jun 2, 2026

The release verify gate has never passed because cilock verify could not select the build collection as a policy candidate. Two independent bugs, both hidden behind the same misleading ErrNoCollections message ("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 collection release-build-linux-amd64, but the policy has a single step release-build. source.Search keys on referencesByCollectionName[stepName] (exact match), so searching for step release-build returned zero collections. This is the failure that fired first in rc1–rc6 — the error literally said "for step release-build". Fixed by naming the collection release-build for every platform; per-arch distinction stays in the -o outfile.

Bug 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 — commandrun aliases to nothing, so MemorySource.matchesAttestations 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: 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 are input.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 legacy opa/ast path = RegoV0; v1 deny contains msg if would fail to parse).

Verification (against the real rc6 platform-signed attestation)

  • Candidate selection goes 0 → 1 with the combined fix (differential: command-run → 1 candidate, commandrun → 0; real step name release-build → 1 only after both fixes).
  • Signer cert Fulcio extensions (Issuer / SourceRepositoryURI / BuildConfigURI) match the functionary constraint.
  • Rego passes the legitimate release; denies wrong-repo, non-tag, and missing-field inputs (validated with opa eval and a cilock-legacy-ast parse probe).

🤖 Generated with Claude Code

…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 colek42 marked this pull request as ready for review June 2, 2026 05:46
@colek42 colek42 merged commit a1fc622 into main Jun 2, 2026
21 checks passed
@colek42 colek42 deleted the fix/release-policy-attestation-types branch June 2, 2026 05:46
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants