-
Notifications
You must be signed in to change notification settings - Fork 0
ci: scan and sign published container images #118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -172,6 +172,7 @@ jobs: | |
| permissions: | ||
| contents: read | ||
| packages: write | ||
| id-token: write # keyless cosign signing via OIDC | ||
| steps: | ||
| - name: Download digests | ||
| uses: actions/download-artifact@v8 | ||
|
|
@@ -202,3 +203,54 @@ jobs: | |
| docker buildx imagetools create \ | ||
| $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ | ||
| $(printf 'ghcr.io/${{ github.repository }}@sha256:%s ' *) | ||
| - name: Install cosign | ||
| uses: sigstore/cosign-installer@v3 | ||
| - name: Sign the published image (keyless) | ||
| run: | | ||
| tag=$(jq -cr '.tags[0]' <<< "$DOCKER_METADATA_OUTPUT_JSON") | ||
| digest=$(docker buildx imagetools inspect "$tag" --format '{{.Manifest.Digest}}') | ||
| cosign sign --yes "ghcr.io/${{ github.repository }}@${digest}" | ||
|
|
||
| # Build the runtime image and scan it for OS/dependency vulnerabilities. | ||
| # Non-blocking for now (exit-code 0): findings surface in the Security tab. | ||
| # Flip exit-code to 1 to gate once the baseline is clean. | ||
| image-scan: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
| name: Image Scan | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| security-events: write | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v4 | ||
| - name: Build image (amd64) for scanning | ||
| uses: docker/build-push-action@v7 | ||
| with: | ||
| context: . | ||
| file: docker/Dockerfile | ||
| platforms: linux/amd64 | ||
| load: true | ||
| tags: postguard-business:scan | ||
| cache-from: type=gha | ||
| # Run Trivy from its official image rather than the GitHub Action, which | ||
| # had a supply-chain compromise advisory (GHSA-69fq-xp46-6x23). | ||
| - name: Trivy vulnerability scan | ||
| run: | | ||
| docker run --rm \ | ||
| -v /var/run/docker.sock:/var/run/docker.sock \ | ||
| -v "$PWD:/work" \ | ||
| aquasec/trivy:latest image \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| --severity HIGH,CRITICAL \ | ||
| --ignore-unfixed \ | ||
| --format sarif \ | ||
| --output /work/trivy-results.sarif \ | ||
| --exit-code 0 \ | ||
| postguard-business:scan | ||
| - name: Upload Trivy results | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
| if: always() | ||
| uses: github/codeql-action/upload-sarif@v3 | ||
| with: | ||
| sarif_file: trivy-results.sarif | ||
| category: trivy | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cosign signruns on PR events too:finalizehas no event filter (if: always() && needs.build.result == 'success'), so every PR signs itspr-Nimage. Keyless cosign records each signature (with commit/actor identity) permanently in the public Rekor transparency log and leaves orphan.sigtags in GHCR for throwaway images. Gate the sign step (or job) withif: github.event_name != 'pull_request'; the PR-run smoke test of the cosign path can be done once rather than on every future PR.