mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
feat: add SBOM generation and attestation to GitHub workflow (#17277)
Move SBOM generation and attestation to GitHub workflow This PR moves the SBOM generation and attestation process from the `build_docker.sh` script to the GitHub workflow. The change: 1. Removes SBOM generation and attestation from the `build_docker.sh` script 2. Adds a new "SBOM Generation and Attestation" step in the GitHub workflow 3. Generates and attests SBOMs for both multi-arch images and latest tags when applicable This approach ensures SBOM generation happens once for the final multi-architecture image rather than for each architecture separately. Change-Id: I2e15d7322ddec933bbc9bd7880abba9b0842719f Signed-off-by: Thomas Kosiewski <tk@coder.com>
This commit is contained in:
27
.github/workflows/ci.yaml
vendored
27
.github/workflows/ci.yaml
vendored
@ -1180,6 +1180,33 @@ jobs:
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
- name: SBOM Generation and Attestation
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
env:
|
||||||
|
COSIGN_EXPERIMENTAL: 1
|
||||||
|
run: |
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
# Define image base and tags
|
||||||
|
IMAGE_BASE="ghcr.io/coder/coder-preview"
|
||||||
|
TAGS=("${{ steps.build-docker.outputs.tag }}" "main" "latest")
|
||||||
|
|
||||||
|
# Generate and attest SBOM for each tag
|
||||||
|
for tag in "${TAGS[@]}"; do
|
||||||
|
IMAGE="${IMAGE_BASE}:${tag}"
|
||||||
|
SBOM_FILE="coder_sbom_${tag//[:\/]/_}.spdx.json"
|
||||||
|
|
||||||
|
echo "Generating SBOM for image: ${IMAGE}"
|
||||||
|
syft "${IMAGE}" -o spdx-json > "${SBOM_FILE}"
|
||||||
|
|
||||||
|
echo "Attesting SBOM to image: ${IMAGE}"
|
||||||
|
cosign clean "${IMAGE}"
|
||||||
|
cosign attest --type spdxjson \
|
||||||
|
--predicate "${SBOM_FILE}" \
|
||||||
|
--yes \
|
||||||
|
"${IMAGE}"
|
||||||
|
done
|
||||||
|
|
||||||
# GitHub attestation provides SLSA provenance for the Docker images, establishing a verifiable
|
# GitHub attestation provides SLSA provenance for the Docker images, establishing a verifiable
|
||||||
# record that these images were built in GitHub Actions with specific inputs and environment.
|
# record that these images were built in GitHub Actions with specific inputs and environment.
|
||||||
# This complements our existing cosign attestations which focus on SBOMs.
|
# This complements our existing cosign attestations which focus on SBOMs.
|
||||||
|
67
.github/workflows/release.yaml
vendored
67
.github/workflows/release.yaml
vendored
@ -496,6 +496,39 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CODER_BASE_IMAGE_TAG: ${{ steps.image-base-tag.outputs.tag }}
|
CODER_BASE_IMAGE_TAG: ${{ steps.image-base-tag.outputs.tag }}
|
||||||
|
|
||||||
|
- name: SBOM Generation and Attestation
|
||||||
|
if: ${{ !inputs.dry_run }}
|
||||||
|
env:
|
||||||
|
COSIGN_EXPERIMENTAL: "1"
|
||||||
|
run: |
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
# Generate SBOM for multi-arch image with version in filename
|
||||||
|
echo "Generating SBOM for multi-arch image: ${{ steps.build_docker.outputs.multiarch_image }}"
|
||||||
|
syft "${{ steps.build_docker.outputs.multiarch_image }}" -o spdx-json > coder_${{ steps.version.outputs.version }}_sbom.spdx.json
|
||||||
|
|
||||||
|
# Attest SBOM to multi-arch image
|
||||||
|
echo "Attesting SBOM to multi-arch image: ${{ steps.build_docker.outputs.multiarch_image }}"
|
||||||
|
cosign clean "${{ steps.build_docker.outputs.multiarch_image }}"
|
||||||
|
cosign attest --type spdxjson \
|
||||||
|
--predicate coder_${{ steps.version.outputs.version }}_sbom.spdx.json \
|
||||||
|
--yes \
|
||||||
|
"${{ steps.build_docker.outputs.multiarch_image }}"
|
||||||
|
|
||||||
|
# If latest tag was created, also attest it
|
||||||
|
if [[ "${{ steps.build_docker.outputs.created_latest_tag }}" == "true" ]]; then
|
||||||
|
latest_tag="$(./scripts/image_tag.sh --version latest)"
|
||||||
|
echo "Generating SBOM for latest image: ${latest_tag}"
|
||||||
|
syft "${latest_tag}" -o spdx-json > coder_latest_sbom.spdx.json
|
||||||
|
|
||||||
|
echo "Attesting SBOM to latest image: ${latest_tag}"
|
||||||
|
cosign clean "${latest_tag}"
|
||||||
|
cosign attest --type spdxjson \
|
||||||
|
--predicate coder_latest_sbom.spdx.json \
|
||||||
|
--yes \
|
||||||
|
"${latest_tag}"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: GitHub Attestation for Docker image
|
- name: GitHub Attestation for Docker image
|
||||||
id: attest_main
|
id: attest_main
|
||||||
if: ${{ !inputs.dry_run }}
|
if: ${{ !inputs.dry_run }}
|
||||||
@ -612,16 +645,27 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
declare -p publish_args
|
declare -p publish_args
|
||||||
|
|
||||||
|
# Build the list of files to publish
|
||||||
|
files=(
|
||||||
|
./build/*_installer.exe
|
||||||
|
./build/*.zip
|
||||||
|
./build/*.tar.gz
|
||||||
|
./build/*.tgz
|
||||||
|
./build/*.apk
|
||||||
|
./build/*.deb
|
||||||
|
./build/*.rpm
|
||||||
|
./coder_${{ steps.version.outputs.version }}_sbom.spdx.json
|
||||||
|
)
|
||||||
|
|
||||||
|
# Only include the latest SBOM file if it was created
|
||||||
|
if [[ "${{ steps.build_docker.outputs.created_latest_tag }}" == "true" ]]; then
|
||||||
|
files+=(./coder_latest_sbom.spdx.json)
|
||||||
|
fi
|
||||||
|
|
||||||
./scripts/release/publish.sh \
|
./scripts/release/publish.sh \
|
||||||
"${publish_args[@]}" \
|
"${publish_args[@]}" \
|
||||||
--release-notes-file "$CODER_RELEASE_NOTES_FILE" \
|
--release-notes-file "$CODER_RELEASE_NOTES_FILE" \
|
||||||
./build/*_installer.exe \
|
"${files[@]}"
|
||||||
./build/*.zip \
|
|
||||||
./build/*.tar.gz \
|
|
||||||
./build/*.tgz \
|
|
||||||
./build/*.apk \
|
|
||||||
./build/*.deb \
|
|
||||||
./build/*.rpm
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
CODER_GPG_RELEASE_KEY_BASE64: ${{ secrets.GPG_RELEASE_KEY_BASE64 }}
|
CODER_GPG_RELEASE_KEY_BASE64: ${{ secrets.GPG_RELEASE_KEY_BASE64 }}
|
||||||
@ -663,6 +707,15 @@ jobs:
|
|||||||
./build/*.apk
|
./build/*.apk
|
||||||
./build/*.deb
|
./build/*.deb
|
||||||
./build/*.rpm
|
./build/*.rpm
|
||||||
|
./coder_${{ steps.version.outputs.version }}_sbom.spdx.json
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
- name: Upload latest sbom artifact to actions (if dry-run)
|
||||||
|
if: inputs.dry_run && steps.build_docker.outputs.created_latest_tag == 'true'
|
||||||
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||||
|
with:
|
||||||
|
name: latest-sbom-artifact
|
||||||
|
path: ./coder_latest_sbom.spdx.json
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
- name: Send repository-dispatch event
|
- name: Send repository-dispatch event
|
||||||
|
@ -153,17 +153,6 @@ if [[ "$push" == 1 ]]; then
|
|||||||
docker push "$image_tag" 1>&2
|
docker push "$image_tag" 1>&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "--- Generating SBOM for Docker image ($image_tag)"
|
# SBOM generation and attestation moved to the GitHub workflow
|
||||||
syft "$image_tag" -o spdx-json >"${image_tag//[:\/]/_}.spdx.json"
|
|
||||||
|
|
||||||
if [[ "$push" == 1 ]]; then
|
|
||||||
log "--- Attesting SBOM to Docker image for $arch ($image_tag)"
|
|
||||||
COSIGN_EXPERIMENTAL=1 cosign clean "$image_tag"
|
|
||||||
|
|
||||||
COSIGN_EXPERIMENTAL=1 cosign attest --type spdxjson \
|
|
||||||
--predicate "${image_tag//[:\/]/_}.spdx.json" \
|
|
||||||
--yes \
|
|
||||||
"$image_tag"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$image_tag"
|
echo "$image_tag"
|
||||||
|
Reference in New Issue
Block a user