diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 6a6a3d3..abf07fe 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -30,7 +30,7 @@ jobs: - name: Install build dependencies run: | - for pkg in make gnu-sed crane; do + for pkg in make gnu-sed crane cosign syft; do brew list --formula "$pkg" &>/dev/null || brew install "$pkg" done gmake --version | head -1 @@ -63,11 +63,15 @@ jobs: - name: Build installer and disk image run: gmake installer - - name: Tag release images - run: gmake release TAG=${{ steps.version.outputs.tag }} + - name: Attest installer image + env: + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + run: gmake attest COSIGN_KEY=<(echo "${{ secrets.COSIGN_PRIVATE_KEY }}") - - name: Run Docker Scout CVE scan - run: gmake scout + - name: Tag release images + env: + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + run: gmake release TAG=${{ steps.version.outputs.tag }} COSIGN_KEY=<(echo "${{ secrets.COSIGN_PRIVATE_KEY }}") - name: Compress disk image run: | @@ -91,11 +95,6 @@ jobs: REPO="${GITHUB_REPOSITORY}" API="${GITEA_URL}/api/v1" - SCOUT_SECTION="" - if [ -f _out/scout-report.md ]; then - SCOUT_SECTION=$(cat _out/scout-report.md) - fi - # Extract component versions from tag (format: v1.12.3-k6.12.47-1) TALOS_VER=$(echo "$TAG" | sed -E 's/^(v[0-9]+\.[0-9]+\.[0-9]+)-.*/\1/') KERNEL_VER=$(echo "$TAG" | sed -E 's/.*-k([0-9]+\.[0-9]+\.[0-9]+)-.*/\1/') @@ -109,10 +108,7 @@ jobs: ## Artifacts - \`metal-arm64.raw.zst\` — Raw disk image for eMMC flashing - - \`docker.io/svrnty/talos-rpi5:${TAG}\` — Installer image for talosctl upgrade - - ## Security Scan - ${SCOUT_SECTION}" + - \`docker.io/svrnty/talos-rpi5:${TAG}\` — Installer image for talosctl upgrade" # Strip leading whitespace from heredoc-style indentation RELEASE_BODY=$(echo "$RELEASE_BODY" | sed 's/^ //') diff --git a/Makefile b/Makefile index a587a25..157a7bb 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ help: @echo " overlay — Build SBC overlay (U-Boot, firmware, DTBs)" @echo " installer — Build Talos installer image + raw disk image" @echo " release — Tag and push release images" - @echo " scout — Run Docker Scout CVE scan on all images" + @echo " attest — Attach SBOM attestation to installer image" @echo " clean — Remove checkouts and build artifacts" @echo "" @echo "Variables:" @@ -188,45 +188,32 @@ installer: --base-installer-image="$(INSTALLER_IMAGE):$(TALOS_TAG)" \ $(IMAGER_COMMON_FLAGS) +# +# Attestation — attach SBOM to crane-pushed images +# +COSIGN_KEY ?= cosign.key + +.PHONY: attest +attest: + syft $(INSTALLER_IMAGE):$(TALOS_TAG) \ + --platform linux/arm64 \ + -o spdx-json=_out/installer-sbom.spdx.json + cosign attest --predicate _out/installer-sbom.spdx.json \ + --type spdxjson \ + --key $(COSIGN_KEY) \ + $(INSTALLER_IMAGE):$(TALOS_TAG) + # # Release — tag images with the Git tag for stable references # .PHONY: release release: - docker pull $(INSTALLER_IMAGE):$(TALOS_TAG) && \ - docker tag $(INSTALLER_IMAGE):$(TALOS_TAG) $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG) && \ - docker push $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG) - -# -# Scout — Docker Scout CVE scan on all pushed images -# -SCOUT_REPORT := _out/scout-report.md -SCOUT_IMAGES := \ - $(KERNEL_IMAGE):$(PKGS_TAG) \ - $(OVERLAY_IMAGE):$(SBCOVERLAY_TAG) \ - $(IMAGER_IMAGE):$(TALOS_TAG) \ - $(INSTALLER_IMAGE):base-$(TALOS_TAG) \ - $(INSTALLER_IMAGE):$(TALOS_TAG) - -.PHONY: scout -scout: - @mkdir -p _out - @if ! docker scout version >/dev/null 2>&1; then \ - echo "Docker Scout not available -- skipping CVE scan." > $(SCOUT_REPORT); \ - exit 0; \ - fi - @echo "# Docker Scout CVE Summary" > $(SCOUT_REPORT) - @echo "" >> $(SCOUT_REPORT) - @for image in $(SCOUT_IMAGES); do \ - echo "Scanning $$image ..."; \ - echo "### $${image##*/}" >> $(SCOUT_REPORT); \ - echo '```' >> $(SCOUT_REPORT); \ - docker scout quickview "$$image" --platform linux/arm64 2>&1 >> $(SCOUT_REPORT) || \ - echo "Scout scan failed for $$image" >> $(SCOUT_REPORT); \ - echo '```' >> $(SCOUT_REPORT); \ - echo "" >> $(SCOUT_REPORT); \ - done - @echo "Scout report written to $(SCOUT_REPORT)" + crane copy $(INSTALLER_IMAGE):$(TALOS_TAG) \ + $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG) + cosign attest --predicate _out/installer-sbom.spdx.json \ + --type spdxjson \ + --key $(COSIGN_KEY) \ + $(REGISTRY)/$(REGISTRY_USERNAME)/$(IMAGE_NAME):$(TAG) # # Clean diff --git a/cosign.pub b/cosign.pub new file mode 100644 index 0000000..d6a2db6 --- /dev/null +++ b/cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPkZxXgi280kakXdVwjygCvIs5chd +Ns/gANqNilq0OZDkmcAzeaKJRkRbiDjqNeW1JLv1CYwN/1olypEdVyjLoQ== +-----END PUBLIC KEY-----