Zion Boggan zionboggan.com ↗

build-sign-verify: syft sbom, grype scan, keyless cosign sign + verify

50fb6dd   Zion Boggan committed on May 4, 2026 (1 month ago)
.github/workflows/build-sign-verify.yml +130 -0
@@ -0,0 +1,130 @@
+name: build-sign-verify
+
+on:
+ push:
+ branches: [main]
+ tags: ["v*"]
+ pull_request:
+ branches: [main]
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+permissions:
+ contents: read
+ packages: write
+ id-token: write
+ attestations: write
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ outputs:
+ digest: ${{ steps.push.outputs.digest }}
+ tags: ${{ steps.meta.outputs.tags }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: docker/setup-buildx-action@v3
+
+ - id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=sha
+ type=ref,event=branch
+ type=semver,pattern={{version}}
+
+ - uses: docker/login-action@v3
+ if: github.event_name != 'pull_request'
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - id: push
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ push: ${{ github.event_name != 'pull_request' }}
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ provenance: true
+ sbom: true
+
+ scan:
+ runs-on: ubuntu-latest
+ needs: build
+ if: github.event_name != 'pull_request'
+ steps:
+ - uses: actions/checkout@v4
+
+ - id: sbom
+ uses: anchore/sbom-action@v0
+ with:
+ image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
+ format: spdx-json
+ output-file: sbom.spdx.json
+
+ - uses: anchore/scan-action@v5
+ id: grype
+ with:
+ image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
+ fail-build: true
+ severity-cutoff: high
+
+ - uses: actions/upload-artifact@v4
+ with:
+ name: sbom
+ path: sbom.spdx.json
+
+ sign:
+ runs-on: ubuntu-latest
+ needs: [build, scan]
+ if: github.event_name != 'pull_request'
+ steps:
+ - uses: sigstore/cosign-installer@v3
+
+ - uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: sign image keyless
+ run: cosign sign --yes ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
+
+ - uses: actions/download-artifact@v4
+ with:
+ name: sbom
+
+ - name: attach sbom attestation
+ run: |
+ cosign attest --yes \
+ --predicate sbom.spdx.json \
+ --type spdxjson \
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
+
+ verify:
+ runs-on: ubuntu-latest
+ needs: [build, sign]
+ if: github.event_name != 'pull_request'
+ steps:
+ - uses: sigstore/cosign-installer@v3
+
+ - name: verify signature and provenance
+ run: |
+ cosign verify \
+ --certificate-identity-regexp "^https://github.com/${{ github.repository_owner }}/" \
+ --certificate-oidc-issuer https://token.actions.githubusercontent.com \
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
+
+ - name: verify sbom attestation
+ run: |
+ cosign verify-attestation \
+ --type spdxjson \
+ --certificate-identity-regexp "^https://github.com/${{ github.repository_owner }}/" \
+ --certificate-oidc-issuer https://token.actions.githubusercontent.com \
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
Makefile +22 -0
@@ -0,0 +1,22 @@
+IMAGE ?= ghcr.io/zionboggan/cicd-supply-chain-security:dev
+OWNER ?= zionboggan
+
+.PHONY: build sbom scan sign verify policy-test
+
+build:
+ docker build -t $(IMAGE) .
+
+sbom:
+ syft $(IMAGE) -o spdx-json=sbom.spdx.json
+
+scan:
+ grype $(IMAGE) --fail-on high
+
+sign:
+ cosign sign --yes $(IMAGE)
+
+verify:
+ OWNER=$(OWNER) ./policy/verify.sh $(IMAGE)
+
+policy-test:
+ kyverno apply policy/kyverno-verify-images.yaml --resource policy/test/pods.yaml