ci: add cosign keyless sigs, SBOM, and provenance attestation

Sign each ISO chunk with cosign keyless OIDC, generate an SPDX SBOM
of the build output, and attach an in-toto build-provenance
attestation. Sigs/certs/SBOM are uploaded alongside the ISO parts in
the ci-latest rolling prerelease so the test/auto-install.sh path
can verify before reassembling.

Action versions are major-version tags (@v3, @v0, @v2). SHA-pinning
is tracked separately to keep this PR small and avoid the long web
lookups that stalled the previous attempt.
This commit is contained in:
veilor-org 2026-05-06 10:40:56 +01:00
parent abb67841f1
commit 25b8d30f35

View file

@ -20,7 +20,9 @@ on:
types: [published] types: [published]
permissions: permissions:
contents: write # needed for action-gh-release to create+update ci-latest contents: write # needed for action-gh-release to create+update ci-latest
id-token: write # cosign keyless OIDC + attest-build-provenance
attestations: write # attest-build-provenance writes the attestation
jobs: jobs:
build: build:
@ -197,6 +199,34 @@ jobs:
echo "[OK] split into:" echo "[OK] split into:"
ls "${ISO}".part-* ls "${ISO}".part-*
- name: Install cosign
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: sigstore/cosign-installer@v3
- name: Sign ISO parts (keyless)
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
run: |
cd build/out
for f in *.part-*; do
cosign sign-blob --yes "$f" \
--output-signature "$f.sig" \
--output-certificate "$f.pem"
done
- name: Generate SBOM (SPDX)
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: anchore/sbom-action@v0
with:
path: build/out
format: spdx-json
output-file: build/out/veilor-os.spdx.json
- name: Build provenance attestation
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: actions/attest-build-provenance@v2
with:
subject-path: 'build/out/*.iso.part-*'
- name: Publish to ci-latest rolling prerelease - name: Publish to ci-latest rolling prerelease
if: success() && github.ref == 'refs/heads/main' if: success() && github.ref == 'refs/heads/main'
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
@ -220,6 +250,9 @@ jobs:
files: | files: |
build/out/*.iso.part-* build/out/*.iso.part-*
build/out/*.sha256 build/out/*.sha256
build/out/*.sig
build/out/*.pem
build/out/*.spdx.json
# Build log on failure: print inline + skip artifact upload to avoid # Build log on failure: print inline + skip artifact upload to avoid
# quota wall. Job log retains everything anyway. # quota wall. Job log retains everything anyway.