From 908d18d3a23d01db8ebd1d581b6b89774b0fe22d Mon Sep 17 00:00:00 2001 From: pos Date: Sat, 5 Sep 2026 17:24:21 +0200 Subject: [PATCH 1/3] M11.2: add fail-closed release ref verifier --- scripts/verify-release-ref.sh | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 scripts/verify-release-ref.sh diff --git a/scripts/verify-release-ref.sh b/scripts/verify-release-ref.sh new file mode 100644 index 0000000..1c6c644 --- /dev/null +++ b/scripts/verify-release-ref.sh @@ -0,0 +1,33 @@ +#!/bin/sh +set -eu + +tag=${1:-${GITHUB_REF_NAME:-}} +expected_sha=${2:-${GITHUB_SHA:-}} + +if [ -z "$tag" ] || [ -z "$expected_sha" ]; then + echo "usage: verify-release-ref.sh " >&2 + exit 2 +fi + +if ! printf '%s\n' "$tag" | grep -Eq '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$'; then + echo "invalid release tag: $tag" >&2 + exit 1 +fi + +actual_sha=$(git rev-parse "${tag}^{commit}" 2>/dev/null) || { + echo "cannot resolve release tag to a commit: $tag" >&2 + exit 1 +} + +if [ "$actual_sha" != "$expected_sha" ]; then + echo "release tag/commit mismatch: tag=$tag actual=$actual_sha expected=$expected_sha" >&2 + exit 1 +fi + +head_sha=$(git rev-parse HEAD) +if [ "$head_sha" != "$expected_sha" ]; then + echo "checkout/commit mismatch: HEAD=$head_sha expected=$expected_sha" >&2 + exit 1 +fi + +printf 'release ref verified: tag=%s commit=%s\n' "$tag" "$expected_sha" From 0da36bba6a5a930f17c1cd347886142469f46b2e Mon Sep 17 00:00:00 2001 From: pos Date: Sat, 5 Sep 2026 17:24:36 +0200 Subject: [PATCH 2/3] M11.2: enforce strict release integrity --- .github/workflows/release.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 79205bc..5dc69f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,6 +19,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + fetch-depth: 0 + + - name: Verify release tag and commit binding + run: sh scripts/verify-release-ref.sh "$GITHUB_REF_NAME" "$GITHUB_SHA" - name: Set up QEMU uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 @@ -44,6 +49,10 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} + labels: | + org.opencontainers.image.source=https://github.com/${{ github.repository }} + org.opencontainers.image.version=${{ github.ref_name }} + org.opencontainers.image.revision=${{ github.sha }} - name: Build and push id: push From adf8c316b4c110f4b861e09cd272a8015c69aa81 Mon Sep 17 00:00:00 2001 From: pos Date: Sat, 5 Sep 2026 17:24:53 +0200 Subject: [PATCH 3/3] M11.2: qualify release integrity policy in CI --- .github/workflows/ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a500241..0baae85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + fetch-depth: 0 - name: Set up Go uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 @@ -30,6 +32,20 @@ jobs: - name: Vet run: go vet ./... + - name: Verify release-ref policy + run: | + git tag m11.2-test "$GITHUB_SHA" + if sh scripts/verify-release-ref.sh m11.2-test "$GITHUB_SHA"; then + echo "non-SemVer tag unexpectedly accepted" >&2 + exit 1 + fi + git tag v0.0.0-m11.2 "$GITHUB_SHA" + sh scripts/verify-release-ref.sh v0.0.0-m11.2 "$GITHUB_SHA" + if sh scripts/verify-release-ref.sh v0.0.0-m11.2 0000000000000000000000000000000000000000; then + echo "tag/commit mismatch unexpectedly accepted" >&2 + exit 1 + fi + - name: Set up QEMU uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3