Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/publish-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,10 @@ jobs:
base_version="$(grep -m1 '^FROM postgres:' images/postgres/Dockerfile | sed -E 's#^FROM postgres:([^@[:space:]]+).*#\1#')"
;;
restic)
base_version="$(grep -m1 '^FROM restic/restic:' images/restic/Dockerfile | sed -E 's#^FROM restic/restic:([^@[:space:]]+).*#\1#')"
# restic is compiled from source in images/restic/Dockerfile (the
# upstream restic/restic image is no longer the base), so the base
# version comes from the pinned source tag ARG.
base_version="$(grep -m1 '^ARG RESTIC_VERSION=' images/restic/Dockerfile | cut -d= -f3)"
;;
*)
echo "No version scheme defined for image '${{ matrix.image.name }}'" >&2
Expand Down
178 changes: 0 additions & 178 deletions .trivyignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,181 +18,3 @@
# Rules: only IDs reported by the scan may be listed, each ID at most once,
# and exp must be a valid date at most 90 days out. An expired exception
# stops being ignored and fails the daily scan again.
Comment thread
RonaldHensbergen marked this conversation as resolved.
Resolved

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2025-61726 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2025-61729 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2025-68121 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-111943 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-25679 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-27145 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-32280 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-32281 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-32283 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-33811 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-33814 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-33818 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-39820 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-39821 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-39822 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-39836 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-42499 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-42504 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-56853 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-56858 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-56859 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-56860 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-56862 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-78667 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-78669 exp:2027-01-23

# gosu 1.19 in the pinned postgres:18 base is built with go1.24.6;
# patched in the next upstream base image digest (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-97031 exp:2027-01-23

# restic 0.19.1 (the latest upstream release, digest-pinned) is built with
# github.com/klauspost/compress v1.18.6; patched in the next restic
# release (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-63209 exp:2027-01-26

# restic 0.19.1 (the latest upstream release, digest-pinned) is built with
# golang.org/x/crypto v0.52.0; patched in the next restic release
# (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-56854 exp:2027-01-26

# restic 0.19.1 (the latest upstream release, digest-pinned) is built with
# golang.org/x/net v0.55.0 and Go stdlib v1.26.4; patched in the next
# restic release (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-46600 exp:2027-01-26

# restic 0.19.1 (the latest upstream release, digest-pinned) is built with
# golang.org/x/text v0.37.0 (CVE-2026-56851); patched in the next restic
# release (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-56851 exp:2027-01-26

# restic 0.19.1 (the latest upstream release, digest-pinned) is built with
# golang.org/x/text v0.37.0 (CVE-2026-56852); patched in the next restic
# release (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-56852 exp:2027-01-26

# restic 0.19.1 (the latest upstream release, digest-pinned) is built with
# google.golang.org/grpc v1.81.1 (CVE-2026-84304); patched in the next
# restic release (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-84304 exp:2027-01-26

# restic 0.19.1 (the latest upstream release, digest-pinned) is built with
# google.golang.org/grpc v1.81.1 (CVE-2026-84445); patched in the next
# restic release (refresh the pin)
# owner:@ronaldhensbergen
CVE-2026-84445 exp:2027-01-26

# restic 0.19.1 (the latest upstream release, digest-pinned) is built with
# google.golang.org/grpc v1.81.1 (GHSA-hrxh-6v49-42gf); patched in the next
# restic release (refresh the pin)
# owner:@ronaldhensbergen
GHSA-hrxh-6v49-42gf exp:2027-01-26
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ The format is based on Keep a Changelog.

### Fixed

