Skip to content

fix: patch CVEs flagged by Trivy image scan#435

Merged
moizpgedge merged 3 commits into
mainfrom
Bug/PLAT-686/Security-Trivy-Triage-security-issues
Jul 21, 2026
Merged

fix: patch CVEs flagged by Trivy image scan#435
moizpgedge merged 3 commits into
mainfrom
Bug/PLAT-686/Security-Trivy-Triage-security-issues

Conversation

@moizpgedge

@moizpgedge moizpgedge commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the Trivy image scan findings (2 Critical, 28 High, 17 Medium, 1 Low) by bumping the vulnerable deps and Go toolchain, risk-accepting the couple of CVEs with no fix available, hardening the Dockerfiles, and fixing the licenses-ci CI failure that came out of it.

Changes

Dependency bumps. Bumped pgx to v5.10.0 (fixes two Critical CVEs), opentelemetry to v1.44.0, x/crypto to v0.54.0, x/net to v0.57.0, and the Go toolchain itself to 1.26.5, which alone covers 11 stdlib CVEs. These were all just following the Trivy report's fixed-version column.

Risk acceptances. docker/docker's CVEs don't have a fix in the v27 line we're on — confirmed with govulncheck that every one says "Fixed in: N/A" — and we don't use any of the archive/copy APIs the vulnerable code paths are in anyway. x/crypto/openpgp's advisory doesn't apply since we don't import it. Both documented in trivyignore.

Dockerfile hardening. Pinned the FROM images to digests instead of floating latest tags, added --no-install-recommends to the CI Dockerfile. All four Dockerfiles still run as root on purpose — the binary needs to chown bind-mounted Postgres/Patroni data for arbitrary DB-owner UIDs, and distroless has no shell to drop privileges with anyway. docs/Dockerfile has its own reason: the doc build bind-mounts the whole repo with no UID mapping, so a fixed non-root user could just as easily break on a different host UID. Tried the inline trivy:ignore comment for this first but it doesn't actually work (it's a whole-file check, not line-scoped, confirmed by testing it), so moved the suppression to a plain .trivyignore entry with the reasoning written down instead.

NOTICE.txt fix. go-licenses has a bug where it generates duplicate-path LICENSE links for some opentelemetry-go packages, giving 404s. Fixed it in the Makefile itself (a sed step, not a one-off edit) so regeneration stays correct going forward, then regenerated NOTICE.txt for real in a container matching CI's Go version — my local macOS Go can't even run go-licenses. This is also what fixes the licenses-ci failure, since an earlier manual edit to NOTICE.txt couldn't survive CI regenerating and diffing it.

Testing

go build, go vet clean. go test passes except one pre-existing unrelated failure in the mqtt package that needs a rootless-docker socket, nothing to do with this PR. Cross-checked the docker/docker CVEs with govulncheck. Rebuilt the actual production image and rescanned it with Trivy: zero vulnerabilities at any severity, and confirmed with --show-suppressed that only the 6 documented docker/docker CVEs are hidden, nothing else. Rescanned all four Dockerfiles for misconfigs: clean except the pre-existing missing-HEALTHCHECK low finding, out of scope here. Also checked for secrets and license issues on the built image, nothing concerning. Ran make licenses in a matching container and confirmed zero diff against the committed NOTICE.txt.

Checklist

  • Tests — N/A, this is dependency/config only, verified via the rescans above
  • Documentation — NOTICE.txt regenerated, risk acceptances and root-user reasoning documented inline
  • Issue linked — PLAT-686
  • Changelog entry added
  • No breaking changes

@codacy-production

codacy-production Bot commented Jul 16, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@moizpgedge, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 27 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 51108ebb-a1dd-4218-ba54-4630eea0d9aa

📥 Commits

Reviewing files that changed from the base of the PR and between 22752e2 and 9a84717.

📒 Files selected for processing (7)
  • .trivy/pgedge-control-plane.trivyignore.yaml
  • .trivyignore
  • changes/unreleased/Security-20260717-040124.yaml
  • docker/control-plane-ci/Dockerfile
  • docker/control-plane-dev/Dockerfile
  • docker/control-plane/Dockerfile
  • docs/Dockerfile
📝 Walkthrough

Walkthrough

