Skip to content

feat(ci): add GitHub Actions pipeline with cosign signing, SBOM, and … #1

feat(ci): add GitHub Actions pipeline with cosign signing, SBOM, and …

feat(ci): add GitHub Actions pipeline with cosign signing, SBOM, and … #1

Workflow file for this run

name: CI - Build, Sign, SBOM (GHCR)
on:
push:
branches: [supply-chain-signing]
tags: ["v*"]
workflow_dispatch:
permissions:
contents: read
packages: write # push to GHCR
id-token: write # OIDC token for cosign keyless signing
jobs:
build:
runs-on: ubuntu-latest
outputs:
frontend_digest: ${{ steps.digests.outputs.frontend }}
backend_digest: ${{ steps.digests.outputs.backend }}
steps:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set image tag
id: vars
run: echo "tag=signed-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: Build and push (bake)
id: bake
uses: docker/bake-action@v5
with:
push: true
set: |
frontend.tags=ghcr.io/atkaridarshan04/cloudnative-devops-blueprint/bookstore-frontend:${{ steps.vars.outputs.tag }}
backend.tags=ghcr.io/atkaridarshan04/cloudnative-devops-blueprint/bookstore-backend:${{ steps.vars.outputs.tag }}
- name: Extract pushed image digests
id: digests
run: |
echo "frontend=$(jq -r '.frontend."containerimage.digest"' <<< '${{ steps.bake.outputs.metadata }}')" >> "$GITHUB_OUTPUT"
echo "backend=$(jq -r '.backend."containerimage.digest"' <<< '${{ steps.bake.outputs.metadata }}')" >> "$GITHUB_OUTPUT"
scan-sbom-sign:
needs: build
runs-on: ubuntu-latest
strategy:
matrix:
include:
- key: frontend
image: bookstore-frontend
- key: backend
image: bookstore-backend
env:
DIGEST: ${{ matrix.key == 'frontend' && needs.build.outputs.frontend_digest || needs.build.outputs.backend_digest }}
REF: ghcr.io/atkaridarshan04/cloudnative-devops-blueprint/${{ matrix.image }}
steps:
- name: Trivy image scan
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REF }}@${{ env.DIGEST }}
format: table
exit-code: "0"
- name: Generate SBOM (Syft)
uses: anchore/sbom-action@v0
with:
image: ${{ env.REF }}@${{ env.DIGEST }}
format: spdx-json
output-file: ${{ matrix.image }}-sbom.spdx.json
- uses: sigstore/cosign-installer@v3
- name: Sign image (keyless via GitHub OIDC)
run: cosign sign --yes "${REF}@${DIGEST}"
- name: Attach SBOM attestation
run: |
cosign attest --yes \
--predicate "${{ matrix.image }}-sbom.spdx.json" \
--type spdxjson \
"${REF}@${DIGEST}"