Skip to content

🔒 fix(release): pin cosign signer identity on the maintainer verify path (AUD2-F01) - #83

Merged
konih merged 1 commit into
mainfrom
lane/aud2-f01-integrate
Aug 19, 2026
Merged

🔒 fix(release): pin cosign signer identity on the maintainer verify path (AUD2-F01)#83
konih merged 1 commit into
mainfrom
lane/aud2-f01-integrate

Conversation

@konih

@konih konih commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

AUD2-F01 — SEC-03's twin on the maintainer/CI path

verify_cosign() in hack/release/verify-artifacts.sh ran the byte-identical unpinned cosign verify-blob --bundle "$bundle" "$archive" that AUD2-S03 had just fixed in hack/install.sh. Keyless verification without a signer pin either errors out on cosign v2 or accepts ANY Fulcio identity, so a mirror-swapped archive shipped with its own validly signed bundle verified clean on the path task release-verify uses — and --require-signature promised something it did not deliver there.

The fix

The call now carries the D-153 pair, byte-identical to SECURITY.md and hack/install.sh:

--certificate-oidc-issuer https://token.actions.githubusercontent.com
--certificate-identity-regexp '^https://github\.com/PlatformRelay/[Aa]ssent/'

Enforcement extends the existing drift gate rather than starting a second published truth (D-128): hack/release/install_cosign_pin_test.sh now grades verify-artifacts.sh as the third file, requiring exactly one distinct value per file and all three pairwise-equal. No new task check stage — the gate is already wired as release-install-cosign-pin-test, so CHECK_STAGES stays at 19.

Non-vacuity

verify-artifacts.sh only reaches cosign when a .sigstore.json sits beside an archive, and the snapshot path ships no bundles — so an end-to-end test can pass green without ever executing the changed line. The discriminator is therefore the stubbed cosign's argv log, not the exit code: §5d requires that log to be non-empty and to carry both pinned values, and §5e is the paired control showing a bundle-less (snapshot-shaped) dist/ leaves the same log empty.

Gates

  • task checkexit 0, all 19 stages
  • bash hack/release/install_cosign_pin_test.shexit 0 standalone
  • Independent review: APPROVE, P3 notes only, no conditions
  • hack/audit/exitgate_test.sh untouched

…ath (AUD2-F01)

`verify_cosign()` in hack/release/verify-artifacts.sh ran the byte-identical
unpinned `cosign verify-blob --bundle "$bundle" "$archive"` that AUD2-S03 had
just fixed in hack/install.sh. Keyless verification without a signer pin either
errors out on cosign v2 or accepts ANY Fulcio identity, so a mirror-swapped
archive shipped with its own validly signed bundle verified clean on the path
`task release-verify` uses to check a release before it ships — and
`--require-signature` promised something it did not deliver there.

The call now carries the D-153 pair, byte-identical to SECURITY.md and
hack/install.sh:

  --certificate-oidc-issuer https://token.actions.githubusercontent.com
  --certificate-identity-regexp '^https://github\.com/PlatformRelay/[Aa]ssent/'

Enforcement extends the EXISTING drift gate rather than starting a second
published truth (D-128): hack/release/install_cosign_pin_test.sh now grades
verify-artifacts.sh as the THIRD file, requiring exactly one distinct value per
file and all three pairwise-equal. No new `task check` stage — the gate is
already wired as release-install-cosign-pin-test, so CHECK_STAGES stays at 19.

Non-vacuity, which is the hard part here: verify-artifacts.sh only reaches
cosign when a .sigstore.json sits beside an archive, and the snapshot path ships
no bundles, so an end-to-end test can pass green without ever executing the
changed line. The discriminator is therefore the stubbed cosign's argv LOG, not
the exit code — §5d requires that log to be non-empty and to carry both pinned
values, and §5e is the paired control showing a bundle-less (snapshot-shaped)
dist/ leaves the same log empty. Offline throughout: stubbed cosign, no network.

Proved red by mutation, each on a temp copy: each flag deleted from
verify-artifacts.sh; the pre-fix both-flags-missing shape; either field drifted
from the other two files; the file disagreeing with itself; the pre-existing
install.sh flag and drift mutations re-run unweakened; and the trap case — both
flags left textually in place while the cosign branch is never entered, which
§5d catches on the empty stub log.
@konih
konih merged commit e575ef8 into main Aug 19, 2026
5 checks passed
@konih
konih deleted the lane/aud2-f01-integrate branch August 19, 2026 04:18
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.

1 participant