@@ -116,3 +116,139 @@ git status --short
116116Summarize user-facing changes since the last tag (not internal refactors).
117117Audit-trail dashboard changes are user-facing — flag dropdown reorganizations
118118or new filters here.
119+
120+ ---
121+
122+ ## 8. Sigstore Signing — End-to-End Verification (REQUIRED on first signed release)
123+
124+ ** Background.** Round 8 (build 629, 2026-04-29) wired Sigstore keyless
125+ signing into ` .github/workflows/release.yml ` . The workflow uses GitHub
126+ Actions' OIDC token to mint short-lived ephemeral keys via Fulcio,
127+ records the signature in the Rekor transparency log, and produces
128+ ` <artifact>.sig ` + ` <artifact>.crt ` alongside the ` .spl ` and ` .cdx.json ` .
129+
130+ ** The signing path has never been verified end-to-end** — wiring was
131+ deferred until first release rather than tested in a throwaway tag,
132+ because every ` release: published ` event is observable to anyone
133+ watching the repo and the per-run cost on Sigstore's public infra is
134+ non-zero.
135+
136+ This section MUST be completed before the first signed release ships
137+ publicly. After that, the daily CI job + per-release runs prove the
138+ path stays healthy; this section becomes a one-shot.
139+
140+ ### Step 1 — Cut a draft / pre-release tag
141+
142+ Use a ` v0.0.0-sigstore-test ` -style tag on a throwaway commit so a
143+ verification failure can't affect customer-facing releases:
144+
145+ ``` bash
146+ git tag v0.0.0-sigstore-test
147+ git push origin v0.0.0-sigstore-test
148+ gh release create v0.0.0-sigstore-test \
149+ --prerelease \
150+ --title " Sigstore E2E verification" \
151+ --notes " Throwaway tag — DO NOT INSTALL. Used to prove the signing pipeline."
152+ ```
153+
154+ Watch the run via ` gh run watch ` and confirm:
155+
156+ - The "Sign .spl with Sigstore (keyless)" step succeeded
157+ - The "Sign per-release SBOM with Sigstore (keyless)" step succeeded
158+ - All four asset types are attached: ` .spl ` , ` .sha256 ` , ` .cdx.json ` ,
159+ ` .sig ` , ` .crt `
160+
161+ ### Step 2 — Download and verify the legitimate artifact
162+
163+ ``` bash
164+ mkdir -p /tmp/sigstore-verify && cd /tmp/sigstore-verify
165+ gh release download v0.0.0-sigstore-test
166+ ls -la # should list .spl, .sha256, .cdx.json, .spl.sig, .spl.crt,
167+ # .cdx.json.sig, .cdx.json.crt
168+
169+ # Install cosign locally if not already (one-time setup)
170+ # https://docs.sigstore.dev/cosign/installation/
171+
172+ cosign verify-blob \
173+ --certificate wl_manager-* .spl.crt \
174+ --signature wl_manager-* .spl.sig \
175+ --certificate-identity-regexp \
176+ ' https://github.com/RelativisticJet/wl_manager/.github/workflows/release.yml@refs/tags/.*' \
177+ --certificate-oidc-issuer \
178+ https://token.actions.githubusercontent.com \
179+ wl_manager-* .spl
180+ ```
181+
182+ ** Expected:** ` Verified OK ` . Anything else = pipeline broken; do not
183+ ship a real release until resolved.
184+
185+ Also verify the SBOM signature with the same command pattern, swapping
186+ the artifact + cert + sig file names.
187+
188+ ### Step 3 — Tamper test (proves the verifier actually verifies)
189+
190+ ``` bash
191+ cp wl_manager-* .spl wl_manager-tampered.spl
192+ echo " tamper" >> wl_manager-tampered.spl
193+
194+ cosign verify-blob \
195+ --certificate wl_manager-* .spl.crt \
196+ --signature wl_manager-* .spl.sig \
197+ --certificate-identity-regexp \
198+ ' https://github.com/RelativisticJet/wl_manager/.github/workflows/release.yml@refs/tags/.*' \
199+ --certificate-oidc-issuer \
200+ https://token.actions.githubusercontent.com \
201+ wl_manager-tampered.spl
202+ ```
203+
204+ ** Expected:** verification FAILS with a hash-mismatch error. If it
205+ passes, the verifier is wired wrong — investigate before shipping.
206+
207+ ### Step 4 — Confirm Rekor transparency-log entry
208+
209+ ``` bash
210+ cosign verify-blob ... --rekor-url https://rekor.sigstore.dev < args from step 2>
211+ ```
212+
213+ ** Expected:** the verify command (with ` --rekor-url ` ) confirms a
214+ matching entry in the public log. The Rekor entry is the cryptographic
215+ receipt that this artifact existed at release time — it's what makes
216+ the signing scheme tamper-evident even against a future repo takeover.
217+
218+ ### Step 5 — Document the verifier command for downstream users
219+
220+ After Step 2-4 pass, copy the working ` cosign verify-blob ` invocation
221+ into:
222+
223+ - ` README.md ` — "Verifying a downloaded release" section
224+ - ` INSTALLATION.md ` — recommended verification step before
225+ ` splunk install app `
226+ - ` SECURITY.md ` — under the existing "Distribution integrity"
227+ section in ` docs/SBOM.md `
228+
229+ Use the EXACT command that worked in Step 2 — paraphrased versions
230+ that look right but use slightly different flags create support
231+ tickets.
232+
233+ ### Step 6 — Tear down the test release
234+
235+ ``` bash
236+ gh release delete v0.0.0-sigstore-test --yes
237+ git tag -d v0.0.0-sigstore-test
238+ git push origin :refs/tags/v0.0.0-sigstore-test
239+ ```
240+
241+ Leaves the repo clean for the real first release tag.
242+
243+ ### Acceptance
244+
245+ - Steps 2+3+4 all produced the expected outcomes (legit verify OK,
246+ tamper verify FAIL, Rekor entry confirmed)
247+ - Verifier command published in at least one customer-facing doc
248+ - Test release deleted
249+
250+ After this section is completed once, mark this section as
251+ ** ` [x] DONE — verified <date> on tag <tag-name> ` ** in this file and
252+ leave it in place. Future releases verify automatically via the
253+ quarterly pip-audit cadence + per-release workflow run; this one-shot
254+ just proves the wiring.
0 commit comments