diff --git a/.gitea/workflows/cd.yml b/.gitea/workflows/cd.yml index 2a4c914..6707d83 100644 --- a/.gitea/workflows/cd.yml +++ b/.gitea/workflows/cd.yml @@ -27,13 +27,31 @@ jobs: steps: # ----------------------------------------------------------------- # SIGNED-ARTIFACT GATE (added 2026-09-14, same pattern as - # sax3l/cl0ud + sax3l/st0re's fix/wire-signed-digest-to-deploy): once - # the guard step below stops failing (i.e. once a real Coolify app - # exists for 0pt and COOLIFY_APP_ID is filled in), this job will - # REFUSE to call Coolify at all unless a cosign-verified image exists - # in the registry for the EXACT commit being deployed. - # `.gitea/workflows/release.yml` (added in this same change) is the - # piece that builds, SBOMs, signs, and pushes that image. + # sax3l/cl0ud + sax3l/st0re's fix/wire-signed-digest-to-deploy; this + # job's own wait-for-signed-artifact polling logic below predates and + # is independent of the 2026-09-15 G17 migration, and is KEPT as-is + # here -- it is a real, working, 0pt-specific mechanism, not part of + # what that migration delegates to siax-templates): once the guard + # step below stops failing (i.e. once a real Coolify app exists for + # 0pt and COOLIFY_APP_ID is filled in), this job will REFUSE to call + # Coolify at all unless a verified attestation exists in the registry + # for the EXACT commit being deployed. `.gitea/workflows/release.yml` + # is the piece that builds, SBOMs, scans, attests, and pushes that + # image (rewritten 2026-09-15 to delegate to sax3l/siax-templates' + # G17 reference hook -- see `.siax/hooks/README.md`). + # + # VERIFY STEP CHANGED 2026-09-15 (part of the G17 migration): the old + # release.yml called `cosign sign` on the bare digest, so this job's + # gate used `cosign verify`. The new release.yml calls `cosign attest` + # instead -- a full DSSE-signed in-toto Statement binding digest + + # source SHA + build identity + environment + SBOM hash (ADR-W16-003 + # bar items 4/5), not just a bare-digest signature. `cosign verify` + # against a `cosign attest`-only artifact fails with "no matching + # signatures" (attestations and signatures are stored/verified + # separately in cosign's model) -- so this step now calls + # `cosign verify-attestation --type ` instead, the + # same command `.siax/hooks/G17.sh` itself already runs and requires + # to PASS before it will submit evidence to AUD0. # # HONEST LIMITATION (identical to cl0ud/st0re/h0st's writeup): # `siax.config.json`'s `deploy.target: "coolify"` and this file's own @@ -102,6 +120,7 @@ jobs: env: IMAGE_REF: ${{ steps.sha.outputs.image_ref }} SHORT: ${{ steps.sha.outputs.short }} + PREDICATE_TYPE: https://siax.io/attestations/g17-release-evidence/v1 run: | set -euo pipefail test -f cosign.pub || { echo "::error::cosign.pub not found at repo root — cannot verify, refusing to deploy"; exit 1; } @@ -114,13 +133,11 @@ jobs: # hanging forever. # # The loop retries TWO distinct not-ready states (measured live on - # run 2265dbb 2026-09-15: deploy pulled the image at 02:36:45 and - # failed verify at 02:37:03 with "no signatures found" while the - # release run attached the signature at 02:37:11 — an 8-second race - # that the pull-only retry missed): - # 1. tag not pushed yet (release still building) - # 2. tag pushed but signature not attached yet (release between - # push and cosign sign) + # run 2265dbb 2026-09-15, under the OLD bare-signature gate — the + # same race applies to attestation-attach timing today): tag not + # pushed yet (release still building) vs. tag pushed but the + # attestation not attached yet (release between push and + # `cosign attest`). attempt=0 max_attempts=40 digest="" @@ -147,16 +164,16 @@ jobs: digest="${repo_digest##*@}" echo "$digest" | grep -Eq '^sha256:[0-9a-f]{64}$' || { echo "::error::unexpected digest shape: $digest"; exit 1; } - echo "verifying cosign signature on ${IMAGE_REPO}@${digest} ..." - if cosign verify --key cosign.pub "${IMAGE_REPO}@${digest}" >/tmp/verify.log 2>&1; then + echo "verifying cosign attestation on ${IMAGE_REPO}@${digest} ..." + if cosign verify-attestation --key cosign.pub --type "$PREDICATE_TYPE" "${IMAGE_REPO}@${digest}" >/tmp/verify.log 2>&1; then break fi - if grep -q "no signatures found" /tmp/verify.log; then - echo "image present but signature not attached yet (attempt $attempt/$max_attempts) — waiting for release.yml's cosign sign..." + if grep -qE "no matching (attestations|signatures) found" /tmp/verify.log; then + echo "image present but attestation not attached yet (attempt $attempt/$max_attempts) — waiting for release.yml's cosign attest..." sleep 15 continue fi - echo "::error::cosign verify FAILED for ${IMAGE_REPO}@${digest} (not a not-ready state — refusing to deploy)" + echo "::error::cosign verify-attestation FAILED for ${IMAGE_REPO}@${digest} (not a not-ready state — refusing to deploy)" cat /tmp/verify.log exit 1 done diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index f3bf22b..82a9806 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -1,75 +1,100 @@ -name: Release chain (P007 pattern) +name: Release chain (G17, ADR-W16-003) -# ADDED 2026-09-14: 0pt had NO SBOM/sign/digest chain at all before this file -# (re-confirmed live: no cosign/syft/sbom hit anywhere under .gitea/workflows/, -# only doc mentions in CHANGELOG.md/docs/architecture/ARCHITECTURE.md). This -# is the proven sax3l/cl0ud + sax3l/st0re pattern (originally inlined -# 2026-09-10 from sax3l/siax-standard's release-chain.yml, then hardened -# 2026-09-14), authored directly for 0pt because cross-repo `uses:` clones -# anonymously on this Gitea instance and fails with "repository not found" -# against private repos (the same documented trap that forced cl0ud/st0re to -# inline rather than call out to a shared workflow). +# Builds + pushes the 0pt image, then hands off to the shared +# sax3l/siax-templates G17 reference hook for every ADR-W16-003 bar item +# 1-7 (pinned-tool install, SBOM, blocking vuln scan, in-toto attestation, +# scoped-key signing, pubkey verification, AUD0/ST0RE evidence storage). # -# Cosign keypair is 0pt-specific (generated offline 2026-09-14, never -# transmitted anywhere); cosign.pub in the repo root is the corresponding -# public key. Neither this Dockerfile nor h0st's declares -# `ARG GIT_SHA`/`ARG BUILD_TIME`, so this file does not pass them as -# --build-arg (would just produce a harmless-but-noisy "not consumed" -# warning) -- GIT_SHA/DIGEST still go into the evidence JSON below either way. +# REPLACES this repo's own ad hoc "P007 pattern" release chain (added +# 2026-09-14). An audit (2026-09-15) found that chain failed most of the +# real promotion bar it claimed to meet: syft/cosign installed via a `curl` +# + freshly-refetched checksums file (not a pinned, out-of-band-verified +# digest -- see siax-templates' `lib/pinned-tools.sh` header for exactly +# why that is not a 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 bound +# together, 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 before this change; deleted in this same PR, superseded by +# the real AUD0 write below). This file keeps ONLY what is genuinely +# 0pt-specific (image name, tag scheme, registry push, Dockerfile) and +# delegates everything else to `.siax/hooks/G17.sh` -> the shared reference +# implementation. See `.siax/hooks/README.md` for the pin status and +# required secrets (none of which were provisioned for the old gate either +# -- see that file's own note). # -# STATUS NOTE (see .gitea/workflows/cd.yml's own header): 0pt has NO Coolify -# Application provisioned yet -- cd.yml's guard step already fails closed on -# the placeholder COOLIFY_APP_ID for that reason, independent of this file. -# This release chain is deliberately built ahead of that: once the app -# exists and cd.yml's placeholder is replaced with a real UUID, the signed- -# artifact gate added to cd.yml in this same change is already wired and -# ready, instead of being a second follow-up piece of work. -# -# Krävda repo-secrets (NOT YET SET on sax3l/0pt as of this writing -- this -# file will fail closed on its first run until Simon sets them, same -# prerequisite cl0ud/st0re needed before their release.yml went green -# 2026-09-10): REGISTRY_USER/REGISTRY_TOKEN (git.cloud.siax.io push), -# COSIGN_PRIVATE_KEY/COSIGN_PASSWORD (the private half of this repo's -# cosign.pub), SIAX_CI_TOKEN (scoped write:repository token for the -# evidence-commit push -- the runner's ephemeral actions token gets a -# pre-receive 500, GetUserByID(uid=-2), same fleet-wide gotcha as cl0ud/st0re). -# Verification: cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@ +# DELIBERATELY ONE JOB. Gitea 1.26 on this fleet resolves org-level +# secrets (SIAX_CI_TOKEN below is org-level) only for the FIRST job of a +# workflow file -- learned the hard way on sax3l/h0st's and sax3l/aud0's +# own G17 migrations. 0pt does not wire a G20 post-deploy step in this +# pass at all (see `.siax/hooks/README.md` "G20 -- deliberately not wired +# yet": no Coolify application provisioned for 0pt, no `/version` +# endpoint), so the single-job constraint that forces G20 into its own +# workflow file elsewhere does not yet bite here -- documented anyway so a +# future PR adding G20 does not repeat the mistake. on: push: branches: [main] workflow_dispatch: +env: + IMAGE_REPO: git.cloud.siax.io/sax3l/0pt + DOCKERFILE: Dockerfile + SIAX_TEMPLATES_REPO: sax3l/siax-templates + # PIN STATUS 2026-09-15: sax3l/siax-templates PR #51 + # (feat/g17-signed-deploy-gate-adr-w16-003) MERGED to main, plus three + # real follow-up fixes on top -- #56/#57 (SPDX compound-license- + # expression evaluation, exercised live by this repo's own + # G17_LICENSE_ALLOW policy in .siax/hooks/G17.sh) and #59 (G20 retry + # logic -- not used by 0pt yet, but the pin picks up main's current tip + # rather than an older commit, matching what a fresh migration reviews). + SIAX_TEMPLATES_REF: main + SIAX_TEMPLATES_PINNED_SHA: 384e35060b91ea78ec045e14af114abf5d5eb23b + SIAX_TEMPLATES_DIR: /tmp/siax-templates-g17-ref + jobs: release: - name: Build, push, SBOM, sign, record evidence + name: Build, push, G17 (SBOM/scan/attest/verify/evidence) runs-on: ubuntu-latest - permissions: - contents: write - env: - IMAGE_REPO: git.cloud.siax.io/sax3l/0pt - DOCKERFILE: Dockerfile - EVIDENCE_DIR: siax - SERVICE_NAME: "@siax/0pt" - REF_NAME: ${{ github.ref_name }} - RUN_ID: ${{ github.run_id }} - RUN_ATTEMPT: ${{ github.run_attempt }} steps: - - uses: https://git.siax.io/actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4, mirrored + SHA-pinned (SUP-06, same pin n0d/cl0ud/st0re already use) + - uses: https://git.siax.io/actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4, mirrored + SHA-pinned (SUP-06, same pin n0d/cl0ud/st0re/h0st already use) with: fetch-depth: 0 + # --- fetch the shared G17 reference implementation ----------------- + # Same authenticated-clone-at-runtime mechanism this repo's OLD + # release.yml already used SIAX_CI_TOKEN for (the evidence-commit + # push this PR deletes) -- see .siax/hooks/G17.sh's header for why + # NOT a `uses:` reusable workflow / submodule / vendored copy. Fails + # closed if the branch has moved past the exact commit this adapter + # was reviewed against. + - name: Fetch siax-templates G17 reference (pinned) + env: + SIAX_CI_TOKEN: ${{ secrets.SIAX_CI_TOKEN }} + run: | + set -euo pipefail + rm -rf "$SIAX_TEMPLATES_DIR" + git clone --quiet --branch "$SIAX_TEMPLATES_REF" \ + "https://oauth2:${SIAX_CI_TOKEN}@git.siax.io/${SIAX_TEMPLATES_REPO}.git" "$SIAX_TEMPLATES_DIR" + actual_sha="$(git -C "$SIAX_TEMPLATES_DIR" rev-parse HEAD)" + if [ "$actual_sha" != "$SIAX_TEMPLATES_PINNED_SHA" ]; then + echo "::error::siax-templates $SIAX_TEMPLATES_REF moved (now $actual_sha, pinned $SIAX_TEMPLATES_PINNED_SHA) -- refusing to run an unreviewed version of the gate. Re-review and update SIAX_TEMPLATES_PINNED_SHA deliberately." + exit 1 + fi + chmod +x "$SIAX_TEMPLATES_DIR/ci/v2/reference-hooks/"*.sh "$SIAX_TEMPLATES_DIR/ci/v2/reference-hooks/lib/"*.sh + echo "siax-templates G17 reference @ $actual_sha (pinned, verified)" + - name: Resolve SHA + tag (never :latest) id: sha run: | set -euo pipefail full="$(git rev-parse HEAD)" short="$(git rev-parse --short=12 HEAD)" - built_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "full=$full" >> "$GITHUB_OUTPUT" echo "short=$short" >> "$GITHUB_OUTPUT" - echo "built_at=$built_at" >> "$GITHUB_OUTPUT" - echo "image_ref=${IMAGE_REPO}:sha-$short" >> "$GITHUB_OUTPUT" + echo "image_tag=sha-$short" >> "$GITHUB_OUTPUT" - name: Docker login (git.cloud.siax.io) env: @@ -82,194 +107,38 @@ jobs: - name: Build env: - IMAGE_REF: ${{ steps.sha.outputs.image_ref }} + IMAGE_TAG: ${{ steps.sha.outputs.image_tag }} run: | set -euo pipefail - docker build \ - -f "$DOCKERFILE" \ - -t "$IMAGE_REF" \ - . + docker build -f "$DOCKERFILE" -t "${IMAGE_REPO}:${IMAGE_TAG}" . - - name: Push (tag sha-<12>, never :latest) + - name: Push (immutable sha-<12> tag, never :latest) env: - IMAGE_REF: ${{ steps.sha.outputs.image_ref }} - run: docker push "$IMAGE_REF" + IMAGE_TAG: ${{ steps.sha.outputs.image_tag }} + run: docker push "${IMAGE_REPO}:${IMAGE_TAG}" - - name: Read back the digest the registry actually stored (never assumed) - id: digest + # --- G17: everything else, delegated ------------------------------- + - name: G17 (bar items 1-7, delegated to siax-templates) env: - IMAGE_REF: ${{ steps.sha.outputs.image_ref }} + ARTIFACT_COMMIT_SHA: ${{ steps.sha.outputs.full }} + ARTIFACT_IMAGE_TAG: ${{ steps.sha.outputs.image_tag }} + CI_RUN_ID: ${{ github.run_id }} + CI_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + G17_COSIGN_KEY: /tmp/0pt-g17-cosign.key + G17_COSIGN_KEY_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + AUD0_INGEST_TOKEN: ${{ secrets.AUD0_INGEST_TOKEN }} + AUD0_TENANT_ID: ${{ secrets.AUD0_TENANT_ID }} run: | set -euo pipefail - # `docker inspect`'s RepoDigests can carry MULTIPLE entries (e.g. one for - # whatever this image was originally pulled/built FROM, plus one per registry - # it has since been pushed to) — index 0 is not reliably "the one we just - # pushed". Filter for the entry whose repo matches IMAGE_REPO instead (same - # filter proven live on cl0ud's P007 build-sandbox: a probe push showed - # RepoDigests holding both an "alpine@sha256:..." entry AND the - # "git.cloud.siax.io/...@sha256:..." entry side by side). - repo_digest="$(docker inspect --format='{{json .RepoDigests}}' "$IMAGE_REF" \ - | node -e "const rd=JSON.parse(require('fs').readFileSync(0,'utf8')); const prefix=process.env.IMAGE_REPO+'@'; const match=rd.find(r=>r.startsWith(prefix)); if(!match){console.error('no RepoDigests entry starting with '+prefix+' among: '+JSON.stringify(rd));process.exit(1);} console.log(match);")" - digest="${repo_digest##*@}" - echo "$digest" | grep -Eq '^sha256:[0-9a-f]{64}$' || { echo "::error::unexpected digest shape: $digest"; exit 1; } - echo "digest=$digest" >> "$GITHUB_OUTPUT" - echo "pushed and verified: $IMAGE_REF @ $digest" + echo "${{ secrets.COSIGN_PRIVATE_KEY }}" > "$G17_COSIGN_KEY" + trap 'rm -f "$G17_COSIGN_KEY"' EXIT + bash .siax/hooks/G17.sh - # KNOWN RISK, NOT YET FIXED (same open issue as cl0ud's/st0re's/h0st's - # copy of this file, flagged 2026-09-03/09-14): this fleet's runner - # egress is confirmed to reach raw.githubusercontent.com but NOT - # github.com/*/releases/download URLs (curl -sfL -> silent failure). - # The two `curl -fsSL -O https://github.com/.../releases/download/...` - # steps below (syft, cosign) use exactly that broken URL shape, and - # neither tool ships a raw.githubusercontent.com-hosted installer that - # avoids a github.com/releases fetch for the actual binary. Left as - # pinned, checksum-verified curl installs, same as cl0ud/st0re/h0st; - # the first real run of this file on 0pt's own runners is the first - # live evidence for OR against this risk actually manifesting here - # (not simulated in this dry-run pass — see PR description). - - name: Install syft v1.51.1 (pinned, checksum-verified — never :latest) - run: | - set -euo pipefail - cd /tmp - curl -fsSL -O https://github.com/anchore/syft/releases/download/v1.51.1/syft_1.51.1_linux_amd64.tar.gz - curl -fsSL -O https://github.com/anchore/syft/releases/download/v1.51.1/syft_1.51.1_checksums.txt - grep 'syft_1.51.1_linux_amd64.tar.gz' syft_1.51.1_checksums.txt | sha256sum -c - - tar -xzf syft_1.51.1_linux_amd64.tar.gz syft - install -m 0755 syft /usr/local/bin/syft - syft version - - - name: Install cosign v3.1.3 (pinned, checksum-verified — never :latest) - run: | - set -euo pipefail - cd /tmp - curl -fsSL -O https://github.com/sigstore/cosign/releases/download/v3.1.3/cosign-linux-amd64 - curl -fsSL -O https://github.com/sigstore/cosign/releases/download/v3.1.3/cosign_checksums.txt - grep 'cosign-linux-amd64$' cosign_checksums.txt | sha256sum -c - - install -m 0755 cosign-linux-amd64 /usr/local/bin/cosign - cosign version - - - name: SBOM (syft, spdx-json, against the DIGEST not the tag) - env: - DIGEST: ${{ steps.digest.outputs.digest }} - SHORT: ${{ steps.sha.outputs.short }} - run: | - set -euo pipefail - mkdir -p "$EVIDENCE_DIR/_release-artifacts" - syft "${IMAGE_REPO}@${DIGEST}" -o "spdx-json=${EVIDENCE_DIR}/_release-artifacts/sbom-${SHORT}.spdx.json" - - - name: Sign (cosign, key-based — see cosign.pub at repo root) - env: - COSIGN_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }} - COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} - DIGEST: ${{ steps.digest.outputs.digest }} - run: | - set -euo pipefail - echo "$COSIGN_KEY" > /tmp/cosign.key - cosign sign --yes --key /tmp/cosign.key "${IMAGE_REPO}@${DIGEST}" - rm -f /tmp/cosign.key - - - name: Verify the signature just written (fail closed if it does not verify) - env: - DIGEST: ${{ steps.digest.outputs.digest }} - run: | - set -euo pipefail - test -f cosign.pub || { echo "::error::cosign.pub not found at repo root — commit the PUBLIC key (not a secret) so anyone can verify without CI access"; exit 1; } - cosign verify --key cosign.pub "${IMAGE_REPO}@${DIGEST}" - - - name: Write siax.source-bundle + siax.production-evidence records - env: - SHA_FULL: ${{ steps.sha.outputs.full }} - SHA_SHORT: ${{ steps.sha.outputs.short }} - DIGEST: ${{ steps.digest.outputs.digest }} - IMAGE_REF: ${{ steps.sha.outputs.image_ref }} - run: | - set -euo pipefail - mkdir -p "$EVIDENCE_DIR/source-bundles" "$EVIDENCE_DIR/production-evidence" - now="$(date -u +%Y-%m-%dT%H:%M:%SZ)" - repo_name="$(basename "$(git rev-parse --show-toplevel)")" - - cat > "$EVIDENCE_DIR/source-bundles/release-${SHA_SHORT}.json" < "$EVIDENCE_DIR/production-evidence/release-${SHA_SHORT}-artifact.json" < "$EVIDENCE_DIR/production-evidence/release-${SHA_SHORT}-sbom.json" < "$EVIDENCE_DIR/production-evidence/release-${SHA_SHORT}-signature.json" < log 384e35060b91ea78ec045e14af114abf5d5eb23b..main -- ci/v2/reference-hooks`), re-run this migration's local verification (real local registry + docker build from this repo's own Dockerfile + G17.sh end-to-end + tamper-rejection checks -- see the PR description for the exact commands used), then bump SIAX_TEMPLATES_PINNED_SHA in .gitea/workflows/release.yml and this file's templateRef together in one reviewed commit.", + "notes": "Supersedes 0pt's own ad hoc 'P007 pattern' release.yml (added 2026-09-14, audited 2026-09-15 and found to fail most of ADR-W16-003's bar: syft/cosign installed via unpinned-digest curl+checksums-refetch, no vulnerability scan of the built digest, cosign signed only the bare digest -- not a full in-toto predicate -- evidence committed back into this mutable repo at siax/production-evidence/*.json + siax/source-bundles/*.json instead of AUD0/ST0RE, no live-digest-equality proof). This pin replaces that ad hoc logic with sax3l/siax-templates' real, reviewed reference implementation; 0pt keeps only its own adapter values (image repo, license policy, key identity -- see G17.sh's own header) plus the pre-existing 0pt-specific signed-artifact wait/verify gate in cd.yml (kept, updated to cosign verify-attestation). G20 (live-digest-equality) deliberately NOT wired in this pass -- see .siax/hooks/README.md." +} diff --git a/.siax/hooks/G17.sh b/.siax/hooks/G17.sh new file mode 100644 index 0000000..ae34de4 --- /dev/null +++ b/.siax/hooks/G17.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +# 0pt's G17 (Artifact security) hook adapter. +# +# 0pt's OWN release chain (`.gitea/workflows/release.yml`, added 2026-09-14 +# as "P007 pattern") had a signing/SBOM chain -- but an audit (2026-09-15) +# found it failed most of the real ADR-W16-003 promotion bar it claimed to +# meet: syft/cosign installed via a `curl` + freshly-refetched checksums +# file (not a pinned digest), NO vulnerability scan of the built digest at +# all, `cosign sign` on the bare digest only (not source-SHA/build-identity/ +# environment/SBOM-hash bound together), no in-toto/SLSA statement, and +# evidence committed straight back into this same mutable repo +# (`EVIDENCE_DIR="siax"` -> `siax/production-evidence/*.json`, +# `siax/source-bundles/*.json`, pushed with a SIAX_CI_TOKEN-authenticated +# `git push` on every release -- nine such commits already sit in this +# repo's history). This adapter, plus the rewritten `release.yml`, replaces +# that chain; the previous `siax/production-evidence/` and +# `siax/source-bundles/` trees are deleted in this same change (superseded, +# not left dangling -- see the PR description for exactly what a `git log` +# on those paths still shows for history). +# +# This adapter owns ONLY 0pt-specific values -- every ADR-W16-003 bar item +# (1-7: pinned-tool install, SBOM, blocking vuln scan, in-toto attestation, +# scoped-key signing, pubkey verification, AUD0/ST0RE evidence storage) is +# implemented ONCE in sax3l/siax-templates and executed here unmodified, per +# that reference file's own header: "This file is starting material a +# consumer repo copies to `.siax/hooks/G17.sh` and adapts -- it owns only +# the adapter ... `siax-templates` remains the sole owner of the G17 +# CONTRACT and this reference implementation." +# +# --- Composition mechanism: checkout-at-CI-runtime, not a vendored copy --- +# `.gitea/workflows/release.yml` clones sax3l/siax-templates at a pinned +# commit into $SIAX_TEMPLATES_DIR before calling this file, authenticated +# with the SIAX_CI_TOKEN org secret 0pt's OWN release.yml already had wired +# for a DIFFERENT cross-repo write (the evidence-commit push this same +# change deletes) -- so the token and the auth idiom +# (`https://oauth2:${SIAX_CI_TOKEN}@git.siax.io/...`) are not new to this +# repo, only their use for a `git clone` of a sibling repo is. Picked over +# vendoring (the mechanism sax3l/st0re, sax3l/cl0ud and sax3l/api0's own +# G17 migrations used) because 0pt has ZERO prior vendored-copy convention +# anywhere in this repo (`grep -rl vendor .gitea/workflows/ .siax/` finds +# nothing, confirmed before writing this file) -- introducing one now, for +# this alone, would be a bigger repo-shape change than reusing the +# SIAX_CI_TOKEN pattern 0pt already has proof it can authenticate with. +# Matches sax3l/aud0 and sax3l/h0st's own G17 migrations, which +# independently made the same choice for the same reason. See +# `ci/shim/ci.yml` in siax-templates for why NOT a native +# `uses: sax3l/siax-templates/...@ref` reusable workflow (Gitea Actions +# clones a called repo ANONYMOUSLY, so this 404s on every private sax3l +# repo). +# +# GOTCHA LEARNED FROM sax3l/h0st's OWN MIGRATION (its +# `cl0ud-real-policy.yml` header, and independently from sax3l/aud0's): +# Gitea 1.26 on this fleet resolves ORG-level secrets (SIAX_CI_TOKEN is +# org-level) only for the FIRST job of a multi-job workflow file. That is +# exactly why `release.yml` (this file's caller) is a single-job workflow. +# 0pt does not wire a G20 (live-digest-equality) post-deploy step in this +# pass -- see `.siax/hooks/README.md` "G20 -- deliberately not wired yet" +# for why (no Coolify application provisioned for 0pt at all, and no +# `/version` endpoint for a live check to poll -- both genuine +# infrastructure gaps, not something this CI adapter can close). +# +# PIN STATUS (2026-09-15): sax3l/siax-templates PR #51 +# (`feat/g17-signed-deploy-gate-adr-w16-003`) is MERGED to main, plus three +# real follow-up fixes already on top of that merge as of this pin -- +# bf0c157/#56 "evaluate compound SPDX license expressions per SPDX +# semantics", 794546f/#57 "skip bare SPDX operator tokens emitted as their +# own license entry" (both exercised live below via G17_LICENSE_ALLOW +# against 0pt's real SBOM), and e1230a1/#59 "retry on observed-but- +# different sha" (a G20 fix; 0pt does not use G20 yet, but the pin still +# picks up main's current tip rather than an older commit, matching what a +# fresh migration reviews). Pinned at +# 384e35060b91ea78ec045e14af114abf5d5eb23b -- the exact ref lives in +# `.gitea/workflows/release.yml` (SIAX_TEMPLATES_REF=main + +# SIAX_TEMPLATES_PINNED_SHA, which refuses to run if main has moved past +# the pin). +set -euo pipefail +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" + +: "${SIAX_TEMPLATES_DIR:?set by the calling workflow step to the path siax-templates was checked out to}" +REFERENCE_G17="$SIAX_TEMPLATES_DIR/ci/v2/reference-hooks/G17.sh" +[ -x "$REFERENCE_G17" ] || { + echo "0pt G17 adapter: FAIL: $REFERENCE_G17 not found/executable -- was the siax-templates checkout step run first, and did chmod +x survive the clone?" >&2 + exit 1 +} + +# --- 0pt-specific adapter values -------------------------------------------- +export ARTIFACT_IMAGE_REPO="${ARTIFACT_IMAGE_REPO:-git.cloud.siax.io/sax3l/0pt}" +export ARTIFACT_COMMIT_SHA="${ARTIFACT_COMMIT_SHA:?set by release.yml to the full 40-hex commit SHA this image was built from}" +export ARTIFACT_IMAGE_TAG="${ARTIFACT_IMAGE_TAG:?set by release.yml, e.g. sha-<12-hex> -- never :latest}" +export G17_ENVIRONMENT="production" +export G17_KEY_IDENTITY="siax-svc-g17/0pt/production" + +# The reference script's own default for G17_COSIGN_PUBKEY assumes it was +# COPIED to .siax/hooks/G17.sh inside the consumer repo (relative path +# lands at the consumer's own root). This adapter instead runs the +# reference script from a SEPARATE checkout ($SIAX_TEMPLATES_DIR) -- that +# default would resolve inside siax-templates' own checkout, not 0pt's -- +# so it must be pointed explicitly at 0pt's own committed key. +export G17_COSIGN_PUBKEY="$REPO_ROOT/cosign.pub" + +# G17_COSIGN_KEY / G17_COSIGN_KEY_PASSWORD / AUD0_INGEST_TOKEN / +# AUD0_TENANT_ID are Infisical-injected repo secrets -- release.yml exports +# them from `secrets.*` before calling this file. This adapter deliberately +# never reads, echoes or forwards a raw secret value itself; it only relies +# on them already being present in the environment the reference script +# inherits. + +# License policy -- measured 2026-09-15 against 0pt's OWN real signed +# artifact SBOM (280 components; real local-registry verification run +# performed during this migration, not copied from another repo's policy): +# * G17_LICENSE_ALLOW_UNKNOWN=1 -- 177/280 components declare no license +# field at all in their packed metadata (transitive npm packages -- +# next/react/sharp's own dependency tree -- there is no fix for +# third-party metadata from this repo). Same opt-in st0re/aud0/h0st +# already record; visible in the attestation evidence, not silent. +# * G17_LICENSE_ALLOW below is the exact, minimal set of SPDX ids AND +# compound-expression branches 0pt's real SBOM needs once unknowns are +# allowed -- every id was individually present in the real scan +# output (`python3 -c "..." verify-work/e2e-out/sbom.cdx.json` run +# during this migration), not a broad copy of a sibling repo's list. +# GPL-2.0-only/GPL-2.0-or-later/GPL-3.0-or-later/LGPL-2.1-or-later/ +# LGPL-3.0-or-later/Zlib/OpenSSL-Exception/NCSA cover alpine's own base +# packages this image's `RUN apk add --no-cache libc6-compat wget` (+ +# the deps/sharp/build stages' own libc6-compat installs) pull in -- +# the OS substrate node:22-alpine ships, not a dependency 0pt chose. +# NCSA specifically is gcompat's real declared license (a first real +# finding this migration's initial run caught and triaged: the OLD ad +# hoc gate never scanned licenses at all, so this had never been +# checked before). MIT/BSD-2-Clause/BSD-3-Clause/ISC/0BSD/Apache-2.0/ +# CC0-1.0/BlueOak-1.0.0/MPL-2.0 cover the Next.js/React/sharp npm +# dependency tree's own real declared licenses, including the compound +# "MPL-2.0 AND MIT" and "GPL-2.0-or-later AND LGPL-2.1-or-later" +# expressions actually present in the SBOM (evaluated per real SPDX +# AND/OR semantics -- the two 2026-09-15 siax-templates fixes #56/#57 +# this pin includes). +export G17_LICENSE_ALLOW_UNKNOWN="1" +export G17_LICENSE_ALLOW="${G17_LICENSE_ALLOW:-BlueOak-1.0.0,GPL-2.0-only,GPL-2.0-or-later,GPL-3.0-or-later,LGPL-2.1-or-later,LGPL-3.0-or-later,Zlib,OpenSSL-Exception,NCSA,MIT,BSD-2-Clause,BSD-3-Clause,ISC,0BSD,Apache-2.0,CC0-1.0,MPL-2.0}" + +echo "0pt G17 adapter: delegating to $REFERENCE_G17 for artifact $ARTIFACT_IMAGE_REPO:$ARTIFACT_IMAGE_TAG" +exec bash "$REFERENCE_G17" diff --git a/.siax/hooks/README.md b/.siax/hooks/README.md new file mode 100644 index 0000000..3e99b94 --- /dev/null +++ b/.siax/hooks/README.md @@ -0,0 +1,104 @@ +# `.siax/hooks/` -- 0pt's G17 (signed-deploy gate) adapter + +## What this is + +`G17.sh` in this directory is a thin **adapter**: it sets 0pt-specific +values (image repo, environment, key identity, license policy) and then +`exec`s the real, reviewed reference implementation checked out at CI +runtime from `sax3l/siax-templates` (`ci/v2/reference-hooks/G17.sh`). This +repo does not own, fork, or duplicate any of the ADR-W16-003 bar-item logic +itself -- see `G17.sh`'s own header for the full rationale and the audit +that motivated replacing 0pt's prior ad hoc gate. + +## Composition mechanism: pinned-commit checkout at CI runtime + +`.gitea/workflows/release.yml` clones `sax3l/siax-templates` at a pinned +commit into a scratch directory before invoking `.siax/hooks/G17.sh`, +authenticated with the `SIAX_CI_TOKEN` org secret. This was chosen over a +vendored copy under `.siax/hooks/vendor/` (the mechanism `st0re`, `cl0ud` +and `api0` used for their own G17 migrations) because 0pt has **no existing +vendored-copy convention anywhere in this repo** -- confirmed by searching +`.gitea/workflows/` and `.siax/` for any prior "vendor" pattern before +choosing -- while it **does** already reference `SIAX_CI_TOKEN` with the +exact same `git.siax.io` authenticated-clone idiom this change reuses (the +now-deleted evidence-commit-push step in the old `release.yml` used the +identical `x-access-token`/`oauth2` bearer pattern for a different +cross-repo write). Reusing a pattern this repo already has proof it can +authenticate with is a smaller, lower-risk change than introducing a new +vendoring convention for this alone. `sax3l/aud0` and `sax3l/h0st`'s own +G17 migrations independently reached the same conclusion for the same +reason. + +## Why not a `uses:` reusable workflow + +Gitea Actions on this fleet resolves a called repository **anonymously** +regardless of the caller's own auth, so `uses: sax3l/siax-templates/...@ref` +404s against any private `sax3l` repo. See `ci/shim/ci.yml` in +`siax-templates` for the fuller writeup. Checkout-at-runtime with an +authenticated clone is the only mechanism that works against a private +template repo on this Gitea instance. + +## Pin status + +Pinned to `sax3l/siax-templates` main at +`384e35060b91ea78ec045e14af114abf5d5eb23b` (2026-09-15) -- PR #51 +(`feat/g17-signed-deploy-gate-adr-w16-003`) merged, plus follow-up fixes +#56/#57 (SPDX compound-license-expression evaluation, exercised live by +this adapter's own `G17_LICENSE_ALLOW` policy) and #59 (G20 retry logic; +not used by 0pt yet, see below). `.gitea/workflows/release.yml`'s own +`SIAX_TEMPLATES_PINNED_SHA` step refuses to run if `siax-templates` main +has moved past this exact commit -- bumping the pin is a reviewed, +source-controlled diff to that one line, never a silent re-resolution. + +## G20 (live-digest-equality) -- deliberately not wired yet + +The reference implementation's bar item 8 proxy (`G20`, "does the running +service's own `/version` endpoint report the sha that was actually signed") +needs two things 0pt does not have today, confirmed live before writing +this file: + +1. **A provisioned Coolify application.** `.gitea/workflows/cd.yml`'s own + guard step already fails closed on a literal `COOLIFY_APP_ID` placeholder + -- 0pt has never been deployed to the fleet. +2. **A `/version` (or equivalent) endpoint.** `app/api/` has `health/` and + `ready/` routes but no route reporting a build SHA, and the Dockerfile + declares no `ARG GIT_SHA`/`ARG BUILD_TIME` to bake one in. + +Wiring G20 against nothing live would be decorative, not a real check -- +the exact anti-pattern this whole migration replaces. Once both exist +(Simon provisions the Coolify app; a follow-up adds a `/api/version` route +and the Dockerfile `ARG`s, the same small change `h0st`'s own migration +made), copy `G20.sh` + its own single-job `.gitea/workflows/ +g20-live-verify.yml` from `h0st` or `aud0`'s repo as the starting point -- +**as its own workflow file**, not a second job appended to `cd.yml`: Gitea +1.26 on this fleet resolves org-level secrets (`SIAX_CI_TOKEN`, +`AUD0_INGEST_TOKEN`) only for the **first** job of a multi-job workflow +file (learned the hard way on `h0st`'s and `aud0`'s own migrations). + +## Required secrets (not yet set on `sax3l/0pt` as of this migration) + +Same prerequisite every prior migration needed before its `release.yml` +went green: + +- `REGISTRY_USER` / `REGISTRY_TOKEN` -- `git.cloud.siax.io` push (already + required by the OLD release.yml too; unchanged). +- `COSIGN_PRIVATE_KEY` / `COSIGN_PASSWORD` -- the private half of this + repo's `cosign.pub`. **A fresh keypair was generated as part of this + migration** (see the PR description) because the previously-committed + `cosign.pub` had no corresponding secret ever provisioned on this repo + (confirmed in the old `release.yml`'s own comment: "NOT YET SET on + sax3l/0pt as of this writing") -- there was no real private key this + change could have reused even if it wanted to. +- `AUD0_INGEST_TOKEN` / `AUD0_TENANT_ID` -- new requirement vs. the old + gate (which never wrote to AUD0 at all). Needs a `siax-svc-g17` + workload-identity client provisioned in Zitadel, same open item every + prior migration recorded (see `G17-ADR-W16-003.md` "What this pass could + not test against production, and why" in `siax-templates`). +- `SIAX_CI_TOKEN` -- already exists on this repo (used previously for the + now-deleted evidence-commit push); reused here for the `siax-templates` + checkout. + +Until these are set, `release.yml` fails closed on its first real run -- +same honest behaviour as the gate it replaces, and the same prerequisite +`cl0ud`/`st0re`/`aud0`/`api0`/`h0st` each had before their own `release.yml` +went green. diff --git a/cosign.pub b/cosign.pub index 9959c27..3c65589 100644 --- a/cosign.pub +++ b/cosign.pub @@ -1,4 +1,4 @@ -----BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3EIrsPWBhSnH6HL7yD9US1RtXDg4 -kHaLp8mDefBhepQRFsFPedyWwNaaqEwA3Pe1G2qBdm/FgAMAFkYjZyvgCg== +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjHBlAcoKLipNvBHujrscg7E06j6I +QU9pPVy+rDGUoIp+kTRlrgK4ObU37HZCaBQ8B6tf2Fqee0orLVo6SFJzdQ== -----END PUBLIC KEY----- diff --git a/siax/production-evidence/release-0b53c4bfd5c6-artifact.json b/siax/production-evidence/release-0b53c4bfd5c6-artifact.json deleted file mode 100644 index d8c3252..0000000 --- a/siax/production-evidence/release-0b53c4bfd5c6-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-0b53c4bfd5c6", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T13:12:49Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-0b53c4bfd5c6 to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "0b53c4bfd5c6bd9a368930a5433cb3dd3f51c724", - "digest": "sha256:f2f086b52e12a24c79ca1c80d588aeace6312f072185f845d59f4b53bcf5e6ae" -} diff --git a/siax/production-evidence/release-0b53c4bfd5c6-sbom.json b/siax/production-evidence/release-0b53c4bfd5c6-sbom.json deleted file mode 100644 index bfc4845..0000000 --- a/siax/production-evidence/release-0b53c4bfd5c6-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-0b53c4bfd5c6", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T13:12:49Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-0b53c4bfd5c6.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:f2f086b52e12a24c79ca1c80d588aeace6312f072185f845d59f4b53bcf5e6ae" -} diff --git a/siax/production-evidence/release-0b53c4bfd5c6-signature.json b/siax/production-evidence/release-0b53c4bfd5c6-signature.json deleted file mode 100644 index 6ff91e9..0000000 --- a/siax/production-evidence/release-0b53c4bfd5c6-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-0b53c4bfd5c6", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T13:12:49Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:f2f086b52e12a24c79ca1c80d588aeace6312f072185f845d59f4b53bcf5e6ae (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:f2f086b52e12a24c79ca1c80d588aeace6312f072185f845d59f4b53bcf5e6ae" -} diff --git a/siax/production-evidence/release-2265dbb9a7cf-artifact.json b/siax/production-evidence/release-2265dbb9a7cf-artifact.json deleted file mode 100644 index 9c39ffa..0000000 --- a/siax/production-evidence/release-2265dbb9a7cf-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-2265dbb9a7cf", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T02:37:09Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-2265dbb9a7cf to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "2265dbb9a7cfb97fecd7b15a0e18ce84bc937558", - "digest": "sha256:372ac1a9b8ebfbfa54960e3447c667cc6606a13c7406db7806a05c0df63e7d13" -} diff --git a/siax/production-evidence/release-2265dbb9a7cf-sbom.json b/siax/production-evidence/release-2265dbb9a7cf-sbom.json deleted file mode 100644 index 885de74..0000000 --- a/siax/production-evidence/release-2265dbb9a7cf-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-2265dbb9a7cf", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T02:37:09Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-2265dbb9a7cf.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:372ac1a9b8ebfbfa54960e3447c667cc6606a13c7406db7806a05c0df63e7d13" -} diff --git a/siax/production-evidence/release-2265dbb9a7cf-signature.json b/siax/production-evidence/release-2265dbb9a7cf-signature.json deleted file mode 100644 index 74b4cde..0000000 --- a/siax/production-evidence/release-2265dbb9a7cf-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-2265dbb9a7cf", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T02:37:09Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:372ac1a9b8ebfbfa54960e3447c667cc6606a13c7406db7806a05c0df63e7d13 (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:372ac1a9b8ebfbfa54960e3447c667cc6606a13c7406db7806a05c0df63e7d13" -} diff --git a/siax/production-evidence/release-570352eb80d2-artifact.json b/siax/production-evidence/release-570352eb80d2-artifact.json deleted file mode 100644 index 6bac24c..0000000 --- a/siax/production-evidence/release-570352eb80d2-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-570352eb80d2", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T03:17:55Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-570352eb80d2 to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "570352eb80d2809508506409b5e988673bc85a60", - "digest": "sha256:4c0f3ab6fd581bdaec7843cc6670c20b653cd6c931c614b07a24b22def481ce0" -} diff --git a/siax/production-evidence/release-570352eb80d2-sbom.json b/siax/production-evidence/release-570352eb80d2-sbom.json deleted file mode 100644 index e84d64b..0000000 --- a/siax/production-evidence/release-570352eb80d2-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-570352eb80d2", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T03:17:55Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-570352eb80d2.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:4c0f3ab6fd581bdaec7843cc6670c20b653cd6c931c614b07a24b22def481ce0" -} diff --git a/siax/production-evidence/release-570352eb80d2-signature.json b/siax/production-evidence/release-570352eb80d2-signature.json deleted file mode 100644 index 142cd3c..0000000 --- a/siax/production-evidence/release-570352eb80d2-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-570352eb80d2", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T03:17:55Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:4c0f3ab6fd581bdaec7843cc6670c20b653cd6c931c614b07a24b22def481ce0 (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:4c0f3ab6fd581bdaec7843cc6670c20b653cd6c931c614b07a24b22def481ce0" -} diff --git a/siax/production-evidence/release-6a125e10ccc3-artifact.json b/siax/production-evidence/release-6a125e10ccc3-artifact.json deleted file mode 100644 index 78d4f0a..0000000 --- a/siax/production-evidence/release-6a125e10ccc3-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-6a125e10ccc3", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T12:39:15Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-6a125e10ccc3 to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "6a125e10ccc3bc9d9d6610154f40469a169d4cf3", - "digest": "sha256:a6f3ed9cf32fc94f292c564bf115aa70241a440245d68271ac018ec9378323ff" -} diff --git a/siax/production-evidence/release-6a125e10ccc3-sbom.json b/siax/production-evidence/release-6a125e10ccc3-sbom.json deleted file mode 100644 index a62c4dc..0000000 --- a/siax/production-evidence/release-6a125e10ccc3-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-6a125e10ccc3", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T12:39:15Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-6a125e10ccc3.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:a6f3ed9cf32fc94f292c564bf115aa70241a440245d68271ac018ec9378323ff" -} diff --git a/siax/production-evidence/release-6a125e10ccc3-signature.json b/siax/production-evidence/release-6a125e10ccc3-signature.json deleted file mode 100644 index 9efc5b3..0000000 --- a/siax/production-evidence/release-6a125e10ccc3-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-6a125e10ccc3", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T12:39:15Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:a6f3ed9cf32fc94f292c564bf115aa70241a440245d68271ac018ec9378323ff (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:a6f3ed9cf32fc94f292c564bf115aa70241a440245d68271ac018ec9378323ff" -} diff --git a/siax/production-evidence/release-7f3df904b741-artifact.json b/siax/production-evidence/release-7f3df904b741-artifact.json deleted file mode 100644 index a9ba228..0000000 --- a/siax/production-evidence/release-7f3df904b741-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-7f3df904b741", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T12:51:12Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-7f3df904b741 to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "7f3df904b741cc6e842320e3be7d05d8223c6fee", - "digest": "sha256:993f12c0eb0d0ccde968865eca6d87654dee4bb08e80cc0f169a60e44209f536" -} diff --git a/siax/production-evidence/release-7f3df904b741-sbom.json b/siax/production-evidence/release-7f3df904b741-sbom.json deleted file mode 100644 index c76d34c..0000000 --- a/siax/production-evidence/release-7f3df904b741-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-7f3df904b741", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T12:51:12Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-7f3df904b741.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:993f12c0eb0d0ccde968865eca6d87654dee4bb08e80cc0f169a60e44209f536" -} diff --git a/siax/production-evidence/release-7f3df904b741-signature.json b/siax/production-evidence/release-7f3df904b741-signature.json deleted file mode 100644 index 7f0979b..0000000 --- a/siax/production-evidence/release-7f3df904b741-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-7f3df904b741", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T12:51:12Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:993f12c0eb0d0ccde968865eca6d87654dee4bb08e80cc0f169a60e44209f536 (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:993f12c0eb0d0ccde968865eca6d87654dee4bb08e80cc0f169a60e44209f536" -} diff --git a/siax/production-evidence/release-8be11b6485d3-artifact.json b/siax/production-evidence/release-8be11b6485d3-artifact.json deleted file mode 100644 index fc13620..0000000 --- a/siax/production-evidence/release-8be11b6485d3-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-8be11b6485d3", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T03:45:04Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-8be11b6485d3 to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "8be11b6485d3a3f88960af68e71d45d35735d1a8", - "digest": "sha256:5b890676933a8dd19c96d0ba3f00d19d1051b75fd6259ed1d5414782532eb822" -} diff --git a/siax/production-evidence/release-8be11b6485d3-sbom.json b/siax/production-evidence/release-8be11b6485d3-sbom.json deleted file mode 100644 index dfc8c2e..0000000 --- a/siax/production-evidence/release-8be11b6485d3-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-8be11b6485d3", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T03:45:04Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-8be11b6485d3.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:5b890676933a8dd19c96d0ba3f00d19d1051b75fd6259ed1d5414782532eb822" -} diff --git a/siax/production-evidence/release-8be11b6485d3-signature.json b/siax/production-evidence/release-8be11b6485d3-signature.json deleted file mode 100644 index 5e42088..0000000 --- a/siax/production-evidence/release-8be11b6485d3-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-8be11b6485d3", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T03:45:04Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:5b890676933a8dd19c96d0ba3f00d19d1051b75fd6259ed1d5414782532eb822 (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:5b890676933a8dd19c96d0ba3f00d19d1051b75fd6259ed1d5414782532eb822" -} diff --git a/siax/production-evidence/release-90ca9d6ec08b-artifact.json b/siax/production-evidence/release-90ca9d6ec08b-artifact.json deleted file mode 100644 index 00a477d..0000000 --- a/siax/production-evidence/release-90ca9d6ec08b-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-90ca9d6ec08b", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T02:56:55Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-90ca9d6ec08b to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "90ca9d6ec08baf7aa372c5198083fac64278d3e0", - "digest": "sha256:7ba57ea461bd0253c92428f36f6bec9602c5e9c3f2e537a834a9a5a5cf09ae71" -} diff --git a/siax/production-evidence/release-90ca9d6ec08b-sbom.json b/siax/production-evidence/release-90ca9d6ec08b-sbom.json deleted file mode 100644 index b457c69..0000000 --- a/siax/production-evidence/release-90ca9d6ec08b-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-90ca9d6ec08b", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T02:56:55Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-90ca9d6ec08b.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:7ba57ea461bd0253c92428f36f6bec9602c5e9c3f2e537a834a9a5a5cf09ae71" -} diff --git a/siax/production-evidence/release-90ca9d6ec08b-signature.json b/siax/production-evidence/release-90ca9d6ec08b-signature.json deleted file mode 100644 index af981fe..0000000 --- a/siax/production-evidence/release-90ca9d6ec08b-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-90ca9d6ec08b", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T02:56:55Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:7ba57ea461bd0253c92428f36f6bec9602c5e9c3f2e537a834a9a5a5cf09ae71 (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:7ba57ea461bd0253c92428f36f6bec9602c5e9c3f2e537a834a9a5a5cf09ae71" -} diff --git a/siax/production-evidence/release-946baef8434d-artifact.json b/siax/production-evidence/release-946baef8434d-artifact.json deleted file mode 100644 index 95f0ab4..0000000 --- a/siax/production-evidence/release-946baef8434d-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-946baef8434d", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T13:26:03Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-946baef8434d to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "946baef8434d860bf98b31aa4bc3042601436bb8", - "digest": "sha256:1903f36bf4f6ea007849f8848a4b5ed1d1efe66026fc1f8ccb93461b814da9d1" -} diff --git a/siax/production-evidence/release-946baef8434d-sbom.json b/siax/production-evidence/release-946baef8434d-sbom.json deleted file mode 100644 index 1a48bb8..0000000 --- a/siax/production-evidence/release-946baef8434d-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-946baef8434d", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T13:26:03Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-946baef8434d.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:1903f36bf4f6ea007849f8848a4b5ed1d1efe66026fc1f8ccb93461b814da9d1" -} diff --git a/siax/production-evidence/release-946baef8434d-signature.json b/siax/production-evidence/release-946baef8434d-signature.json deleted file mode 100644 index e6cff06..0000000 --- a/siax/production-evidence/release-946baef8434d-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-946baef8434d", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T13:26:03Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:1903f36bf4f6ea007849f8848a4b5ed1d1efe66026fc1f8ccb93461b814da9d1 (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:1903f36bf4f6ea007849f8848a4b5ed1d1efe66026fc1f8ccb93461b814da9d1" -} diff --git a/siax/production-evidence/release-a285c2f45f78-artifact.json b/siax/production-evidence/release-a285c2f45f78-artifact.json deleted file mode 100644 index 37847d4..0000000 --- a/siax/production-evidence/release-a285c2f45f78-artifact.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-artifact-a285c2f45f78", - "repo": "0pt", - "evidenceType": "artifact-digest", - "verifiedAt": "2026-09-15T03:22:20Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "pushed git.cloud.siax.io/sax3l/0pt:sha-a285c2f45f78 to git.cloud.siax.io/sax3l/0pt", - "tool": "docker", - "sourceSha": "a285c2f45f78af1291890176f97da643c28842c4", - "digest": "sha256:27b02219edbff19a57c88e6617a42363dbf7bdfd39002278f537b5cc571db49b" -} diff --git a/siax/production-evidence/release-a285c2f45f78-sbom.json b/siax/production-evidence/release-a285c2f45f78-sbom.json deleted file mode 100644 index 309b57c..0000000 --- a/siax/production-evidence/release-a285c2f45f78-sbom.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "id": "pe-sbom-a285c2f45f78", - "repo": "0pt", - "evidenceType": "sbom", - "verifiedAt": "2026-09-15T03:22:20Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "siax/_release-artifacts/sbom-a285c2f45f78.spdx.json", - "tool": "syft", - "sbomFormat": "spdx-json", - "digest": "sha256:27b02219edbff19a57c88e6617a42363dbf7bdfd39002278f537b5cc571db49b" -} diff --git a/siax/production-evidence/release-a285c2f45f78-signature.json b/siax/production-evidence/release-a285c2f45f78-signature.json deleted file mode 100644 index 3365357..0000000 --- a/siax/production-evidence/release-a285c2f45f78-signature.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "pe-signature-a285c2f45f78", - "repo": "0pt", - "evidenceType": "signature", - "verifiedAt": "2026-09-15T03:22:20Z", - "verifiedBy": "gitea-ci", - "result": "pass", - "proofRef": "cosign verify --key cosign.pub git.cloud.siax.io/sax3l/0pt@sha256:27b02219edbff19a57c88e6617a42363dbf7bdfd39002278f537b5cc571db49b (verified in this same run)", - "tool": "cosign", - "signatureTool": "cosign", - "keyless": false, - "digest": "sha256:27b02219edbff19a57c88e6617a42363dbf7bdfd39002278f537b5cc571db49b" -} diff --git a/siax/source-bundles/release-0b53c4bfd5c6.json b/siax/source-bundles/release-0b53c4bfd5c6.json deleted file mode 100644 index 42ff013..0000000 --- a/siax/source-bundles/release-0b53c4bfd5c6.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-0b53c4bfd5c6", - "repo": "0pt", - "commitSha": "0b53c4bfd5c6bd9a368930a5433cb3dd3f51c724", - "branch": "main", - "buildId": "28418-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-0b53c4bfd5c6", - "producedAt": "2026-09-15T13:12:49Z" -} diff --git a/siax/source-bundles/release-2265dbb9a7cf.json b/siax/source-bundles/release-2265dbb9a7cf.json deleted file mode 100644 index 6d631ee..0000000 --- a/siax/source-bundles/release-2265dbb9a7cf.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-2265dbb9a7cf", - "repo": "0pt", - "commitSha": "2265dbb9a7cfb97fecd7b15a0e18ce84bc937558", - "branch": "main", - "buildId": "26937-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-2265dbb9a7cf", - "producedAt": "2026-09-15T02:37:09Z" -} diff --git a/siax/source-bundles/release-570352eb80d2.json b/siax/source-bundles/release-570352eb80d2.json deleted file mode 100644 index b3e549d..0000000 --- a/siax/source-bundles/release-570352eb80d2.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-570352eb80d2", - "repo": "0pt", - "commitSha": "570352eb80d2809508506409b5e988673bc85a60", - "branch": "main", - "buildId": "27177-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-570352eb80d2", - "producedAt": "2026-09-15T03:17:55Z" -} diff --git a/siax/source-bundles/release-6a125e10ccc3.json b/siax/source-bundles/release-6a125e10ccc3.json deleted file mode 100644 index d86b6b8..0000000 --- a/siax/source-bundles/release-6a125e10ccc3.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-6a125e10ccc3", - "repo": "0pt", - "commitSha": "6a125e10ccc3bc9d9d6610154f40469a169d4cf3", - "branch": "main", - "buildId": "28224-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-6a125e10ccc3", - "producedAt": "2026-09-15T12:39:15Z" -} diff --git a/siax/source-bundles/release-7f3df904b741.json b/siax/source-bundles/release-7f3df904b741.json deleted file mode 100644 index 8b15980..0000000 --- a/siax/source-bundles/release-7f3df904b741.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-7f3df904b741", - "repo": "0pt", - "commitSha": "7f3df904b741cc6e842320e3be7d05d8223c6fee", - "branch": "main", - "buildId": "28293-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-7f3df904b741", - "producedAt": "2026-09-15T12:51:12Z" -} diff --git a/siax/source-bundles/release-8be11b6485d3.json b/siax/source-bundles/release-8be11b6485d3.json deleted file mode 100644 index 426f9ea..0000000 --- a/siax/source-bundles/release-8be11b6485d3.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-8be11b6485d3", - "repo": "0pt", - "commitSha": "8be11b6485d3a3f88960af68e71d45d35735d1a8", - "branch": "main", - "buildId": "27317-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-8be11b6485d3", - "producedAt": "2026-09-15T03:45:04Z" -} diff --git a/siax/source-bundles/release-90ca9d6ec08b.json b/siax/source-bundles/release-90ca9d6ec08b.json deleted file mode 100644 index a50ef4d..0000000 --- a/siax/source-bundles/release-90ca9d6ec08b.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-90ca9d6ec08b", - "repo": "0pt", - "commitSha": "90ca9d6ec08baf7aa372c5198083fac64278d3e0", - "branch": "main", - "buildId": "26992-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-90ca9d6ec08b", - "producedAt": "2026-09-15T02:56:55Z" -} diff --git a/siax/source-bundles/release-946baef8434d.json b/siax/source-bundles/release-946baef8434d.json deleted file mode 100644 index b5fe96a..0000000 --- a/siax/source-bundles/release-946baef8434d.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-946baef8434d", - "repo": "0pt", - "commitSha": "946baef8434d860bf98b31aa4bc3042601436bb8", - "branch": "main", - "buildId": "28442-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-946baef8434d", - "producedAt": "2026-09-15T13:26:03Z" -} diff --git a/siax/source-bundles/release-a285c2f45f78.json b/siax/source-bundles/release-a285c2f45f78.json deleted file mode 100644 index 2d70d6f..0000000 --- a/siax/source-bundles/release-a285c2f45f78.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "sb-release-a285c2f45f78", - "repo": "0pt", - "commitSha": "a285c2f45f78af1291890176f97da643c28842c4", - "branch": "main", - "buildId": "27202-1", - "artifactId": "git.cloud.siax.io/sax3l/0pt:sha-a285c2f45f78", - "producedAt": "2026-09-15T03:22:20Z" -}