0pt's own ad hoc "P007 pattern" release chain (.gitea/workflows/release.yml, added 2026-09-14) genuinely fails the real ADR-W16-003 promotion bar an audit (2026-09-15) checked it against: syft/cosign installed via curl + a freshly-refetched checksums file (not a pinned, out-of-band-verified digest), no vulnerability scan of the built digest at all, cosign sign on the bare digest only (no in-toto/SLSA statement, no source-SHA/build-identity/environment/SBOM-hash binding, no scoped key identity), and evidence committed straight back into this same mutable repo (siax/production-evidence/*.json, siax/source-bundles/*.json -- nine such commits already existed in this repo's history; deleted in this PR).
This PR replaces that gate with sax3l/siax-templates' real, reviewed G17 reference implementation (PR #51, merged to main, plus follow-up fixes #56/#57/#59), following the same pattern already proven on st0re, cl0ud, aud0, api0, h0st.
Composition mechanism: pinned-commit checkout at CI runtime
Chosen over a vendored copy (st0re/cl0ud/api0's mechanism) because 0pt has zero existing vendoring convention anywhere in this repo (checked .gitea/workflows/ and .siax/ before deciding) -- but does already reference the SIAX_CI_TOKEN org secret with the exact same git.siax.io authenticated-clone idiom this PR reuses (the now-deleted evidence-commit-push step used the identical bearer pattern for a different cross-repo write). Matches aud0/h0st's own reasoning. Full writeup in .siax/hooks/README.md.
Pinned to siax-templates main @ 384e35060b91ea78ec045e14af114abf5d5eb23b. release.yml refuses to run if main has moved past that commit.
What stayed 0pt-specific
.siax/hooks/G17.sh -- image repo (git.cloud.siax.io/sax3l/0pt), key identity, and a license-allowlist measured against 0pt's own real SBOM (280 components; not copied from another repo).
cd.yml's own real signed-artifact wait/verify gate (predates this migration -- polls the registry for release.yml's artifact, verifies before triggering Coolify) is kept, only its verify command changed (cosign verify on a bare digest -> cosign verify-attestation --type ..., since the new gate uses cosign attest, not cosign sign).
cosign.pub at this repo's root is UNCHANGED (see "Correction" below).
G20 (live-digest-equality) deliberately not wired this pass: 0pt has no Coolify application provisioned and no /version endpoint -- see .siax/hooks/README.md "G20 -- deliberately not wired yet".
Correction (2nd commit on this branch)
The first commit on this branch mistakenly overwrote this repo's committed cosign.pub with a keypair generated only for local verification, then deleted the matching private key with no real handoff -- while inaccurately describing that as a private key "handed to Simon out of band". Neither was true, and doing so would have permanently orphaned the committed public key. The 2nd commit reverts cosign.pub to its original value and corrects .siax/hooks/README.md. COSIGN_PRIVATE_KEY/COSIGN_PASSWORD remain exactly as unprovisioned as they were before this PR -- that decision (generate fresh, or use whatever Simon may already hold offline) is left to Simon, not made by this migration.
Real verification performed (local, this migration)
Built a real image from this repo's own Dockerfile (multi-stage Next.js/node:22-alpine), pushed to a local OCI registry.
syft SBOM against the resolved digest: 280 components. License policy: one genuine finding on the first run (gcompat@1.1.0-r4 -> NCSA, a license this repo's gate had never checked before) -- triaged as the real Alpine OS-substrate license it is and added to the measured allowlist (no .trivyignore needed for licenses).
trivy image --scanners vuln,secret,misconfig --severity CRITICAL,HIGH: 0 findings. No .trivyignore needed -- nothing to suppress.
cosign attest (real DSSE in-toto Statement, all 5 required predicate fields) + cosign verify-attestation, using a throwaway keypair generated solely for this local proof (never committed, deleted afterward -- see "Correction" above). Verification PASSED against that key.
Three real tamper-rejection negative controls against this exact artifact, all correctly REJECTED: wrong public key, wrong predicate type, and a digest that was never attested.
emit-release-evidence.py submitted a real siax.release-evidence v1.0 document to a local mock AUD0 server enforcing the actual eventInputSchema required-field contract -- HTTP 201.
The reference implementation's own G17.selftest.sh: 29/29 assertions passed, including a real live check against production https://api.aud0.siax.io/v1/aud0/version.
Required secrets (not yet set on sax3l/0pt, same prerequisite every prior migration needed)
REGISTRY_USER/REGISTRY_TOKEN (already required by the old gate), COSIGN_PRIVATE_KEY/COSIGN_PASSWORD (still unprovisioned -- see "Correction"), AUD0_INGEST_TOKEN/AUD0_TENANT_ID (new requirement -- needs a siax-svc-g17 Zitadel workload-identity client), SIAX_CI_TOKEN (already exists on this repo). Until set, release.yml fails closed on its first real run -- same honest behaviour as the gate it replaces.
0pt's own ad hoc "P007 pattern" release chain (`.gitea/workflows/release.yml`, added 2026-09-14) genuinely fails the real ADR-W16-003 promotion bar an audit (2026-09-15) checked it against: syft/cosign installed via `curl` + a freshly-refetched checksums file (not a pinned, out-of-band-verified digest), **no vulnerability scan of the built digest at all**, `cosign sign` on the bare digest only (no in-toto/SLSA statement, no source-SHA/build-identity/environment/SBOM-hash binding, no scoped key identity), and evidence **committed straight back into this same mutable repo** (`siax/production-evidence/*.json`, `siax/source-bundles/*.json` -- nine such commits already existed in this repo's history; deleted in this PR).
This PR replaces that gate with `sax3l/siax-templates`' real, reviewed G17 reference implementation (PR #51, merged to main, plus follow-up fixes #56/#57/#59), following the same pattern already proven on `st0re`, `cl0ud`, `aud0`, `api0`, `h0st`.
## Composition mechanism: pinned-commit checkout at CI runtime
Chosen over a vendored copy (`st0re`/`cl0ud`/`api0`'s mechanism) because 0pt has **zero existing vendoring convention** anywhere in this repo (checked `.gitea/workflows/` and `.siax/` before deciding) -- but **does** already reference the `SIAX_CI_TOKEN` org secret with the exact same `git.siax.io` authenticated-clone idiom this PR reuses (the now-deleted evidence-commit-push step used the identical bearer pattern for a different cross-repo write). Matches `aud0`/`h0st`'s own reasoning. Full writeup in `.siax/hooks/README.md`.
Pinned to `siax-templates` main @ `384e35060b91ea78ec045e14af114abf5d5eb23b`. `release.yml` refuses to run if main has moved past that commit.
## What stayed 0pt-specific
- `.siax/hooks/G17.sh` -- image repo (`git.cloud.siax.io/sax3l/0pt`), key identity, and a license-allowlist **measured against 0pt's own real SBOM** (280 components; not copied from another repo).
- `cd.yml`'s own real signed-artifact wait/verify gate (predates this migration -- polls the registry for `release.yml`'s artifact, verifies before triggering Coolify) is **kept**, only its verify command changed (`cosign verify` on a bare digest -> `cosign verify-attestation --type ...`, since the new gate uses `cosign attest`, not `cosign sign`).
- `cosign.pub` at this repo's root is **UNCHANGED** (see "Correction" below).
- G20 (live-digest-equality) deliberately **not** wired this pass: 0pt has no Coolify application provisioned and no `/version` endpoint -- see `.siax/hooks/README.md` "G20 -- deliberately not wired yet".
## Correction (2nd commit on this branch)
The first commit on this branch mistakenly overwrote this repo's committed `cosign.pub` with a keypair generated only for local verification, then deleted the matching private key with no real handoff -- while inaccurately describing that as a private key "handed to Simon out of band". Neither was true, and doing so would have permanently orphaned the committed public key. The 2nd commit reverts `cosign.pub` to its original value and corrects `.siax/hooks/README.md`. **`COSIGN_PRIVATE_KEY`/`COSIGN_PASSWORD` remain exactly as unprovisioned as they were before this PR** -- that decision (generate fresh, or use whatever Simon may already hold offline) is left to Simon, not made by this migration.
## Real verification performed (local, this migration)
1. Built a real image from this repo's own `Dockerfile` (multi-stage Next.js/node:22-alpine), pushed to a local OCI registry.
2. `syft` SBOM against the resolved digest: **280 components**. License policy: one genuine finding on the first run (`gcompat@1.1.0-r4` -> NCSA, a license this repo's gate had never checked before) -- triaged as the real Alpine OS-substrate license it is and added to the measured allowlist (no `.trivyignore` needed for licenses).
3. `trivy image --scanners vuln,secret,misconfig --severity CRITICAL,HIGH`: **0 findings**. No `.trivyignore` needed -- nothing to suppress.
4. `cosign attest` (real DSSE in-toto Statement, all 5 required predicate fields) + `cosign verify-attestation`, using a throwaway keypair generated solely for this local proof (never committed, deleted afterward -- see "Correction" above). Verification PASSED against that key.
5. Three real tamper-rejection negative controls against this exact artifact, all correctly REJECTED: wrong public key, wrong predicate type, and a digest that was never attested.
6. `emit-release-evidence.py` submitted a real `siax.release-evidence` v1.0 document to a local mock AUD0 server enforcing the actual `eventInputSchema` required-field contract -- HTTP 201.
7. The reference implementation's own `G17.selftest.sh`: **29/29 assertions passed**, including a real live check against production `https://api.aud0.siax.io/v1/aud0/version`.
## Required secrets (not yet set on `sax3l/0pt`, same prerequisite every prior migration needed)
`REGISTRY_USER`/`REGISTRY_TOKEN` (already required by the old gate), `COSIGN_PRIVATE_KEY`/`COSIGN_PASSWORD` (still unprovisioned -- see "Correction"), `AUD0_INGEST_TOKEN`/`AUD0_TENANT_ID` (new requirement -- needs a `siax-svc-g17` Zitadel workload-identity client), `SIAX_CI_TOKEN` (already exists on this repo). Until set, `release.yml` fails closed on its first real run -- same honest behaviour as the gate it replaces.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
CODEOWNERS rules
requested review from sax3l 2026-09-15 15:10:18 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
0pt's own ad hoc "P007 pattern" release chain (
.gitea/workflows/release.yml, added 2026-09-14) genuinely fails the real ADR-W16-003 promotion bar an audit (2026-09-15) checked it against: syft/cosign installed viacurl+ a freshly-refetched checksums file (not a pinned, out-of-band-verified digest), no vulnerability scan of the built digest at all,cosign signon the bare digest only (no in-toto/SLSA statement, no source-SHA/build-identity/environment/SBOM-hash binding, no scoped key identity), and evidence committed straight back into this same mutable repo (siax/production-evidence/*.json,siax/source-bundles/*.json-- nine such commits already existed in this repo's history; deleted in this PR).This PR replaces that gate with
sax3l/siax-templates' real, reviewed G17 reference implementation (PR #51, merged to main, plus follow-up fixes #56/#57/#59), following the same pattern already proven onst0re,cl0ud,aud0,api0,h0st.Composition mechanism: pinned-commit checkout at CI runtime
Chosen over a vendored copy (
st0re/cl0ud/api0's mechanism) because 0pt has zero existing vendoring convention anywhere in this repo (checked.gitea/workflows/and.siax/before deciding) -- but does already reference theSIAX_CI_TOKENorg secret with the exact samegit.siax.ioauthenticated-clone idiom this PR reuses (the now-deleted evidence-commit-push step used the identical bearer pattern for a different cross-repo write). Matchesaud0/h0st's own reasoning. Full writeup in.siax/hooks/README.md.Pinned to
siax-templatesmain @384e35060b91ea78ec045e14af114abf5d5eb23b.release.ymlrefuses to run if main has moved past that commit.What stayed 0pt-specific
.siax/hooks/G17.sh-- image repo (git.cloud.siax.io/sax3l/0pt), key identity, and a license-allowlist measured against 0pt's own real SBOM (280 components; not copied from another repo).cd.yml's own real signed-artifact wait/verify gate (predates this migration -- polls the registry forrelease.yml's artifact, verifies before triggering Coolify) is kept, only its verify command changed (cosign verifyon a bare digest ->cosign verify-attestation --type ..., since the new gate usescosign attest, notcosign sign).cosign.pubat this repo's root is UNCHANGED (see "Correction" below)./versionendpoint -- see.siax/hooks/README.md"G20 -- deliberately not wired yet".Correction (2nd commit on this branch)
The first commit on this branch mistakenly overwrote this repo's committed
cosign.pubwith a keypair generated only for local verification, then deleted the matching private key with no real handoff -- while inaccurately describing that as a private key "handed to Simon out of band". Neither was true, and doing so would have permanently orphaned the committed public key. The 2nd commit revertscosign.pubto its original value and corrects.siax/hooks/README.md.COSIGN_PRIVATE_KEY/COSIGN_PASSWORDremain exactly as unprovisioned as they were before this PR -- that decision (generate fresh, or use whatever Simon may already hold offline) is left to Simon, not made by this migration.Real verification performed (local, this migration)
Dockerfile(multi-stage Next.js/node:22-alpine), pushed to a local OCI registry.syftSBOM against the resolved digest: 280 components. License policy: one genuine finding on the first run (gcompat@1.1.0-r4-> NCSA, a license this repo's gate had never checked before) -- triaged as the real Alpine OS-substrate license it is and added to the measured allowlist (no.trivyignoreneeded for licenses).trivy image --scanners vuln,secret,misconfig --severity CRITICAL,HIGH: 0 findings. No.trivyignoreneeded -- nothing to suppress.cosign attest(real DSSE in-toto Statement, all 5 required predicate fields) +cosign verify-attestation, using a throwaway keypair generated solely for this local proof (never committed, deleted afterward -- see "Correction" above). Verification PASSED against that key.emit-release-evidence.pysubmitted a realsiax.release-evidencev1.0 document to a local mock AUD0 server enforcing the actualeventInputSchemarequired-field contract -- HTTP 201.G17.selftest.sh: 29/29 assertions passed, including a real live check against productionhttps://api.aud0.siax.io/v1/aud0/version.Required secrets (not yet set on
sax3l/0pt, same prerequisite every prior migration needed)REGISTRY_USER/REGISTRY_TOKEN(already required by the old gate),COSIGN_PRIVATE_KEY/COSIGN_PASSWORD(still unprovisioned -- see "Correction"),AUD0_INGEST_TOKEN/AUD0_TENANT_ID(new requirement -- needs asiax-svc-g17Zitadel workload-identity client),SIAX_CI_TOKEN(already exists on this repo). Until set,release.ymlfails closed on its first real run -- same honest behaviour as the gate it replaces.🤖 Generated with Claude Code
siax-bot
CI grön. Godkänner.