HH-462: harden release attestation semantics (#94)

* HH-462: bind release attestations to source and digest

* HH-462: exercise release attestation production paths

---------

Co-authored-by: Rogee <rogee@ipao.vip>
This commit is contained in:
Rogee
2026-08-22 04:07:32 +08:00
committed by GitHub
co-authored by rogee
parent 0e23ccc465
commit b6b1597e90
4 changed files with 494 additions and 36 deletions
+34 -34
View File
@@ -32,11 +32,11 @@ jobs:
cache-dependency-path: backend/go.sum
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
python-version: "3.12.11"
- uses: browser-actions/setup-chrome@48ad923757ca74d66703209fe939badbdf80f2f4 # v2
id: chrome
- name: Install browser harness
run: python -m pip install browser-harness==0.1.9
run: python -m pip install --require-hashes -r .github/requirements-browser-harness.txt
- name: Test Prometheus alert rules
run: docker run --rm --entrypoint promtool -v "$PWD/backend/configs:/configs:ro" prom/prometheus:v3.5.0@sha256:63805ebb8d2b3920190daf1cb14a60871b16fd38bed42b857a3182bc621f4996 test rules /configs/prometheus_alerts_test.yml
- name: Test
@@ -170,7 +170,7 @@ jobs:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 20
node-version: 20.19.5
- run: corepack enable && corepack prepare pnpm@10.2.0 --activate
- run: pnpm install --frozen-lockfile
- name: Test
@@ -239,7 +239,7 @@ jobs:
run: |
docker build -t "$GOCHAT_IMAGE_REF" -f deploy/docker/Dockerfile .
docker build -t shangwutong:production-smoke -f channels/shangwutong/Dockerfile .
docker run -d --name gochat-ci-registry -p 127.0.0.1:5000:5000 registry:2
docker run -d --name gochat-ci-registry -p 127.0.0.1:5000:5000 registry:2@sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373
timeout 30 sh -c 'until curl -fsS http://127.0.0.1:5000/v2/; do sleep 1; done'
docker tag "$GOCHAT_IMAGE_REF" localhost:5000/gochat:production-smoke
docker tag shangwutong:production-smoke localhost:5000/shangwutong:production-smoke
@@ -408,18 +408,29 @@ jobs:
run: |
cosign sign --yes "${{ steps.ref.outputs.image_ref }}"
cosign sign --yes "${{ steps.ref.outputs.shangwutong_image_ref }}"
- name: Verify signatures and attestations
- name: Attest SBOM and provenance
env:
SOURCE_URI: git+https://github.com/${{ github.repository }}.git
SOURCE_REF: ${{ github.ref }}
BUILDER_ID: https://github.com/${{ github.repository }}/.github/workflows/ci.yml@${{ github.ref }}
INVOCATION_ID: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}
run: |
for image_ref in "${{ steps.ref.outputs.image_ref }}" "${{ steps.ref.outputs.shangwutong_image_ref }}"; do
cosign verify \
--certificate-identity-regexp "^https://github.com/${GITHUB_REPOSITORY}/.github/workflows/ci.yml@refs/tags/v" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
"$image_ref"
docker buildx imagetools inspect "$image_ref" --format '{{ json .SBOM }}' | grep -q '"SPDXID"'
provenance=$(docker buildx imagetools inspect "$image_ref" --format '{{ json .Provenance }}')
grep -q '"SLSA"' <<< "$provenance"
grep -q "$GITHUB_SHA" <<< "$provenance"
done
set -euo pipefail
.github/scripts/release_attestation.sh attest-images \
"$SOURCE_URI" "$SOURCE_REF" "$GITHUB_SHA" "$BUILDER_ID" "$INVOCATION_ID" \
"${{ steps.ref.outputs.image_ref }}" "${{ steps.ref.outputs.shangwutong_image_ref }}"
- name: Verify signatures and attestations
env:
SOURCE_URI: git+https://github.com/${{ github.repository }}.git
SOURCE_REF: ${{ github.ref }}
BUILDER_ID: https://github.com/${{ github.repository }}/.github/workflows/ci.yml@${{ github.ref }}
INVOCATION_ID: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}
run: |
set -euo pipefail
identity="https://github.com/${GITHUB_REPOSITORY}/.github/workflows/ci.yml@${GITHUB_REF}"
.github/scripts/release_attestation.sh verify-images \
"$identity" "$SOURCE_URI" "$SOURCE_REF" "$GITHUB_SHA" "$BUILDER_ID" "$INVOCATION_ID" \
"${{ steps.ref.outputs.image_ref }}" "${{ steps.ref.outputs.shangwutong_image_ref }}"
- name: Promote and reverify release tags
env:
GOCHAT_RELEASE_TAGS: ${{ steps.meta.outputs.tags }}
@@ -427,6 +438,10 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PACKAGE_OWNER: ${{ github.repository_owner }}
PACKAGE_OWNER_TYPE: ${{ github.event.repository.owner.type }}
SOURCE_URI: git+https://github.com/${{ github.repository }}.git
SOURCE_REF: ${{ github.ref }}
BUILDER_ID: https://github.com/${{ github.repository }}/.github/workflows/ci.yml@${{ github.ref }}
INVOCATION_ID: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}
run: |
set -euo pipefail
source .github/scripts/release_helpers.sh
@@ -529,25 +544,10 @@ jobs:
crane tag "$source_ref" "$tag"
done
for entry in "${targets[@]}"; do
source_ref=${entry%%|*}
target=${entry#*|}
expected=${source_ref##*@}
actual=$(crane digest "$target")
[[ $actual == "$expected" ]] || {
echo "Digest mismatch: $target resolved to $actual, expected $expected" >&2
exit 1
}
echo "$target -> $actual"
cosign verify \
--certificate-identity-regexp "^https://github.com/${GITHUB_REPOSITORY}/.github/workflows/ci.yml@refs/tags/v" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
"$target"
docker buildx imagetools inspect "$target" --format '{{ json .SBOM }}' | grep -q '"SPDXID"'
provenance=$(docker buildx imagetools inspect "$target" --format '{{ json .Provenance }}')
grep -q '"SLSA"' <<< "$provenance"
grep -q "$GITHUB_SHA" <<< "$provenance"
done
identity="https://github.com/${GITHUB_REPOSITORY}/.github/workflows/ci.yml@${GITHUB_REF}"
.github/scripts/release_attestation.sh verify-promoted \
"$identity" "$SOURCE_URI" "$SOURCE_REF" "$GITHUB_SHA" "$BUILDER_ID" "$INVOCATION_ID" \
"${targets[@]}"
trap - EXIT INT TERM
for repo in "${!cleanup_refs[@]}"; do