Zion Boggan
repos/CI/CD Supply Chain Security/.github/workflows/build-sign-verify.yml
zionboggan.com ↗
130 lines · yaml
History for this file →
1
name: build-sign-verify
2
 
3
on:
4
  push:
5
    branches: [main]
6
    tags: ["v*"]
7
  pull_request:
8
    branches: [main]
9
 
10
env:
11
  REGISTRY: ghcr.io
12
  IMAGE_NAME: ${{ github.repository }}
13
 
14
permissions:
15
  contents: read
16
  packages: write
17
  id-token: write
18
  attestations: write
19
 
20
jobs:
21
  build:
22
    runs-on: ubuntu-latest
23
    outputs:
24
      digest: ${{ steps.push.outputs.digest }}
25
      tags: ${{ steps.meta.outputs.tags }}
26
    steps:
27
      - uses: actions/checkout@v4
28
 
29
      - uses: docker/setup-buildx-action@v3
30
 
31
      - id: meta
32
        uses: docker/metadata-action@v5
33
        with:
34
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
35
          tags: |
36
            type=sha
37
            type=ref,event=branch
38
            type=semver,pattern={{version}}
39
 
40
      - uses: docker/login-action@v3
41
        if: github.event_name != 'pull_request'
42
        with:
43
          registry: ${{ env.REGISTRY }}
44
          username: ${{ github.actor }}
45
          password: ${{ secrets.GITHUB_TOKEN }}
46
 
47
      - id: push
48
        uses: docker/build-push-action@v6
49
        with:
50
          context: .
51
          push: ${{ github.event_name != 'pull_request' }}
52
          tags: ${{ steps.meta.outputs.tags }}
53
          labels: ${{ steps.meta.outputs.labels }}
54
          provenance: true
55
          sbom: true
56
 
57
  scan:
58
    runs-on: ubuntu-latest
59
    needs: build
60
    if: github.event_name != 'pull_request'
61
    steps:
62
      - uses: actions/checkout@v4
63
 
64
      - id: sbom
65
        uses: anchore/sbom-action@v0
66
        with:
67
          image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
68
          format: spdx-json
69
          output-file: sbom.spdx.json
70
 
71
      - uses: anchore/scan-action@v5
72
        id: grype
73
        with:
74
          image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
75
          fail-build: true
76
          severity-cutoff: high
77
 
78
      - uses: actions/upload-artifact@v4
79
        with:
80
          name: sbom
81
          path: sbom.spdx.json
82
 
83
  sign:
84
    runs-on: ubuntu-latest
85
    needs: [build, scan]
86
    if: github.event_name != 'pull_request'
87
    steps:
88
      - uses: sigstore/cosign-installer@v3
89
 
90
      - uses: docker/login-action@v3
91
        with:
92
          registry: ${{ env.REGISTRY }}
93
          username: ${{ github.actor }}
94
          password: ${{ secrets.GITHUB_TOKEN }}
95
 
96
      - name: sign image keyless
97
        run: cosign sign --yes ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
98
 
99
      - uses: actions/download-artifact@v4
100
        with:
101
          name: sbom
102
 
103
      - name: attach sbom attestation
104
        run: |
105
          cosign attest --yes \
106
            --predicate sbom.spdx.json \
107
            --type spdxjson \
108
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
109
 
110
  verify:
111
    runs-on: ubuntu-latest
112
    needs: [build, sign]
113
    if: github.event_name != 'pull_request'
114
    steps:
115
      - uses: sigstore/cosign-installer@v3
116
 
117
      - name: verify signature and provenance
118
        run: |
119
          cosign verify \
120
            --certificate-identity-regexp "^https://github.com/${{ github.repository_owner }}/" \
121
            --certificate-oidc-issuer https://token.actions.githubusercontent.com \
122
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}
123
 
124
      - name: verify sbom attestation
125
        run: |
126
          cosign verify-attestation \
127
            --type spdxjson \
128
            --certificate-identity-regexp "^https://github.com/${{ github.repository_owner }}/" \
129
            --certificate-oidc-issuer https://token.actions.githubusercontent.com \
130
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ needs.build.outputs.digest }}