Skip to content

Commit d1d23b1

Browse files
authored
ci: scan and sign published container images (#118)
* ci: scan and sign published container images * ci: run Trivy from its official image (avoids compromised trivy-action) * ci: address review — pin Trivy, gate signing to non-PR, guard SARIF upload, needs build
1 parent bf8be23 commit d1d23b1

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ jobs:
172172
permissions:
173173
contents: read
174174
packages: write
175+
id-token: write # keyless cosign signing via OIDC
175176
steps:
176177
- name: Download digests
177178
uses: actions/download-artifact@v8
@@ -202,3 +203,61 @@ jobs:
202203
docker buildx imagetools create \
203204
$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
204205
$(printf 'ghcr.io/${{ github.repository }}@sha256:%s ' *)
206+
# Sign only on pushes to main/releases — not PRs. Signing every PR would
207+
# record throwaway pr-N images in the public Rekor transparency log and
208+
# leave orphan .sig tags in GHCR. The cosign path was smoke-tested on the
209+
# PR that introduced it (#118).
210+
- name: Install cosign
211+
if: github.event_name != 'pull_request'
212+
uses: sigstore/cosign-installer@v3
213+
- name: Sign the published image (keyless)
214+
if: github.event_name != 'pull_request'
215+
run: |
216+
tag=$(jq -cr '.tags[0]' <<< "$DOCKER_METADATA_OUTPUT_JSON")
217+
digest=$(docker buildx imagetools inspect "$tag" --format '{{.Manifest.Digest}}')
218+
cosign sign --yes "ghcr.io/${{ github.repository }}@${digest}"
219+
220+
# Build the runtime image and scan it for OS/dependency vulnerabilities.
221+
# Non-blocking for now (exit-code 0): findings surface in the Security tab.
222+
# Flip exit-code to 1 to gate once the baseline is clean.
223+
image-scan:
224+
name: Image Scan
225+
needs: build
226+
runs-on: ubuntu-latest
227+
permissions:
228+
contents: read
229+
security-events: write
230+
steps:
231+
- name: Checkout repository
232+
uses: actions/checkout@v6
233+
- name: Set up Docker Buildx
234+
uses: docker/setup-buildx-action@v4
235+
- name: Build image (amd64) for scanning
236+
uses: docker/build-push-action@v7
237+
with:
238+
context: .
239+
file: docker/Dockerfile
240+
platforms: linux/amd64
241+
load: true
242+
tags: postguard-business:scan
243+
cache-from: type=gha
244+
# Run Trivy from its official image rather than the GitHub Action, which
245+
# had a supply-chain compromise advisory (GHSA-69fq-xp46-6x23).
246+
- name: Trivy vulnerability scan
247+
run: |
248+
docker run --rm \
249+
-v /var/run/docker.sock:/var/run/docker.sock \
250+
-v "$PWD:/work" \
251+
aquasec/trivy:0.72.0 image \
252+
--severity HIGH,CRITICAL \
253+
--ignore-unfixed \
254+
--format sarif \
255+
--output /work/trivy-results.sarif \
256+
--exit-code 0 \
257+
postguard-business:scan
258+
- name: Upload Trivy results
259+
if: hashFiles('trivy-results.sarif') != ''
260+
uses: github/codeql-action/upload-sarif@v3
261+
with:
262+
sarif_file: trivy-results.sarif
263+
category: trivy

0 commit comments

Comments
 (0)