You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
🔒 fix(security): make the published cosign verify command actually verify
The identity regexp published in docs/RELEASE.md, docs/security/security-architecture.md
and ADR-0709 was lowercase (`platformrelay/kollect`), but GitHub's OIDC SAN preserves the
repository's canonical casing (`PlatformRelay/Kollect`) and
`--certificate-identity-regexp` is a case-sensitive Go RE2 pattern. The command therefore
could not verify any Kollect release, for anyone, since the first signed release.
Proven, not assumed: run against a real published signature
(charts/kollect:0.19.0@sha256:7812957c), the old value FAILS and the new one PASSES, with
wrong-org, wrong-repo and wrong-issuer negative controls all still rejecting.
Why it went unnoticed: .github/release-notes-install.md builds the same command from
${GITHUB_REPOSITORY}, which GitHub expands with canonical casing. Verifying from the
release page worked; verifying from the docs never did.
The new value is case-tolerant on both path segments and escapes the host dots,
matching the convention already proven in the assent repo:
^https://github\.com/[Pp]latform[Rr]elay/[Kk]ollect/.+
Also removes the hardcoded ERE copy of this value in the migration gate. That copy was a
second source of truth full of regex metacharacters, and it went on asserting the broken
lowercase identity while agreeing with itself. It is replaced by logged_f(), a
fixed-string twin of logged() fed from the variable the gate already cross-checks against
docs/RELEASE.md, so the value can no longer drift between what is pinned and what is run.
Mutation-proven: pointing the real cosign call at the old value while leaving the pinned
variable correct now reds the gate with the drifted command printed.
ADR-0709 keeps its original analysis paragraph and gains a dated amendment: that
paragraph's central claim ("every documented verification command matches the signer")
was false, and executing its own V1 gate is what proved it.
# Fixed-string twin. Use this whenever the needle is a VALUE the gate already pins
762
+
# (an identity regexp, an issuer URL): the value is full of ERE metacharacters, so a
763
+
# hand-escaped copy of it is a second source of truth that drifts silently. SEC-VERIFYCASE-01
764
+
# is exactly that failure -- a hardcoded copy here went on asserting the lowercase identity
765
+
# that cosign could never match, and agreed with itself while the real command was broken.
766
+
logged_f() { grep -Fq "$2""$1/log"; }
761
767
762
768
# --- 8a. A bare invocation must not write. ---------------------------------
763
769
# Kills three mutations at once: APPLY defaulting to 1; run_mutating executing regardless
@@ -803,7 +809,7 @@ for v in 0.14.0 0.15.0 0.16.0 0.17.0 0.18.0 0.19.0; do
803
809
fail "--apply copied ${v} without running 'cosign verify' against ${DST}:${v}. Recorded verifies:"$'\n'"$(grep -E '^cosign verify'"${scene}/log"||echo'(none)')"
804
810
done
805
811
# ...and with the published flag shape, on the real call rather than in the source text.
fail "the recorded 'cosign verify' does not carry the published issuer/identity flags. Recorded:"$'\n'"$(grep -E '^cosign verify'"${scene}/log"| head -1)"
808
814
809
815
# THE transposition assertion. `cosign copy DST SRC` would push the chart-only path back
0 commit comments