|
68 | 68 | release:
|
69 | 69 | name: release
|
70 | 70 | needs: [build]
|
| 71 | + outputs: |
| 72 | + container_digest: ${{ steps.container_info.outputs.container_digest }} |
| 73 | + container_tags: ${{ steps.container_info.outputs.container_tags }} |
71 | 74 |
|
72 | 75 | runs-on: ubuntu-20.04
|
73 | 76 |
|
|
87 | 90 | with:
|
88 | 91 | cosign-release: 'v1.6.0'
|
89 | 92 |
|
| 93 | + - name: Install Syft |
| 94 | + uses: anchore/sbom-action/[email protected] |
| 95 | + |
90 | 96 | - name: Checkout
|
91 | 97 | uses: actions/checkout@v3
|
92 | 98 | with:
|
@@ -126,6 +132,149 @@ jobs:
|
126 | 132 | GIT_HASH: ${{ steps.release-vars.outputs.GIT_HASH }}
|
127 | 133 | COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
|
128 | 134 |
|
| 135 | + - name: Get container info |
| 136 | + id: container_info |
| 137 | + if: startsWith(github.ref, 'refs/tags/') |
| 138 | + run: | |
| 139 | + export CONTAINER_DIGEST=$(make container-digest GITHUB_REF=${{ github.ref_name }}) |
| 140 | + echo "::set-output name=container_digest::$CONTAINER_DIGEST" |
| 141 | + echo "::set-output name=container_tags::$(make container-tags CONTAINER_DIGEST="${CONTAINER_DIGEST}" | paste -s -d ',' -)" |
| 142 | +
|
129 | 143 | - name: Cleanup signing keys
|
130 | 144 | if: ${{ always() }}
|
131 | 145 | run: rm -f cosign.key
|
| 146 | + |
| 147 | + sbom: |
| 148 | + name: sbom |
| 149 | + needs: [release] |
| 150 | + if: startsWith(github.ref, 'refs/tags/') |
| 151 | + runs-on: ubuntu-20.04 |
| 152 | + env: |
| 153 | + TAGS: "${{ needs.release.outputs.container_tags }}" |
| 154 | + |
| 155 | + steps: |
| 156 | + - name: Install cosign |
| 157 | + |
| 158 | + with: |
| 159 | + cosign-release: 'v1.6.0' |
| 160 | + |
| 161 | + - name: Install Syft |
| 162 | + uses: anchore/sbom-action/[email protected] |
| 163 | + |
| 164 | + - name: Login to ghcr.io |
| 165 | + |
| 166 | + with: |
| 167 | + registry: ghcr.io |
| 168 | + username: ${{ github.actor }} |
| 169 | + password: ${{ secrets.GITHUB_TOKEN }} |
| 170 | + |
| 171 | + - name: Attach SBOM |
| 172 | + env: |
| 173 | + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} |
| 174 | + REPO: ghcr.io/philips-labs/fatt |
| 175 | + run: | |
| 176 | + echo '${{ secrets.COSIGN_PUBLIC_KEY }}' > cosign.pub |
| 177 | + echo '${{ secrets.COSIGN_PRIVATE_KEY }}' > cosign.key |
| 178 | + IFS=, |
| 179 | + for t in ${TAGS}; do |
| 180 | + cosign verify --key cosign.pub ${REPO}:${t} |
| 181 | + syft ${REPO}:${t} -o spdx-json > sbom-spdx.json |
| 182 | + cosign attach sbom --sbom sbom-spdx.json --type spdx ${REPO}:${t} |
| 183 | + cosign attest --predicate sbom-spdx.json --type spdx --key cosign.key ${REPO}:${t} |
| 184 | + cosign verify-attestation -o verified-sbom-spdx.json --key cosign.pub ${REPO}:${t} |
| 185 | + done |
| 186 | +
|
| 187 | + - name: Clean up signing keys |
| 188 | + if: ${{ always() }} |
| 189 | + run: | |
| 190 | + rm -f cosign.key |
| 191 | +
|
| 192 | + provenance: |
| 193 | + name: provenance |
| 194 | + needs: [release] |
| 195 | + if: startsWith(github.ref, 'refs/tags/') |
| 196 | + runs-on: ubuntu-20.04 |
| 197 | + |
| 198 | + steps: |
| 199 | + - name: Generate provenance for Release |
| 200 | + uses: philips-labs/[email protected] |
| 201 | + with: |
| 202 | + command: generate |
| 203 | + subcommand: github-release |
| 204 | + arguments: --artifact-path release-assets --output-path provenance.att --tag-name ${{ github.ref_name }} |
| 205 | + env: |
| 206 | + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" |
| 207 | + |
| 208 | + - name: Install cosign |
| 209 | + |
| 210 | + with: |
| 211 | + cosign-release: 'v1.6.0' |
| 212 | + |
| 213 | + - name: Sign provenance |
| 214 | + run: | |
| 215 | + echo '${{ secrets.COSIGN_PRIVATE_KEY }}' > cosign.key |
| 216 | + cosign sign-blob --key cosign.key --output-signature "${SIGNATURE}" provenance.att |
| 217 | + cat "${SIGNATURE}" |
| 218 | + curl_args=(-s -H "Authorization: token ${GITHUB_TOKEN}") |
| 219 | + curl_args+=(-H "Accept: application/vnd.github.v3+json") |
| 220 | + release_id="$(curl "${curl_args[@]}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases?per_page=10" | jq "map(select(.name == \"${GITHUB_REF_NAME}\"))" | jq -r '.[0].id')" |
| 221 | + echo "Upload ${SIGNATURE} to release with id ${release_id}…" |
| 222 | + curl_args+=(-H "Content-Type: $(file -b --mime-type "${SIGNATURE}")") |
| 223 | + curl "${curl_args[@]}" \ |
| 224 | + --data-binary @"${SIGNATURE}" \ |
| 225 | + "https://uploads.github.com/repos/${GITHUB_REPOSITORY}/releases/${release_id}/assets?name=${SIGNATURE}" |
| 226 | + env: |
| 227 | + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" |
| 228 | + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} |
| 229 | + SIGNATURE: provenance.att.sig |
| 230 | + |
| 231 | + container-provenance: |
| 232 | + name: container-provenance |
| 233 | + needs: [release] |
| 234 | + if: startsWith(github.ref, 'refs/tags/') |
| 235 | + runs-on: ubuntu-20.04 |
| 236 | + env: |
| 237 | + REPO: ghcr.io/philips-labs/fatt |
| 238 | + |
| 239 | + steps: |
| 240 | + - name: Install cosign |
| 241 | + |
| 242 | + with: |
| 243 | + cosign-release: 'v1.6.0' |
| 244 | + |
| 245 | + - name: Generate provenance for ${REPO} |
| 246 | + uses: philips-labs/[email protected] |
| 247 | + with: |
| 248 | + command: generate |
| 249 | + subcommand: container |
| 250 | + arguments: --repository ${REPO} --output-path provenance.att --digest ${{ needs.release.outputs.container_digest }} --tags ${{ needs.release.outputs.container_tags }} |
| 251 | + env: |
| 252 | + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" |
| 253 | + |
| 254 | + - name: Get slsa-provenance predicate |
| 255 | + run: | |
| 256 | + cat provenance.att | jq .predicate > provenance-predicate.att |
| 257 | +
|
| 258 | + - name: Login to ghcr.io |
| 259 | + |
| 260 | + with: |
| 261 | + registry: ghcr.io |
| 262 | + username: ${{ github.actor }} |
| 263 | + password: ${{ secrets.GITHUB_TOKEN }} |
| 264 | + |
| 265 | + - name: Attach provenance to image |
| 266 | + run: | |
| 267 | + echo '${{ secrets.COSIGN_PRIVATE_KEY }}' > cosign.key |
| 268 | + cosign attest --predicate provenance-predicate.att --type slsaprovenance --key cosign.key ${REPO}@${{ needs.release.outputs.container_digest }} |
| 269 | + env: |
| 270 | + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} |
| 271 | + |
| 272 | + - name: Verify attestation |
| 273 | + run: | |
| 274 | + echo '${{ secrets.COSIGN_PUBLIC_KEY }}' > cosign.pub |
| 275 | + cosign verify-attestation --key cosign.pub ${REPO}@${{ needs.release.outputs.container_digest }} |
| 276 | +
|
| 277 | + - name: Cleanup signing keys |
| 278 | + if: ${{ always() }} |
| 279 | + run: | |
| 280 | + rm -f cosign.key |
0 commit comments