From bb7eb58c8f14d8936cae0e968b50ae721516d213 Mon Sep 17 00:00:00 2001 From: SimpleTest Date: Thu, 20 Aug 2026 23:40:28 +0300 Subject: [PATCH] Refresh vulnerable infrastructure runtimes --- Dockerfile | 9 +++++ Dockerfile.backup | 4 +-- Dockerfile.caddy | 4 +-- Dockerfile.mailpit | 64 +++++++++++++++++++++++++++++++++++ Dockerfile.minio | 4 +-- Dockerfile.traefik | 7 ++-- compose.yaml | 7 ++-- deploy/kind/dependencies.yaml | 2 +- docs/dependency-baseline.md | 16 +++++---- docs/operations.md | 19 ++++++++--- scripts/bootstrap-restic.sh | 2 +- scripts/kind-up.sh | 6 ++-- scripts/quality.sh | 53 +++++++++++++++++++++++------ 13 files changed, 161 insertions(+), 36 deletions(-) create mode 100644 Dockerfile.mailpit diff --git a/Dockerfile b/Dockerfile index babbd41..faf25f2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -91,14 +91,23 @@ FROM ${RUNNER_IMAGE} AS final RUN apt-get update \ && apt-get install -y --no-install-recommends \ + bsdutils=1:2.41.5-0+deb13u1 \ ca-certificates=20250419 \ curl=8.14.1-2+deb13u4 \ iproute2=6.15.0-1 \ + libblkid1=2.41.5-0+deb13u1 \ + liblastlog2-2=2.41.5-0+deb13u1 \ + libmount1=2.41.5-0+deb13u1 \ libncurses6=6.5+20250216-2 \ + libsmartcols1=2.41.5-0+deb13u1 \ libsctp1=1.0.21+dfsg-1 \ libstdc++6=14.2.0-19 \ + libuuid1=2.41.5-0+deb13u1 \ locales=2.41-12+deb13u3 \ + login=1:4.16.0-2+really2.41.5-0+deb13u1 \ + mount=2.41.5-0+deb13u1 \ openssl=3.5.6-1~deb13u2 \ + util-linux=2.41.5-0+deb13u1 \ && rm -rf /var/lib/apt/lists/* # Set the locale diff --git a/Dockerfile.backup b/Dockerfile.backup index 7f8b7cf..ec2d3bb 100644 --- a/Dockerfile.backup +++ b/Dockerfile.backup @@ -1,4 +1,4 @@ -FROM golang:1.26.5-alpine3.23@sha256:622e56dbc11a8cfe87cafa2331e9a201877271cbff918af53d3be315f3da88cc AS restic +FROM golang:1.26.7-alpine3.23@sha256:b17af760035fc2f338eed92d448a6c67f2d45438844fc6c60678fa5f99e44b57 AS restic ARG X_TEXT_VERSION=v0.40.0 ARG X_NET_VERSION=v0.57.0 @@ -29,7 +29,7 @@ RUN apk add --no-cache \ libssl3=3.5.7-r0 \ musl=1.2.5-r23 \ musl-utils=1.2.5-r23 \ - postgresql18-client=18.4-r0 \ + postgresql18-client=18.6-r0 \ zlib=1.3.2-r0 COPY --from=restic /out/restic /usr/local/bin/restic diff --git a/Dockerfile.caddy b/Dockerfile.caddy index dd6b53a..69bbd14 100644 --- a/Dockerfile.caddy +++ b/Dockerfile.caddy @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1.20.0 -FROM golang:1.26.5-alpine3.23@sha256:622e56dbc11a8cfe87cafa2331e9a201877271cbff918af53d3be315f3da88cc AS builder +FROM golang:1.26.7-alpine3.23@sha256:b17af760035fc2f338eed92d448a6c67f2d45438844fc6c60678fa5f99e44b57 AS builder ENV CGO_ENABLED=0 ENV GOTOOLCHAIN=local @@ -19,7 +19,7 @@ RUN go mod init who-need-help/caddy-build \ && test "$(go list -m -f '{{.Version}}' golang.org/x/text)" = "$X_TEXT_VERSION" \ && go build \ -trimpath \ - -ldflags="-s -w -X github.com/caddyserver/caddy/v2.CustomVersion=${CADDY_VERSION}-wnh-grpc1.82.1-xtext0.40.0" \ + -ldflags="-s -w -X github.com/caddyserver/caddy/v2.CustomVersion=${CADDY_VERSION}-wnh-go1.26.7-grpc1.82.1-xtext0.40.0" \ -o /out/caddy \ github.com/caddyserver/caddy/v2/cmd/caddy diff --git a/Dockerfile.mailpit b/Dockerfile.mailpit new file mode 100644 index 0000000..75c9d65 --- /dev/null +++ b/Dockerfile.mailpit @@ -0,0 +1,64 @@ +# syntax=docker/dockerfile:1.20.0 + +FROM docker.io/node:24.18.0-bookworm-slim@sha256:6f7b03f7c2c8e2e784dcf9295400527b9b1270fd37b7e9a7285cf83b6951452d AS ui + +ARG MAILPIT_VERSION=v1.30.7 +ARG MAILPIT_SOURCE_SHA256=19366f9b6fb3c8dd8f9c97b2e894133c6fbac2c2fee9657975874a0deab71777 + +ADD --checksum=sha256:19366f9b6fb3c8dd8f9c97b2e894133c6fbac2c2fee9657975874a0deab71777 \ + https://github.com/axllent/mailpit/archive/refs/tags/v1.30.7.tar.gz \ + /tmp/mailpit.tar.gz + +WORKDIR /src + +RUN test "$MAILPIT_SOURCE_SHA256" = "19366f9b6fb3c8dd8f9c97b2e894133c6fbac2c2fee9657975874a0deab71777" \ + && tar -xzf /tmp/mailpit.tar.gz --strip-components=1 \ + && npm ci \ + && npm run package + +FROM golang:1.26.7-alpine3.23@sha256:b17af760035fc2f338eed92d448a6c67f2d45438844fc6c60678fa5f99e44b57 AS builder + +ARG MAILPIT_VERSION=v1.30.7 +ARG X_MOD_VERSION=v0.40.0 + +ENV CGO_ENABLED=0 +ENV GOTOOLCHAIN=local + +COPY --from=ui /src /src +WORKDIR /src + +RUN go get "golang.org/x/mod@${X_MOD_VERSION}" \ + && test "$(go list -m -f '{{.Version}}' golang.org/x/mod)" = "$X_MOD_VERSION" \ + && go build \ + -trimpath \ + -ldflags "-s -w -X github.com/axllent/mailpit/config.Version=${MAILPIT_VERSION}-wnh-go1.26.7-xmod0.40.0" \ + -o /out/mailpit + +FROM alpine:3.24.1@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b AS runtime_files + +RUN apk add --no-cache \ + ca-certificates=20260611-r0 \ + tzdata=2026c-r0 + +FROM scratch + +LABEL org.opencontainers.image.title="Mailpit" \ + org.opencontainers.image.description="An email and SMTP testing tool for Who Need Help development" \ + org.opencontainers.image.source="https://github.com/axllent/mailpit" \ + org.opencontainers.image.url="https://mailpit.axllent.org" \ + org.opencontainers.image.documentation="https://mailpit.axllent.org/docs/" \ + org.opencontainers.image.licenses="MIT" + +ENV HOME=/tmp + +COPY --from=runtime_files /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=runtime_files /usr/share/zoneinfo /usr/share/zoneinfo +COPY --from=builder /out/mailpit /mailpit + +USER 65534:65534 + +EXPOSE 1025/tcp 1110/tcp 8025/tcp + +HEALTHCHECK --interval=15s --start-period=10s --start-interval=1s CMD ["/mailpit", "readyz"] + +ENTRYPOINT ["/mailpit"] diff --git a/Dockerfile.minio b/Dockerfile.minio index 3e7ef7c..825c27a 100644 --- a/Dockerfile.minio +++ b/Dockerfile.minio @@ -1,4 +1,4 @@ -FROM golang:1.26.5-alpine3.23@sha256:622e56dbc11a8cfe87cafa2331e9a201877271cbff918af53d3be315f3da88cc AS minio_builder +FROM golang:1.26.7-alpine3.23@sha256:b17af760035fc2f338eed92d448a6c67f2d45438844fc6c60678fa5f99e44b57 AS minio_builder ARG X_TEXT_VERSION=v0.40.0 ARG X_CRYPTO_VERSION=v0.54.0 @@ -36,7 +36,7 @@ RUN tar --extract --gzip --file /tmp/minio.tar.gz \ -X github.com/minio/minio/cmd.ShortCommitID=9e49d5e7a648" \ -o /out/minio . -FROM golang:1.26.5-alpine3.23@sha256:622e56dbc11a8cfe87cafa2331e9a201877271cbff918af53d3be315f3da88cc AS mc_builder +FROM golang:1.26.7-alpine3.23@sha256:b17af760035fc2f338eed92d448a6c67f2d45438844fc6c60678fa5f99e44b57 AS mc_builder ARG X_TEXT_VERSION=v0.40.0 ARG X_CRYPTO_VERSION=v0.54.0 diff --git a/Dockerfile.traefik b/Dockerfile.traefik index 1ec0f4d..e9ac788 100644 --- a/Dockerfile.traefik +++ b/Dockerfile.traefik @@ -1,11 +1,12 @@ # syntax=docker/dockerfile:1.20.0 -FROM golang:1.26.5-alpine3.23@sha256:622e56dbc11a8cfe87cafa2331e9a201877271cbff918af53d3be315f3da88cc AS builder +FROM golang:1.26.7-alpine3.23@sha256:b17af760035fc2f338eed92d448a6c67f2d45438844fc6c60678fa5f99e44b57 AS builder ARG TRAEFIK_VERSION=v3.7.10 ARG TRAEFIK_SOURCE_SHA256=31e0e2fbdccd3170b3bc5c3d233a08585bcbc5ede8f753d12a5999d69c21cdd6 ARG TRAEFIK_BUILD_DATE=2026-07-31_12:49:21PM ARG GRPC_GO_VERSION=v1.82.1 +ARG X_MOD_VERSION=v0.40.0 ADD --checksum=sha256:31e0e2fbdccd3170b3bc5c3d233a08585bcbc5ede8f753d12a5999d69c21cdd6 \ https://github.com/traefik/traefik/releases/download/v3.7.10/traefik-v3.7.10.src.tar.gz \ @@ -16,10 +17,12 @@ WORKDIR /src RUN test "$TRAEFIK_SOURCE_SHA256" = "31e0e2fbdccd3170b3bc5c3d233a08585bcbc5ede8f753d12a5999d69c21cdd6" \ && tar -xzf /tmp/traefik.tar.gz --strip-components=1 \ && go get "google.golang.org/grpc@${GRPC_GO_VERSION}" \ + && go get "golang.org/x/mod@${X_MOD_VERSION}" \ && test "$(go list -m -f '{{.Version}}' google.golang.org/grpc)" = "$GRPC_GO_VERSION" \ + && test "$(go list -m -f '{{.Version}}' golang.org/x/mod)" = "$X_MOD_VERSION" \ && CGO_ENABLED=0 go build \ -trimpath \ - -ldflags "-s -w -X github.com/traefik/traefik/v3/pkg/version.Version=${TRAEFIK_VERSION}-wnh-grpc1.82.1 -X github.com/traefik/traefik/v3/pkg/version.BuildDate=${TRAEFIK_BUILD_DATE}" \ + -ldflags "-s -w -X github.com/traefik/traefik/v3/pkg/version.Version=${TRAEFIK_VERSION}-wnh-grpc1.82.1-xmod0.40.0 -X github.com/traefik/traefik/v3/pkg/version.BuildDate=${TRAEFIK_BUILD_DATE}" \ -installsuffix nocgo \ -o /out/traefik \ ./cmd/traefik diff --git a/compose.yaml b/compose.yaml index 0e0b91d..01b10b6 100644 --- a/compose.yaml +++ b/compose.yaml @@ -100,7 +100,7 @@ services: restart: unless-stopped proxy: - image: who-need-help:traefik-v3.7.10-grpc1.82.1 + image: who-need-help:traefik-v3.7.10-grpc1.82.1-xmod0.40.0 build: context: . dockerfile: Dockerfile.traefik @@ -157,7 +157,10 @@ services: restart: unless-stopped mailpit: - image: axllent/mailpit:v1.30.4@sha256:5a49a77c5bdbe7c5474450b4f46348d09949df3695257729c93a30369382d4f6 + image: who-need-help:mailpit-v1.30.7-go1.26.7-xmod0.40.0 + build: + context: . + dockerfile: Dockerfile.mailpit user: "65534:65534" ports: - "${MAILPIT_BIND_ADDRESS:-127.0.0.1}:${MAILPIT_PORT:-8027}:8025" diff --git a/deploy/kind/dependencies.yaml b/deploy/kind/dependencies.yaml index fd1f7c7..f944f89 100644 --- a/deploy/kind/dependencies.yaml +++ b/deploy/kind/dependencies.yaml @@ -93,7 +93,7 @@ spec: type: RuntimeDefault containers: - name: mailpit - image: axllent/mailpit:v1.30.4@sha256:5a49a77c5bdbe7c5474450b4f46348d09949df3695257729c93a30369382d4f6 + image: who-need-help:mailpit-v1.30.7-go1.26.7-xmod0.40.0 imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false diff --git a/docs/dependency-baseline.md b/docs/dependency-baseline.md index 5ea6437..0fd26b1 100644 --- a/docs/dependency-baseline.md +++ b/docs/dependency-baseline.md @@ -38,18 +38,20 @@ package checksums are in `mix.lock` and `assets/package-lock.json`. | --- | --- | | PostgreSQL | 18.4 | | PostGIS | 3.6.4 | -| Traefik | 3.7.10 | -| Mailpit | 1.30.4 | +| Caddy | 2.11.4, rebuilt with Go 1.26.7 | +| Traefik | 3.7.10, rebuilt with Go 1.26.7, gRPC-Go 1.82.1, and `golang.org/x/mod` 0.40.0 | +| Mailpit | 1.30.7, rebuilt with Go 1.26.7 and `golang.org/x/mod` 0.40.0 | | k6 load generator | 2.1.0 | | Prometheus | 3.13.1 | | Alertmanager | 0.33.1 | | Grafana | 13.1.0 | | Python alert/external-mock runtime | 3.14.6 / Alpine 3.23 | -| Restic | 0.19.1, rebuilt with Go 1.26.5 and `golang.org/x/net` 0.57.0 | -| MinIO server | RELEASE.2025-10-15T17-29-55Z, rebuilt with Go 1.26.5 | -| MinIO client | RELEASE.2025-08-13T08-35-41Z, rebuilt with Go 1.26.5 | -| Backup runtime | Alpine 3.23.3 / PostgreSQL client 18.4-r0 | +| Restic | 0.19.1, rebuilt with Go 1.26.7 and `golang.org/x/net` 0.57.0 | +| MinIO server | RELEASE.2025-10-15T17-29-55Z, rebuilt with Go 1.26.7 | +| MinIO client | RELEASE.2025-08-13T08-35-41Z, rebuilt with Go 1.26.7 | +| Backup runtime | Alpine 3.23.3 / PostgreSQL client 18.6-r0 | | Debian builder/runner snapshot | trixie-20260713-slim | +| Debian release `util-linux` security packages | 2.41.5-0+deb13u1 | Every external Compose/kind service image and every Dockerfile base image is locked to both an exact tag and an OCI digest. The observed local Docker tooling @@ -101,7 +103,7 @@ because the official SDK channel identifies it as a QPR beta. | ShellCheck | 0.11.0 | | Hadolint | 2.14.0 | | actionlint | 1.7.12 | -| Trivy | 0.72.0 | +| Trivy | 0.74.0 | | Credo | 1.7.19 | | Dialyxir | 1.4.7 | | Sobelow | 0.14.1 | diff --git a/docs/operations.md b/docs/operations.md index cab4280..d696e2c 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -606,8 +606,8 @@ Restic credentials in ignored `output/runtime/load.env` and restricts that file `0600`. MinIO publishes Docker-assigned ports only on `127.0.0.1`; the observed API and console URLs are printed after a successful run. -The backup tool combines the matching PostgreSQL 18 client with pinned Restic -rebuilt on Go 1.26.5. MinIO server and client are also rebuilt as non-root +The backup tool combines the PostgreSQL 18.6 client with pinned Restic +rebuilt on Go 1.26.7. MinIO server and client are also rebuilt as non-root Alpine images from checksum-pinned upstream source commits with the exact dependency updates recorded in `Dockerfile.minio`. The quality gate verifies their reported release, commit, Go runtime, configured user, and current @@ -1138,8 +1138,11 @@ curl --fail \ The endpoint returns `401` without the exact token, disables response caching, and does not put the credential in a URL. The reporter exports cumulative HTTP request and duration, router exception, database query and duration, WebSocket -connection, Oban job, aggregate single-email delivery outcome, VM memory, and -scheduler run-queue metrics. Email metrics retain the adapter-level `ok`/`error` +connection, Oban attempt and stop outcome, aggregate single-email delivery +outcome, VM memory, and scheduler run-queue metrics. The Oban outcome series +distinguishes the fixed `success`, `cancelled`, `discard`, and `snoozed` stop +states without job arguments or identifiers; exception attempts remain a +separate counter. Email metrics retain the adapter-level `ok`/`error` counter and exception counter, and also expose the application's fixed allow-listed delivery purpose together with `ok`, `error`, or `exception`. Purpose labels are code-defined values such as `auth_login`, @@ -1228,6 +1231,14 @@ references, or user identifiers. The panel is intended to answer which bounded workflow is creating delivery volume or failures; it is not a user-activity log. +The metrics endpoint also exposes cumulative rate-limit bucket checks grouped +only by the configured action name and the bounded `allowed` or `limited` +outcome. It never labels a metric with the hashed scope, email address, client +address, user identifier, bucket count, or reset timestamp. Use these counters +to observe which pilot policies affect real traffic before changing their +limits; the counters do not by themselves establish an abuse policy or a safe +capacity threshold. + Support conversations deliberately do not send one email per staff message. The requester receives an email for the first staff response and for later public status changes; additional messages while the status is unchanged stay diff --git a/scripts/bootstrap-restic.sh b/scripts/bootstrap-restic.sh index 5edd868..0b1b984 100755 --- a/scripts/bootstrap-restic.sh +++ b/scripts/bootstrap-restic.sh @@ -6,7 +6,7 @@ ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) target_dir="$ROOT/.tools/restic" target="$target_dir/restic" image=${WNH_BACKUP_TOOLS_IMAGE:-who-need-help:backup-tools} -expected='restic 0.19.1 compiled with go1.26.5' +expected='restic 0.19.1 compiled with go1.26.7' if [[ -x "$target" ]] && [[ "$($target version)" == "$expected"* ]]; then printf 'Pinned Restic is already available: %s\n' "$target" diff --git a/scripts/kind-up.sh b/scripts/kind-up.sh index 0c864b8..d1e6971 100755 --- a/scripts/kind-up.sh +++ b/scripts/kind-up.sh @@ -13,8 +13,7 @@ NAMESPACE=who-need-help SECRET_NAME=who-need-help-local POSTGIS_IMAGE=postgis/postgis:18-3.6-alpine POSTGIS_SOURCE="${POSTGIS_IMAGE}@sha256:05d68c7f0f19b9aa0bf7c4a2049b2e8b38b44a63116392b95726a4c913766cf6" -MAILPIT_IMAGE=axllent/mailpit:v1.30.4 -MAILPIT_SOURCE="${MAILPIT_IMAGE}@sha256:5a49a77c5bdbe7c5474450b4f46348d09949df3695257729c93a30369382d4f6" +MAILPIT_IMAGE=who-need-help:mailpit-v1.30.7-go1.26.7-xmod0.40.0 kube() { kubectl --context "kind-${CLUSTER}" "$@" @@ -89,7 +88,8 @@ else fi load_pinned_image "$POSTGIS_SOURCE" "$POSTGIS_IMAGE" "$ROOT/.tools/postgis-kind.tar" -load_pinned_image "$MAILPIT_SOURCE" "$MAILPIT_IMAGE" "$ROOT/.tools/mailpit-kind.tar" +docker build --tag "$MAILPIT_IMAGE" --file "$ROOT/Dockerfile.mailpit" "$ROOT" +kind load docker-image "$MAILPIT_IMAGE" --name "$CLUSTER" docker build --tag who-need-help:local "$ROOT" kind load docker-image who-need-help:local --name "$CLUSTER" diff --git a/scripts/quality.sh b/scripts/quality.sh index 3537eea..f728608 100755 --- a/scripts/quality.sh +++ b/scripts/quality.sh @@ -7,7 +7,7 @@ cd "$ROOT" SHELLCHECK_IMAGE="koalaman/shellcheck-alpine:v0.11.0@sha256:9955be09ea7f0dbf7ae942ac1f2094355bb30d96fffba0ec09f5432207544002" HADOLINT_IMAGE="hadolint/hadolint:v2.14.0-debian@sha256:158cd0184dcaa18bd8ec20b61f4c1cabdf8b32a592d062f57bdcb8e4c1d312e2" ACTIONLINT_IMAGE="rhysd/actionlint:1.7.12@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667" -TRIVY_IMAGE="aquasec/trivy:0.72.0@sha256:cffe3f5161a47a6823fbd23d985795b3ed72a4c806da4c4df16266c02accdd6f" +TRIVY_IMAGE="aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969" PROMETHEUS_IMAGE="quay.io/prometheus/prometheus:v3.13.1@sha256:3c42b892cf723fa54d2f262c37a0e1f80aa8c8ddb1da7b9b0df9455a35a7f893" ALERTMANAGER_IMAGE="quay.io/prometheus/alertmanager:v0.33.1@sha256:9e082985f56f4c8c9f724e18f2288c6708f472e56a5286b8863d080434ea065d" PYTHON_IMAGE="python:3.14.6-alpine3.23@sha256:b165067c5afc37fa5608a3c05609cc3d51aafd808a30fbfd822ee594fef55ad4" @@ -26,6 +26,7 @@ socket_proxy_image="who-need-help:socket-proxy-audit-$run_id" postgis_image="who-need-help:postgis-audit-$run_id" caddy_image="who-need-help:caddy-audit-$run_id" traefik_image="who-need-help:traefik-audit-$run_id" +mailpit_image="who-need-help:mailpit-audit-$run_id" socket_proxy_container="wnh-socket-proxy-audit-$run_id" scan_dir=$(mktemp -d "${TMPDIR:-/tmp}/wnh-quality-scan.XXXXXX") scan_list="${scan_dir}.files" @@ -50,7 +51,7 @@ cleanup() { docker image rm "$quality_image" "$assets_image" "$e2e_image" "$release_image" \ "$backup_image" "$minio_image" "$mc_image" \ "$boundary_mock_image" "$socket_proxy_image" "$postgis_image" \ - "$caddy_image" "$traefik_image" \ + "$caddy_image" "$traefik_image" "$mailpit_image" \ >/dev/null 2>&1 || true rm -f "$android_fingerprint_probe" rmdir "$android_fingerprint_probe_dir" >/dev/null 2>&1 || true @@ -143,7 +144,7 @@ echo "Checking isolated production release orchestration" echo "Checking Dockerfiles with Hadolint 2.14.0" for dockerfile in Dockerfile Dockerfile.backup Dockerfile.minio \ Dockerfile.postgis Dockerfile.socket-proxy Dockerfile.traefik \ - Dockerfile.caddy \ + Dockerfile.caddy Dockerfile.mailpit \ android/Dockerfile e2e/Dockerfile ops/external-boundaries/Dockerfile; do docker run --rm --interactive "$HADOLINT_IMAGE" \ hadolint --failure-threshold warning - <"$dockerfile" @@ -1649,12 +1650,16 @@ docker build --tag "$socket_proxy_image" --file Dockerfile.socket-proxy . docker build --tag "$postgis_image" --file Dockerfile.postgis . docker build --tag "$caddy_image" --file Dockerfile.caddy . docker build --tag "$traefik_image" --file Dockerfile.traefik . +docker build --tag "$mailpit_image" --file Dockerfile.mailpit . test "$(docker image inspect --format '{{.Config.User}}' "$socket_proxy_image")" = "haproxy" test "$(docker image inspect --format '{{.Config.User}}' "$postgis_image")" = "postgres" test "$(docker image inspect --format '{{.Config.User}}' "$caddy_image")" = "1000:1000" docker run --rm "$caddy_image" version | - grep -F 'v2.11.4-wnh-grpc1.82.1-xtext0.40.0' >/dev/null -docker run --rm "$traefik_image" version | grep -F 'v3.7.10-wnh-grpc1.82.1' >/dev/null + grep -F 'v2.11.4-wnh-go1.26.7-grpc1.82.1-xtext0.40.0' >/dev/null +docker run --rm "$traefik_image" version | + grep -F 'v3.7.10-wnh-grpc1.82.1-xmod0.40.0' >/dev/null +docker run --rm "$mailpit_image" version | + grep -F 'v1.30.7-wnh-go1.26.7-xmod0.40.0' >/dev/null docker run --rm --entrypoint sh "$postgis_image" -euc ' test ! -e /usr/local/bin/gosu test "$(id -u)" = 70 @@ -1710,7 +1715,7 @@ for image in \ "$postgis_image" \ "$traefik_image" \ "$caddy_image" \ - "axllent/mailpit:v1.30.4@sha256:5a49a77c5bdbe7c5474450b4f46348d09949df3695257729c93a30369382d4f6"; do + "$mailpit_image"; do scan_image "$image" done @@ -1862,9 +1867,9 @@ backup_versions=$(docker run --rm \ sh -euc 'restic version; pg_dump --version; test "$(id -u)" = 10001') printf '%s\n' "$backup_versions" printf '%s\n' "$backup_versions" | - grep -F 'restic 0.19.1 compiled with go1.26.5' >/dev/null + grep -F 'restic 0.19.1 compiled with go1.26.7' >/dev/null printf '%s\n' "$backup_versions" | - grep -F 'pg_dump (PostgreSQL) 18.4' >/dev/null + grep -F 'pg_dump (PostgreSQL) 18.6' >/dev/null scan_image "$backup_image" echo "Building and scanning the pinned non-root MinIO server and client images" @@ -1893,13 +1898,13 @@ printf '%s\n' "$minio_version" | printf '%s\n' "$minio_version" | grep -F 'commit-id=9e49d5e7a648f00e26f2246f4dc28e6b07f8c84a' >/dev/null printf '%s\n' "$minio_version" | - grep -F 'Runtime: go1.26.5 linux/' >/dev/null + grep -F 'Runtime: go1.26.7 linux/' >/dev/null printf '%s\n' "$mc_version" | grep -F 'RELEASE.2025-08-13T08-35-41Z' >/dev/null printf '%s\n' "$mc_version" | grep -F 'commit-id=7394ce0dd2a80935aded936b09fa12cbb3cb8096' >/dev/null printf '%s\n' "$mc_version" | - grep -F 'Runtime: go1.26.5 linux/' >/dev/null + grep -F 'Runtime: go1.26.7 linux/' >/dev/null for image in "$minio_image" "$mc_image"; do scan_image "$image" done @@ -1915,6 +1920,34 @@ scan_image "$boundary_mock_image" echo "Building and scanning the production release image" docker build --target release --tag "$release_image" . +release_security_versions=$(docker run --rm \ + --entrypoint dpkg-query \ + "$release_image" \ + -W \ + -f='${Package}=${Version}\n' \ + bsdutils \ + libblkid1 \ + liblastlog2-2 \ + libmount1 \ + libsmartcols1 \ + libuuid1 \ + login \ + mount \ + util-linux) +printf '%s\n' "$release_security_versions" +for expected_release_package in \ + 'bsdutils=1:2.41.5-0+deb13u1' \ + 'libblkid1=2.41.5-0+deb13u1' \ + 'liblastlog2-2=2.41.5-0+deb13u1' \ + 'libmount1=2.41.5-0+deb13u1' \ + 'libsmartcols1=2.41.5-0+deb13u1' \ + 'libuuid1=2.41.5-0+deb13u1' \ + 'login=1:4.16.0-2+really2.41.5-0+deb13u1' \ + 'mount=2.41.5-0+deb13u1' \ + 'util-linux=2.41.5-0+deb13u1'; do + printf '%s\n' "$release_security_versions" | + grep -F -x "$expected_release_package" >/dev/null +done scan_image "$release_image" echo "All isolated quality and security gates passed."