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
6 changes: 6 additions & 0 deletions .github/workflows/security-grype.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ jobs:
# shipped β€” so this is the authoritative view of the runtime CVE surface.
uses: anchore/scan-action@e1165082ffb1fe366ebaf02d8526e7c4989ea9d2 # v7.4.0
id: grype
env:
# Load the repo-root .grype.yaml explicitly (it documents why the
# bundled cosign/trivy CLI binaries' vendored Go-module CVEs are
# triaged). grype also auto-discovers it from the workspace, but
# pinning the path keeps the gate deterministic across action versions.
GRYPE_CONFIG: ${{ github.workspace }}/.grype.yaml
with:
image: drydock:grype-scan
severity-cutoff: high
Expand Down
28 changes: 28 additions & 0 deletions .grype.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Grype configuration β€” drydock container image scan triage.
#
# The grype-image job (.github/workflows/security-grype.yml) fails the build on
# HIGH/CRITICAL. These ignore rules scope that gate to the dependencies drydock
# actually controls β€” the Node runtime, the Alpine OS packages, and the app
# (npm) dependency graph β€” and exclude the vendored Go module graphs compiled
# into the third-party `cosign` and `trivy` CLI binaries the image ships for
# signature verification and container scanning.
#
# Why: those CVEs (golang.org/x/crypto, x/net, Go stdlib, …) live inside upstream
# tool binaries, not drydock's own code, and reach the binary only as cosign's /
# trivy's vendored modules. We cannot patch them independently β€” they clear only
# when Alpine rebuilds the cosign/trivy packages with a patched toolchain, which
# we pick up by bumping the base image / package pins (the cosign 2.6.3-r1 ->
# 3.0.6-r1 bump in this change already cleared the bulk of them). Gating the build
# on a module graph we don't control is the same manifest-vs-shipped mismatch we
# dropped Snyk over. The Node runtime, musl, curl, git, every other OS package,
# and the entire app dependency graph stay fully gated β€” confirmed by the scan,
# which after the base bump leaves residual HIGH/CRITICAL findings only at these
# two binary locations.
#
# Revisit on each base-image bump: if Alpine ships rebuilt cosign/trivy packages,
# the residuals clear on their own and these scopes simply stop matching anything.
ignore:
- package:
location: "/usr/bin/cosign"
- package:
location: "/usr/bin/trivy"
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ scheme restriction) live in `UPGRADE-NOTES.md` and are auto-appended to every

- **E2E load-test harness `@opentelemetry/core` pinned to 2.8.0 ([CVE-2026-54285](https://github.com/advisories/GHSA-8988-4f7v-96qf)).** artillery pulled `@opentelemetry/core` 2.7.1 transitively, vulnerable to unbounded memory allocation in W3C Baggage propagation; an override forces the patched 2.8.0. Test-only dependency β€” not part of the shipped drydock image.

- **Patched the container image's HIGH/CRITICAL CVE surface and scoped the Grype image gate.** The first `grype-image` scan on `main` flagged a pre-existing CVE backlog that nothing had been scanning (Snyk Container never ran β€” no token was configured). Bumped the `node:24-alpine` base (node 24.14.0 β†’ 24.16.0 clearing CVE-2026-21710, musl 1.2.5 β†’ 1.2.6, curl 8.19.0 β†’ 8.20.0, git 2.52.0 β†’ 2.54.0) and `cosign` 2.6.3 β†’ 3.0.6, which clears every HIGH/CRITICAL in the Node runtime and Alpine OS packages. The only residual HIGH/CRITICAL findings live inside the vendored Go module graphs compiled into the bundled `cosign` and `trivy` CLI binaries (drydock shells out to them for signature verification and container scanning) β€” those clear only when Alpine rebuilds the packages, so a documented `.grype.yaml` scopes the fail-on-HIGH image gate to the dependencies drydock controls (Node, OS packages, the app npm graph) and excludes the two tool-binary locations. cosign 3.0.6 keeps the `verify --output json`/`--certificate-identity`/`--certificate-oidc-issuer`/`--key` flags drydock's signature path uses.

## [1.5.0-rc.37] β€” 2026-06-15

### Security
Expand Down
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# checkov:skip=CKV_DOCKER_3: entrypoint uses su-exec for runtime privilege drop
# Common Stage
FROM node:24-alpine@sha256:7fddd9ddeae8196abf4a3ef2de34e11f7b1a722119f91f28ddf1e99dcafdf114 AS base
FROM node:24-alpine@sha256:21f403ab171f2dc89bad4dd69d7721bfd15f084ccb46cdd225f31f2bc59b5c9a AS base
WORKDIR /home/node/app

LABEL maintainer="CodesWhat"
Expand All @@ -24,15 +24,15 @@ HEALTHCHECK --interval=30s --timeout=5s CMD ["sh", "-c", "if [ -n \"$DD_SERVER_E
# pinned to the package name only.
# hadolint ignore=DL3018
RUN apk add --no-cache \
bash=5.3.3-r1 \
bash=5.3.9-r1 \
curl \
git=2.52.0-r0 \
git=2.54.0-r0 \
jq=1.8.1-r0 \
openssl=3.5.7-r0 \
su-exec=0.3-r0 \
tini=0.19.0-r3 \
tzdata=2026b-r0 \
&& apk add --no-cache cosign=2.6.3-r1 \
&& apk add --no-cache cosign=3.0.6-r1 \
&& apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing trivy \
&& apk upgrade --no-cache zlib libcrypto3 libssl3 \
&& mkdir /store && chown node:node /store
Expand Down
Loading