The changes update Go and dependency versions, refresh license records, pin container images, adjust CI package installation, add Dockerfile security annotations, and document vulnerability remediation and accepted non-applicable findings.

Changes

Security dependency refresh

Layer / File(s) Summary
Go and dependency version updates
go.mod, server/internal/resource/migrations/schematool/go.mod, NOTICE.txt
Go toolchains, application dependencies, migration-tool dependencies, and corresponding license records are updated.
Container image hardening
docker/control-plane*/Dockerfile, docs/Dockerfile
Container bases are upgraded or digest-pinned, CI installs curl without recommended packages, and security-scan annotations document intentional root execution.
Security records and vulnerability suppressions
changes/unreleased/*, .trivy/*
The security changelog records dependency remediation and risk acceptance, while Trivy ignores specified non-applicable findings.

Poem

A rabbit checks the versions bright,
Pins Docker moons in place just right.
Go hops ahead, dependencies grow,
Trivy finds the paths that don’t show.
“Secure and tidy!” the bunny sings,
Then nibbles changelogs with whiskered wings.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: fixing Trivy-flagged CVEs via dependency and image hardening updates.
Description check ✅ Passed The description covers Summary, Changes, Testing, and Checklist, with only the optional Notes for Reviewers section left empty.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch Bug/PLAT-686/Security-Trivy-Triage-security-issues

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
docker/control-plane-dev/Dockerfile (1)

1-1: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Pin the base image by digest.

Use golang:1.26.5@sha256:<digest> rather than relying only on the mutable version tag, so future tag changes cannot silently alter this security-sensitive build.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker/control-plane-dev/Dockerfile` at line 1, Update the Dockerfile’s FROM
declaration to pin golang:1.26.5 to its immutable SHA256 digest, preserving the
existing version tag alongside the digest.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker/control-plane-dev/Dockerfile`:
- Line 1: Update the Dockerfile to create a dedicated unprivileged user, ensure
required application files and directories are accessible to that user, and add
a USER directive selecting it before the entrypoint so the container does not
run as root.

In `@go.mod`:
- Line 5: Update the toolchain directive in the schematool module’s go.mod from
Go 1.25.8 to Go 1.26.5, preserving the existing module configuration and
directive format.

---

Nitpick comments:
In `@docker/control-plane-dev/Dockerfile`:
- Line 1: Update the Dockerfile’s FROM declaration to pin golang:1.26.5 to its
immutable SHA256 digest, preserving the existing version tag alongside the
digest.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e9eb91c6-f070-4dcc-ac1e-3c7276b29246

📥 Commits

Reviewing files that changed from the base of the PR and between 81492c6 and 9880e66.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (4)
  • .trivy/pgedge-control-plane.trivyignore.yaml
  • changes/unreleased/Security-20260717-040124.yaml
  • docker/control-plane-dev/Dockerfile
  • go.mod

@@ -1,4 +1,4 @@
FROM golang:1.25.8
FROM golang:1.26.5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Run the container as a non-root user.

Trivy reports that this image runs as root. Create a dedicated unprivileged user and add a USER directive before the entrypoint; otherwise the security refresh still ships a container with unnecessary privilege.

Proposed fix
 FROM golang:1.26.5
+RUN useradd --system --uid 10001 app
+USER app
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FROM golang:1.26.5
FROM golang:1.26.5
RUN useradd --system --uid 10001 app
USER app
🧰 Tools
🪛 Trivy (0.72.0)

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker/control-plane-dev/Dockerfile` at line 1, Update the Dockerfile to
create a dedicated unprivileged user, ensure required application files and
directories are accessible to that user, and add a USER directive selecting it
before the entrypoint so the container does not run as root.

Source: Linters/SAST tools

Comment thread go.mod

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker/control-plane/Dockerfile`:
- Line 8: Remove the inline DS-0002 suppression comments from
docker/control-plane/Dockerfile:8 and docker/control-plane-ci/Dockerfile:10, and
also remove the corresponding suppression at
docker/control-plane-dev/Dockerfile:11. Add DS-0002 to the repository’s
.trivyignore or .trivyignore.yaml, scoped to these Dockerfiles if supported.

In `@docs/Dockerfile`:
- Line 1: Update the docs Dockerfile after the package installation steps to
switch execution to a non-root USER, using an existing non-root user provided by
the squidfunk/mkdocs-material base image; otherwise document an explicit runtime
user override.

In `@NOTICE.txt`:
- Around line 13736-13737: The license generator invoked by make licenses
produces incorrect OpenTelemetry URLs for the metric, sdk, and trace entries.
Update the generator to use each tag’s root LICENSE URL instead of the
nonexistent module/LICENSE path, then regenerate NOTICE.txt; apply the
correction to NOTICE.txt ranges 13736-13737, 13976-13977, 14216-14217,
14456-14457, 14696-14697, and 14936-14937.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 89a23a44-3049-4d06-8b0b-8e182ee9dc83

📥 Commits

Reviewing files that changed from the base of the PR and between 9880e66 and 22752e2.

⛔ Files ignored due to path filters (1)
  • server/internal/resource/migrations/schematool/go.sum is excluded by !**/*.sum
