From fabc50b26c1ea28074e82ae58db30832d7326520 Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Sat, 19 Sep 2026 22:02:15 +0100 Subject: [PATCH 1/5] Add SBOM and provenance to releases --- .github/workflows/release.yml | 49 ++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2869696..354de33 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,31 +10,68 @@ jobs: build: runs-on: ubuntu-latest permissions: + actions: read + attestations: write contents: write + id-token: write + steps: - uses: actions/checkout@v7 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.0' + php-version: "8.4" extensions: simplexml, zip coverage: none - - name: Install dependencies - run: composer install --no-dev --prefer-dist --no-progress + - name: Install runtime dependencies + run: composer install --no-dev --prefer-dist --no-progress --no-interaction - name: Get tag id: tag - run: echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + run: echo "tag=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" - name: Create package - run: composer archive --format=zip --file="elp-parser-${{ steps.tag.outputs.tag }}" + run: | + composer archive \ + --format=zip \ + --file="elp-parser-${{ steps.tag.outputs.tag }}" + + - name: Generate CycloneDX SBOM + uses: anchore/sbom-action@v0.24.2 + with: + path: . + format: cyclonedx-json + output-file: elp-parser-${{ steps.tag.outputs.tag }}.cdx.json + upload-artifact: false + upload-release-assets: false + + - name: Generate checksums + run: | + sha256sum \ + "elp-parser-${{ steps.tag.outputs.tag }}.zip" \ + "elp-parser-${{ steps.tag.outputs.tag }}.cdx.json" \ + > SHA256SUMS + + - name: Attest build provenance + uses: actions/attest-build-provenance@v4.2.2 + with: + subject-path: elp-parser-${{ steps.tag.outputs.tag }}.zip + + - name: Attest SBOM + uses: actions/attest-sbom@v4.1.0 + with: + subject-path: elp-parser-${{ steps.tag.outputs.tag }}.zip + sbom-path: elp-parser-${{ steps.tag.outputs.tag }}.cdx.json - name: Create Release uses: softprops/action-gh-release@v3 with: - files: elp-parser-${{ steps.tag.outputs.tag }}.zip + files: | + elp-parser-${{ steps.tag.outputs.tag }}.zip + elp-parser-${{ steps.tag.outputs.tag }}.cdx.json + SHA256SUMS draft: false prerelease: false generate_release_notes: true From 1502376f10f59fea88d8694732a06b215e66eab0 Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Sat, 19 Sep 2026 22:02:31 +0100 Subject: [PATCH 2/5] Validate release SBOM artifacts in pull requests --- .github/workflows/release-check.yml | 51 +++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/release-check.yml diff --git a/.github/workflows/release-check.yml b/.github/workflows/release-check.yml new file mode 100644 index 0000000..0f7d1ec --- /dev/null +++ b/.github/workflows/release-check.yml @@ -0,0 +1,51 @@ +name: Supply Chain Check + +on: + pull_request: + paths: + - ".github/workflows/release.yml" + - ".github/workflows/release-check.yml" + - "composer.json" + +permissions: + contents: read + +jobs: + verify-release-artifacts: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v7 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "8.4" + extensions: simplexml, zip + coverage: none + + - name: Install runtime dependencies + run: composer install --no-dev --prefer-dist --no-progress --no-interaction + + - name: Create test package + run: composer archive --format=zip --file=elp-parser-test + + - name: Generate test CycloneDX SBOM + uses: anchore/sbom-action@v0.24.2 + with: + path: . + format: cyclonedx-json + output-file: elp-parser-test.cdx.json + upload-artifact: false + upload-release-assets: false + + - name: Generate and verify checksums + run: | + sha256sum elp-parser-test.zip elp-parser-test.cdx.json > SHA256SUMS + sha256sum --check SHA256SUMS + + - name: Validate CycloneDX document + run: | + jq -e '.bomFormat == "CycloneDX"' elp-parser-test.cdx.json + jq -e '.specVersion != null' elp-parser-test.cdx.json + jq -e '.metadata.component != null' elp-parser-test.cdx.json From e0dd0417cd287144555290768e2fdf8308b010fd Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Sat, 19 Sep 2026 22:02:34 +0100 Subject: [PATCH 3/5] Document release supply chain artifacts --- docs/supply-chain.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 docs/supply-chain.md diff --git a/docs/supply-chain.md b/docs/supply-chain.md new file mode 100644 index 0000000..90053e4 --- /dev/null +++ b/docs/supply-chain.md @@ -0,0 +1,28 @@ +# Release supply chain + +Tagged releases publish more than the Composer archive. + +Each release contains: + +- `elp-parser-.zip` — distributable package archive; +- `elp-parser-.cdx.json` — CycloneDX JSON software bill of materials; +- `SHA256SUMS` — SHA-256 checksums for the archive and SBOM. + +GitHub Artifact Attestations are also created for: + +- build provenance of the ZIP artifact; +- the CycloneDX SBOM bound to that ZIP artifact. + +The attestation actions use GitHub OIDC and repository-scoped workflow permissions; no additional signing key or long-lived secret is stored in the repository. + +## Verify checksums + +```bash +sha256sum --check SHA256SUMS +``` + +## Verify GitHub attestations + +Consumers with the GitHub CLI can verify release artifact attestations using GitHub's artifact-attestation commands against the repository identity. + +A dedicated pull-request workflow builds a test archive, generates the SBOM and validates checksums/CycloneDX structure so release packaging changes are checked before a tag is created. From c8be9c3d9167964079f68561e526dd9cd06f88f0 Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Sat, 19 Sep 2026 22:02:36 +0100 Subject: [PATCH 4/5] Add release supply chain documentation --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index e908822..78b2c1f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -59,6 +59,7 @@ nav: - Guides: - Validation: validation.md - Security: security.md + - Release Supply Chain: supply-chain.md - iDevices: idevices.md - Assets and Package Entries: assets.md - Performance: performance.md From e3554df5f71139a59a2ac35be8409f017a5b50fc Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Sat, 19 Sep 2026 22:02:39 +0100 Subject: [PATCH 5/5] Document release integrity artifacts --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 43aa0d5..b9493fd 100644 --- a/README.md +++ b/README.md @@ -429,6 +429,10 @@ php tests/upstream-compat.php /path/to/exelearning/test/fixtures - [Security policy](SECURITY.md) - [Changelog](CHANGELOG.md) +## Release integrity + +Tagged releases publish a CycloneDX SBOM, SHA-256 checksums and GitHub artifact attestations for build provenance and the SBOM. See [Release supply chain](docs/supply-chain.md). + ## License The project is distributed under the MIT License. See [LICENSE.md](LICENSE.md).