Scan the published image for known vulnerabilities
CI / chart (push) Successful in 1s
CI / test (push) Successful in 25s

terdut-server was the only one of the three release-managed repos with no
image scanning at all. riksdata and rd-web have had a scan-image job since
they were set up; everything published here up to and including v0.9.3 went
out without a CVE check.

It scans the pushed image rather than a locally built one, for the same
reason the siblings do: trivy cannot read a local image on this runner,
since Talos has no docker socket and the dind sidecar shares no filesystem
with the job. So it runs after image rather than gating it, and a red scan
unpublishes nothing. What it means is narrower and worth stating plainly: do
not bump the wrapper chart in Ryuvia/charts to that version.

Checked before wiring it in rather than after. v0.9.3 scans clean at
HIGH,CRITICAL with unfixed findings ignored, so this does not turn the
pipeline red on arrival, and the same command exits 1 on an image that does
have findings — a gate that cannot fail is not a gate.

One platform is scanned, not both. The image is FROM scratch, so there are
no OS packages and trivy sees a single target: the Go binary and its module
graph. linux/amd64 and linux/arm64 are that same module set built for a
different GOARCH, so a finding in one is a finding in both. On an image with
a base layer that reasoning would not hold.

Still no govulncheck and no gitleaks here, which riksdata and rd-web run in
a separate CI job. This is the only security scanning terdut-server has.

Claude-Session: https://claude.ai/code/session_01S7R4gWTz5wh5xCY4nCSJjN
This commit is contained in:
Niklas Ye
2026-09-02 10:04:51 +02:00
parent c6f1fe317e
commit 84146fc903
4 changed files with 72 additions and 6 deletions
+34
View File
@@ -187,3 +187,37 @@ jobs:
set -eu
echo "$TOKEN" | helm registry login "$REGISTRY" -u niklas --password-stdin
make helm-package helm-push VERSION="$REF_NAME"
# Host mode, like image and chart: this needs a docker daemon to run trivy in, and a
# `container:` job would sit on the dind bridge with none.
#
# It scans the pushed image rather than a locally built one, because trivy cannot read a
# local image on this runner -- Talos has no docker socket and the dind sidecar shares no
# filesystem with the job -- so it pulls from the registry. That is also why this runs
# after `image` rather than gating it: a red scan does not unpublish anything.
#
# What a red scan means is therefore not "the release failed" but "do not bump the wrapper
# chart in Ryuvia/charts to this version". The image and chart are already published by
# the time this runs, and deliberately so -- this pipeline does not deploy.
#
# riksdata and rd-web have had this since they were set up; terdut-server went without any
# image scanning until 2026-09-02, so every release before v0.9.4 was published with no
# CVE check at all.
scan-image:
needs: image
runs-on: ubuntu-latest
steps:
- name: Checkout
env:
REF_NAME: ${{ github.ref_name }}
run: git clone --depth=1 --branch "$REF_NAME" "$REPO_URL" .
# Credentials are passed even though these packages are anonymously pullable -- that
# is a property of the personal namespace this publishes to, not something a release
# should depend on staying true.
- name: Scan the pushed image (trivy)
env:
TRIVY_USERNAME: niklas
TRIVY_PASSWORD: ${{ secrets.REGISTRY_TOKEN }}
REF_NAME: ${{ github.ref_name }}
run: make security-image VERSION="$REF_NAME"