📒 Files selected for processing (6)
  • NOTICE.txt
  • docker/control-plane-ci/Dockerfile
  • docker/control-plane-dev/Dockerfile
  • docker/control-plane/Dockerfile
  • docs/Dockerfile
  • server/internal/resource/migrations/schematool/go.mod
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker/control-plane-dev/Dockerfile

Comment thread docker/control-plane/Dockerfile Outdated
Comment thread docs/Dockerfile
@@ -1,3 +1,3 @@
FROM squidfunk/mkdocs-material
FROM squidfunk/mkdocs-material:latest@sha256:51b87149d227691486b5f08993d28c65ca7e4990010664b697265b8e6fcd5287

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== docs/Dockerfile (numbered) ==\n'
cat -n docs/Dockerfile

printf '\n== repo files mentioning mkdocs-material or docs image usage ==\n'
rg -n --hidden --glob '!**/.git/**' 'mkdocs-material|docs/Dockerfile|squidfunk/mkdocs-material|USER ' .

printf '\n== docs directory file list ==\n'
git ls-files docs

Repository: pgEdge/control-plane

Length of output: 5862


🌐 Web query:

squidfunk/mkdocs-material default user root Dockerfile USER upstream image

💡 Result:

The official squidfunk/mkdocs-material Docker image runs as the root user by default [1][2]. Because the container executes commands as root, any files created or modified within a mounted volume (e.g., when running mkdocs new or building a site) will be owned by the root user on the host system [2]. To avoid file permission issues where generated files are owned by root, you can pass the current user's UID and GID to the container using the --user flag when running the docker command [2]: docker run --rm -it -v ${PWD}:/docs --user "$(id -u):$(id -g)" squidfunk/mkdocs-material build This configuration ensures that files created within the container are owned by your host user rather than the root user [2].

Citations:


Run the docs image as non-root. docs/Dockerfile:1 still inherits the upstream image’s default root user, so the container will run as root unless you add a USER after the package install or document an explicit runtime --user override.

🧰 Tools
🪛 Trivy (0.72.0)

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/Dockerfile` at line 1, Update the docs Dockerfile after the package
installation steps to switch execution to a non-root USER, using an existing
non-root user provided by the squidfunk/mkdocs-material base image; otherwise
document an explicit runtime user override.

Source: Linters/SAST tools

Comment thread NOTICE.txt Outdated
@moizpgedge moizpgedge changed the title fix: bump vulnerable dependencies (PLAT-686) fix: bump vulnerable dependencies Jul 19, 2026
@moizpgedge moizpgedge changed the title fix: bump vulnerable dependencies fix: patch CVEs flagged by Trivy image scan Jul 20, 2026
@moizpgedge
moizpgedge requested a review from tsivaprasad July 20, 2026 16:20
@@ -1,10 +1,17 @@
FROM gcr.io/distroless/static-debian12
FROM gcr.io/distroless/static-debian12:latest@sha256:61b7ccecebc7c474a531717de80a94709d20547cdcdaf740c25876f2a8e38b44

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this digest a fat manifest (multi-arch) or platform-specific?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this image works on all the different chip types (Intel/AMD and ARM included), so it's fine

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
@moizpgedge
moizpgedge force-pushed the Bug/PLAT-686/Security-Trivy-Triage-security-issues branch from 5c29fc4 to 9a84717 Compare July 21, 2026 11:11
@moizpgedge
moizpgedge merged commit 747273b into main Jul 21, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants