From dc8d9a34d435d5b3c06f1bbd6602c618e965ea73 Mon Sep 17 00:00:00 2001 From: moizpgedge Date: Fri, 17 Jul 2026 04:04:47 +0500 Subject: [PATCH 1/3] fix: bump vulnerable dependencies (PLAT-686) Bump pgx, otel, x/crypto, x/net, and the Go toolchain to patched versions per Trivy scan. Risk-accept the two docker/docker CVEs with no available fix in the v27.x line. PLAT-686 --- .trivy/pgedge-control-plane.trivyignore.yaml | 2 +- changes/unreleased/Security-20260717-040124.yaml | 3 +++ docker/control-plane-dev/Dockerfile | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 changes/unreleased/Security-20260717-040124.yaml diff --git a/.trivy/pgedge-control-plane.trivyignore.yaml b/.trivy/pgedge-control-plane.trivyignore.yaml index 481a6b77..640518ef 100644 --- a/.trivy/pgedge-control-plane.trivyignore.yaml +++ b/.trivy/pgedge-control-plane.trivyignore.yaml @@ -12,4 +12,4 @@ vulnerabilities: - id: CVE-2026-41568 statement: "docker cp race-condition DoS (moby/moby) — same unfixed v27.x dependency and same unused code path as CVE-2026-41567/CVE-2026-42306 (no CopyToContainer/CopyFromContainer/archive API usage anywhere in the repo). Risk accepted; revisit if a v27.x backport or a migration to moby/moby v2 lands." - id: GO-2026-5932 - statement: "golang.org/x/crypto/openpgp is unmaintained/unsafe-by-design — not applicable, this codebase never imports x/crypto/openpgp (verified via repo-wide grep); x/crypto is used only for ssh/bcrypt/other subpackages." \ No newline at end of file + statement: "golang.org/x/crypto/openpgp is unmaintained/unsafe-by-design — not applicable, this codebase never imports x/crypto/openpgp (verified via repo-wide grep); x/crypto is used only for ssh/bcrypt/other subpackages." diff --git a/changes/unreleased/Security-20260717-040124.yaml b/changes/unreleased/Security-20260717-040124.yaml new file mode 100644 index 00000000..b3f4f672 --- /dev/null +++ b/changes/unreleased/Security-20260717-040124.yaml @@ -0,0 +1,3 @@ +kind: Security +body: Update vulnerable dependencies (pgx v5.10.0, OpenTelemetry v1.44.0, golang.org/x/crypto v0.54.0, golang.org/x/net v0.57.0) and bump the Go toolchain to 1.26.5 to remediate Trivy-flagged CVEs in the control-plane image (PLAT-686). github.com/docker/docker CVE-2026-41567/CVE-2026-42306 have no fix in the v27.x line in use; risk-accepted in .trivy/pgedge-control-plane.trivyignore.yaml since the vulnerable docker-cp/archive-copy code paths are never invoked by this codebase. +time: 2026-07-17T04:01:24.289511+05:00 diff --git a/docker/control-plane-dev/Dockerfile b/docker/control-plane-dev/Dockerfile index ff2cb4c9..9bce1da9 100644 --- a/docker/control-plane-dev/Dockerfile +++ b/docker/control-plane-dev/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.25.8 +FROM golang:1.26.5 ENV CGO_ENABLED=0 From 5e8f2e5e586e2b39ce475b2f6bb4f9d25fc8f19f Mon Sep 17 00:00:00 2001 From: moizpgedge Date: Sun, 19 Jul 2026 15:25:33 +0500 Subject: [PATCH 2/3] left over files --- docker/control-plane-ci/Dockerfile | 4 +++- docker/control-plane-dev/Dockerfile | 2 ++ docker/control-plane/Dockerfile | 7 ++++++- docs/Dockerfile | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docker/control-plane-ci/Dockerfile b/docker/control-plane-ci/Dockerfile index 2aa072eb..f6bcf6f6 100644 --- a/docker/control-plane-ci/Dockerfile +++ b/docker/control-plane-ci/Dockerfile @@ -1,10 +1,12 @@ FROM debian:12 RUN apt-get update && \ - apt-get install -y curl && \ + apt-get install -y --no-install-recommends curl && \ rm -rf /var/lib/apt/lists/* COPY ./pgedge-control-plane /pgedge-control-plane # nosemgrep: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint +# trivy:ignore:DS-0002 -- CI-only image; runs as root by design, same +# reasoning as the production Dockerfile (bind-mount ownership management). ENTRYPOINT ["/pgedge-control-plane"] diff --git a/docker/control-plane-dev/Dockerfile b/docker/control-plane-dev/Dockerfile index 9bce1da9..91a9b05b 100644 --- a/docker/control-plane-dev/Dockerfile +++ b/docker/control-plane-dev/Dockerfile @@ -8,4 +8,6 @@ COPY ./entrypoint.sh /entrypoint.sh COPY ./pgedge-control-plane /pgedge-control-plane # nosemgrep: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint +# trivy:ignore:DS-0002 -- dev-only image; runs as root by design, same +# reasoning as the production Dockerfile (bind-mount ownership management). ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/docker/control-plane/Dockerfile b/docker/control-plane/Dockerfile index 0c0cb941..be5fff42 100644 --- a/docker/control-plane/Dockerfile +++ b/docker/control-plane/Dockerfile @@ -1,10 +1,15 @@ -FROM gcr.io/distroless/static-debian12 +FROM gcr.io/distroless/static-debian12:latest@sha256:61b7ccecebc7c474a531717de80a94709d20547cdcdaf740c25876f2a8e38b44 ARG TARGETOS ARG TARGETARCH ARG ARCHIVE_VERSION # nosemgrep: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint +# trivy:ignore:DS-0002 -- runs as root by design: the control-plane process +# manages bind-mounted host directories and files on behalf of arbitrary +# database owner UIDs/GIDs (chown, permission setup for Postgres/Patroni data +# dirs and certs), which requires root privileges. Distroless static has no +# shell/su-exec to safely drop privileges after that setup either. ENTRYPOINT ["/pgedge-control-plane"] ADD pgedge-control-plane_${ARCHIVE_VERSION}_${TARGETOS}_${TARGETARCH}.tar.gz / diff --git a/docs/Dockerfile b/docs/Dockerfile index 73d95d7a..c8dafdd8 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,3 +1,3 @@ -FROM squidfunk/mkdocs-material +FROM squidfunk/mkdocs-material:latest@sha256:51b87149d227691486b5f08993d28c65ca7e4990010664b697265b8e6fcd5287 RUN pip install pymdown-extensions mkdocs-redoc-tag mkdocs-github-admonitions-plugin From 9a84717fd56a0490e46533028429023bb6afe44b Mon Sep 17 00:00:00 2001 From: moizpgedge Date: Sun, 19 Jul 2026 15:39:52 +0500 Subject: [PATCH 3/3] ai suggestions --- .trivyignore | 18 ++++++++++++++++++ docker/control-plane-ci/Dockerfile | 6 ++++-- docker/control-plane-dev/Dockerfile | 6 ++++-- docker/control-plane/Dockerfile | 12 +++++++----- docs/Dockerfile | 7 +++++++ 5 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 .trivyignore diff --git a/.trivyignore b/.trivyignore new file mode 100644 index 00000000..471a08be --- /dev/null +++ b/.trivyignore @@ -0,0 +1,18 @@ +# DS-0002: "Specify at least 1 USER command in Dockerfile with non-root user" +# +# Every Dockerfile in this repo (docker/control-plane, docker/control-plane-dev, +# docker/control-plane-ci) intentionally runs as root: the control-plane +# process manages ownership (chown) of bind-mounted Postgres/Patroni data, +# config, and cert directories on behalf of arbitrary database-owner +# UIDs/GIDs, which requires root privileges. The distroless static base used +# in production also has no shell/su-exec to drop privileges after that setup. +# See the matching `# nosemgrep: dockerfile.security.missing-user-entrypoint` +# comments in each Dockerfile for the same rationale. +# +# NOTE: inline `# trivy:ignore:DS-0002` comments do NOT suppress this check +# (verified empirically — DS-0002 is a whole-file "is USER present anywhere" +# check, not a line-specific one, so Trivy's line-scoped ignore-comment +# mechanism doesn't apply to it). This global entry is the only form that +# actually works; per-path scoping (`path:DS-0002` or a paths: list in +# .trivyignore.yaml) was tested and does not suppress the finding either. +DS-0002 diff --git a/docker/control-plane-ci/Dockerfile b/docker/control-plane-ci/Dockerfile index f6bcf6f6..006c8072 100644 --- a/docker/control-plane-ci/Dockerfile +++ b/docker/control-plane-ci/Dockerfile @@ -7,6 +7,8 @@ RUN apt-get update && \ COPY ./pgedge-control-plane /pgedge-control-plane # nosemgrep: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint -# trivy:ignore:DS-0002 -- CI-only image; runs as root by design, same -# reasoning as the production Dockerfile (bind-mount ownership management). +# CI-only image; runs as root by design, same reasoning as the production +# Dockerfile (bind-mount ownership management). Trivy's DS-0002 is suppressed +# repo-wide in .trivyignore since inline ignore comments don't work for this +# whole-file check. ENTRYPOINT ["/pgedge-control-plane"] diff --git a/docker/control-plane-dev/Dockerfile b/docker/control-plane-dev/Dockerfile index 91a9b05b..d25ce518 100644 --- a/docker/control-plane-dev/Dockerfile +++ b/docker/control-plane-dev/Dockerfile @@ -8,6 +8,8 @@ COPY ./entrypoint.sh /entrypoint.sh COPY ./pgedge-control-plane /pgedge-control-plane # nosemgrep: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint -# trivy:ignore:DS-0002 -- dev-only image; runs as root by design, same -# reasoning as the production Dockerfile (bind-mount ownership management). +# Dev-only image; runs as root by design, same reasoning as the production +# Dockerfile (bind-mount ownership management). Trivy's DS-0002 is suppressed +# repo-wide in .trivyignore since inline ignore comments don't work for this +# whole-file check. ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/docker/control-plane/Dockerfile b/docker/control-plane/Dockerfile index be5fff42..ccd8c0b5 100644 --- a/docker/control-plane/Dockerfile +++ b/docker/control-plane/Dockerfile @@ -5,11 +5,13 @@ ARG TARGETARCH ARG ARCHIVE_VERSION # nosemgrep: dockerfile.security.missing-user-entrypoint.missing-user-entrypoint -# trivy:ignore:DS-0002 -- runs as root by design: the control-plane process -# manages bind-mounted host directories and files on behalf of arbitrary -# database owner UIDs/GIDs (chown, permission setup for Postgres/Patroni data -# dirs and certs), which requires root privileges. Distroless static has no -# shell/su-exec to safely drop privileges after that setup either. +# Runs as root by design: the control-plane process manages bind-mounted host +# directories and files on behalf of arbitrary database owner UIDs/GIDs (chown, +# permission setup for Postgres/Patroni data dirs and certs), which requires +# root privileges. Distroless static has no shell/su-exec to safely drop +# privileges after that setup either. Trivy's DS-0002 (non-root user) is +# suppressed repo-wide in .trivyignore since inline ignore comments don't work +# for this whole-file check. ENTRYPOINT ["/pgedge-control-plane"] ADD pgedge-control-plane_${ARCHIVE_VERSION}_${TARGETOS}_${TARGETARCH}.tar.gz / diff --git a/docs/Dockerfile b/docs/Dockerfile index c8dafdd8..eb525cef 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,3 +1,10 @@ FROM squidfunk/mkdocs-material:latest@sha256:51b87149d227691486b5f08993d28c65ca7e4990010664b697265b8e6fcd5287 RUN pip install pymdown-extensions mkdocs-redoc-tag mkdocs-github-admonitions-plugin + +# No USER directive: `make docs` bind-mounts the whole repo (-v ${PWD}:/docs) +# with no UID mapping, and the host directory's owning UID varies per +# developer/CI runner. Baking in a fixed non-root UID risks permission-denied +# reads of the bind-mounted docs on any host whose UID doesn't match. Trivy's +# DS-0002 (non-root user) is suppressed repo-wide in .trivyignore for the same +# reason as the other Dockerfiles in this repo.