- Cleared the 34 `.trivyignore` exceptions listed by the trivyignore audit
(#1001) by fixing the findings at the source in the rebuilt images instead
of ignoring them: the `postgres` image now pins the current `postgres:18`
digest (also in `modules/warehouse/postgres/module.yaml`,
`docker-compose.yml`, and `.cds/haven-dev-noinit.yml`) and replaces the
base image's prebuilt `gosu` binary — which no `postgres:18` tag rebuilds
with a fixed Go toolchain — with a build from the pinned gosu 1.20 tag
compiled with Go 1.27.3; the `restic` image now compiles restic 0.19.1 (the
latest upstream release) from source with Go 1.27.3 and the fixed module
versions (`go-jose/v4` 4.1.6, `klauspost/compress` 1.18.7, `x/crypto`
0.57.0, `x/net` 0.60.0, `x/text` 0.42.0, `grpc` 1.83.2) on a pinned Alpine
base instead of using the vulnerable prebuilt `restic/restic` image; both
source tarballs are verified against pinned sha256 hashes in the builder
stages. Both rebuilt images scan clean of HIGH/CRITICAL findings with
Trivy v0.75.0.

- Fixed `cds security` false positives on the reference production profile
(#979): the secret-value rules CDS-SEC-001/003/033 no longer flag values
that are entirely a renderer reference (`config.passwordFrom`,
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ docker-build:
echo "Building $$dockerfile in directory $$dir..."; \
context="$$dir"; \
case "$$dockerfile" in \
./images/dagster/*|./images/superset/*|./images/postgres/*) context="." ;; \
./images/dagster/*|./images/superset/*|./images/dbt/*|./images/dlt/*|./images/postgres/*|./images/restic/*) context="." ;; \
esac; \
docker build -f "$$dockerfile" "$$context" || exit 1; \
done
Expand Down
29 changes: 28 additions & 1 deletion images/postgres/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,37 @@
# The pgdg apt repository is already configured in the upstream postgres
# image; the pgbackrest package version is pinned for reproducible builds.

FROM postgres:18@sha256:32ca0af8e77bfb8c6610c488e4691f83f972a3e9e64d3b02facf3ab111ad5500
# gosu build stage: the upstream postgres image ships a prebuilt gosu binary
# compiled with an old Go toolchain, and no postgres:18 tag rebuilds it, so
# the Go stdlib CVEs against that binary are not fixable by a base digest
# bump alone (#1001). Build gosu from the pinned upstream tag with the
# current Go toolchain instead; the result is a static binary
# (CGO_ENABLED=0). The source tarball is verified against the pinned
# sha256 below (review hardening on #1041); module dependencies would be
# covered by the Go checksum database, but gosu has none.
FROM golang:1.27.3-alpine@sha256:d200d2dd76b03a99b52651fd1325aff7dcd35422c35c01bac56571b0507f3deb AS gosu
ARG GOSU_VERSION=1.20
# sha256 of https://codeload.github.com/tianon/gosu/tar.gz/refs/tags/${GOSU_VERSION}
# (verified stable across downloads). No Renovate datasource exists for
# codeload tarball hashes, so bump this ARG together with GOSU_VERSION —
# the build fails closed on a mismatch.
ARG GOSU_TARBALL_SHA256=207a2045e890d3ca3326027c5f585733085960b401a49dbc00e3bb628c054cf8
RUN mkdir -p /src \
Comment thread
RonaldHensbergen marked this conversation as resolved.
Resolved
&& wget -qO /tmp/gosu.tar.gz "https://codeload.github.com/tianon/gosu/tar.gz/refs/tags/${GOSU_VERSION}" \
&& echo "${GOSU_TARBALL_SHA256} /tmp/gosu.tar.gz" | sha256sum -c - \
&& tar xz --strip-components=1 -C /src -f /tmp/gosu.tar.gz \
&& rm /tmp/gosu.tar.gz \
&& cd /src \
&& CGO_ENABLED=0 go build -trimpath -o /go/bin/gosu .

FROM postgres:18@sha256:979bccfde35445db618c65107d27d08c6c21339d8dc3ad4c830c6633947be0e4

USER root

# Replace the base image's prebuilt gosu with the toolchain-current build
# from the stage above (see the comment on that stage).
COPY --from=gosu /go/bin/gosu /usr/local/bin/gosu

# Pull in Debian security fixes for the base image's OS packages before
# installing pgbackrest, mirroring images/superset/base/Dockerfile: the
# pinned upstream digest can lag behind trixie-security, and the Trivy
Expand Down
6 changes: 6 additions & 0 deletions images/postgres/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ PostgreSQL image with [pgBackRest](https://pgbackrest.org/) for the built-in
backup capability of the `warehouse/postgres` module (issue #665).

- Base: `postgres:18`, digest-pinned (Renovate keeps the pin current).
- Replaces the base image's prebuilt `gosu` binary with a build from the
pinned gosu tag compiled with the current Go toolchain: the upstream
image downloads a prebuilt binary that no `postgres:18` tag rebuilds, so
its Go stdlib CVEs are only fixable by compiling gosu here (#1001). The
source tarball is verified against the pinned `GOSU_TARBALL_SHA256`
during the build (bump it together with `GOSU_VERSION`).
- Adds the `pgbackrest` package from the pgdg apt repository baked into the
upstream image, version-pinned for reproducible builds.
- `cds-pgbackrest-archive` — PostgreSQL `archive_command` handler. Archives WAL
Expand Down
35 changes: 34 additions & 1 deletion images/restic/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,44 @@
# Repository location and S3 settings come from the CDS_BACKUP_*
# environment variables rendered by the module; the repository is always
# client-side encrypted with RESTIC_PASSWORD from the profile's secrets.
#
# restic is compiled from source instead of using the upstream
# restic/restic image: 0.19.1 is still the latest upstream release, and its
# published binary is built with vulnerable Go modules and an old stdlib,
# so no upstream image refresh can clear those findings (#1001). Building
# the pinned release tag with the current Go toolchain and the fixed module
# versions below does. The versions are the fixed versions from the Trivy
# advisories (x/net v0.60.0 requires x/crypto >= v0.57.0 and x/text
# >= v0.42.0); Renovate tracks them via the regex manager in renovate.json.

FROM golang:1.27.3-alpine@sha256:d200d2dd76b03a99b52651fd1325aff7dcd35422c35c01bac56571b0507f3deb AS restic-build
ARG RESTIC_VERSION=0.19.1
# sha256 of https://codeload.github.com/restic/restic/tar.gz/refs/tags/v${RESTIC_VERSION}
# (verified stable across downloads). No Renovate datasource exists for
# codeload tarball hashes, so bump this ARG together with RESTIC_VERSION —
# the build fails closed on a mismatch. Module deps fetched by go get/go mod
# tidy are covered by the Go checksum database.
ARG RESTIC_TARBALL_SHA256=bb9b1a19040744d26d8a79be029d4e6b189c45ccc9d8831d7fe367d3c33df725
WORKDIR /src
RUN wget -qO /tmp/restic.tar.gz "https://codeload.github.com/restic/restic/tar.gz/refs/tags/v${RESTIC_VERSION}" \
&& echo "${RESTIC_TARBALL_SHA256} /tmp/restic.tar.gz" | sha256sum -c - \
&& tar xz --strip-components=1 -f /tmp/restic.tar.gz \
&& rm /tmp/restic.tar.gz \
&& go get github.com/go-jose/go-jose/v4@v4.1.6 \
github.com/klauspost/compress@v1.18.7 \
golang.org/x/crypto@v0.57.0 \
golang.org/x/net@v0.60.0 \
golang.org/x/text@v0.42.0 \
google.golang.org/grpc@v1.83.2 \
&& go mod tidy \
&& CGO_ENABLED=0 go build -trimpath -o /restic ./cmd/restic

FROM restic/restic:0.19.1@sha256:136600b6ff6843d61d355f7f71f460a166429f35de6fd11b568fece3c9a4d510
FROM alpine:3.24@sha256:be2656061b536c1883c4034790e21d0a09c5aaaf51968b89368a3c0371ea2c9a

USER root

COPY --from=restic-build /restic /usr/bin/restic

# Pull in Alpine security fixes for the base image's OS packages before
# creating the user, mirroring images/postgres/Dockerfile: the pinned
# upstream digest can lag behind the fixed packages, and the Trivy scan
Expand Down
11 changes: 9 additions & 2 deletions images/restic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
Restic image for the generic file/volume backup module
(`modules/backup/restic`, issue #668).

- Base: `restic/restic:0.19.1`, digest-pinned (Renovate keeps the pin
current).
- Base: `alpine:3.24`, digest-pinned (Renovate keeps the pin current). restic
itself is compiled from source in a builder stage: `RESTIC_VERSION` pins
the upstream release tag (0.19.1 is still the latest release) and the
`go get` line pins the fixed Go module versions from the Trivy advisories
against the published 0.19.1 binary, compiled with the current Go
toolchain (#1001); Renovate tracks the ARG and the module pins. The source
tarball is verified against the pinned `RESTIC_TARBALL_SHA256` during the
build (bump it together with `RESTIC_VERSION`). Using the prebuilt
`restic/restic` image instead would reintroduce those findings.
- Adds a dedicated non-root `restic` user (uid 10000) and the repository /
source mount points (`/var/lib/restic-repo`, `/backup`) with the right
ownership, so a fresh named volume inherits uid/gid 10000 on first use
Expand Down
2 changes: 1 addition & 1 deletion modules/warehouse/postgres/module.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ spec:
# production-only pieces below replace these fields in production
# profiles (production: mapping form; see apply_production_gates).
postgres:
image: postgres:18@sha256:32ca0af8e77bfb8c6610c488e4691f83f972a3e9e64d3b02facf3ab111ad5500
image: postgres:18@sha256:979bccfde35445db618c65107d27d08c6c21339d8dc3ad4c830c6633947be0e4
user: postgres
init: true
read_only: true
Expand Down
36 changes: 36 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,42 @@
]
},
"customManagers": [
{
"customType": "regex",
"description": "Track the gosu source tag compiled in images/postgres/Dockerfile to replace the postgres base image's prebuilt gosu binary (upstream publishes unprefixed tags like 1.20, hence the loose versioning); when the tag changes, bump GOSU_TARBALL_SHA256 in the same file — no datasource covers codeload tarball hashes, so the sha256 is manual",
"matchStrings": [
"ARG GOSU_VERSION=(?<currentValue>\\S+)"
],
"depNameTemplate": "tianon/gosu",
"datasourceTemplate": "docker",
"versioningTemplate": "loose",
"managerFilePatterns": [
"/^images/postgres/Dockerfile$/"
]
},
{
"customType": "regex",
"description": "Track the restic source tag compiled in images/restic/Dockerfile (restic is built from source with patched Go modules; the upstream restic/restic image is no longer used as a base); when the tag changes, bump RESTIC_TARBALL_SHA256 in the same file — no datasource covers codeload tarball hashes, so the sha256 is manual",
"matchStrings": [
"ARG RESTIC_VERSION=(?<currentValue>\\S+)"
],
"depNameTemplate": "restic/restic",
"datasourceTemplate": "docker",
"managerFilePatterns": [
"/^images/restic/Dockerfile$/"
]
},
{
"customType": "regex",
"description": "Track the Go module versions pinned in the `go get` line of images/restic/Dockerfile (the fixed versions from the Trivy advisories against the restic 0.19.1 binary)",
"matchStrings": [
"(?<depName>[\\w./-]+)@(?<currentValue>v[\\w.-]+)"
],
"datasourceTemplate": "golang",
"managerFilePatterns": [
"/^images/restic/Dockerfile$/"
]
},
{
"customType": "regex",
"description": "Track pip pins in Dagster entrypoint script",
Expand Down
Loading
Loading