From b116b3164291cb81bedd0e25538b953de2ef54ed Mon Sep 17 00:00:00 2001 From: Kyle Santiago Date: Tue, 20 Oct 2026 21:51:56 -0400 Subject: [PATCH 1/2] Strip npm from the frontend image and scan it in CI --- .github/workflows/security-scans.yml | 10 +++++++--- frontend/Dockerfile | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/security-scans.yml b/.github/workflows/security-scans.yml index abd9607f7..4b79e6060 100644 --- a/.github/workflows/security-scans.yml +++ b/.github/workflows/security-scans.yml @@ -73,16 +73,20 @@ jobs: container-scan: runs-on: ubuntu-latest timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + image: [backend, frontend] steps: - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 with: persist-credentials: false # --pull so a cached base image cannot make the RUN layer a cache hit and - # silently skip the pinned security upgrade. - - run: docker build --pull --tag canary-backend:scan backend + # silently skip a pinned security upgrade. + - run: docker build --pull --tag canary-${{ matrix.image }}:scan ${{ matrix.image }} - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 with: - image-ref: canary-backend:scan + image-ref: canary-${{ matrix.image }}:scan format: table exit-code: '1' ignore-unfixed: true diff --git a/frontend/Dockerfile b/frontend/Dockerfile index dfafb4015..d7b815c88 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -39,6 +39,10 @@ ENV NODE_ENV=production RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 nextjs +# The base image's npm and corepack never run here and bring their own vulnerable dependencies. +RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/corepack \ + /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/corepack + # Copy public assets COPY --from=builder /app/public ./public From ced1b8d178f2c99738ed660204dc865df4d013b5 Mon Sep 17 00:00:00 2001 From: Kyle Santiago Date: Tue, 20 Oct 2026 21:58:23 -0400 Subject: [PATCH 2/2] Remove yarn too and keep the container-scan check name --- .github/workflows/security-scans.yml | 16 +++++++++++++++- frontend/Dockerfile | 6 +++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/security-scans.yml b/.github/workflows/security-scans.yml index 4b79e6060..ad7649a61 100644 --- a/.github/workflows/security-scans.yml +++ b/.github/workflows/security-scans.yml @@ -70,7 +70,7 @@ jobs: fi exit $rc - container-scan: + image-scan: runs-on: ubuntu-latest timeout-minutes: 15 strategy: @@ -91,3 +91,17 @@ jobs: exit-code: '1' ignore-unfixed: true severity: CRITICAL,HIGH + + # The deployment gate requires a single check named container-scan. + container-scan: + needs: image-scan + if: always() + runs-on: ubuntu-latest + steps: + - env: + RESULT: ${{ needs.image-scan.result }} + run: | + if [ "$RESULT" != success ]; then + echo "::error::an image scan did not pass: $RESULT" + exit 1 + fi diff --git a/frontend/Dockerfile b/frontend/Dockerfile index d7b815c88..42e95a697 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -39,9 +39,9 @@ ENV NODE_ENV=production RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 nextjs -# The base image's npm and corepack never run here and bring their own vulnerable dependencies. -RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/corepack \ - /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/corepack +# The base image's package managers never run here and bring their own vulnerable dependencies. +RUN rm -rf /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/corepack /opt/yarn-v* \ + /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/corepack /usr/local/bin/yarn /usr/local/bin/yarnpkg # Copy public assets COPY --from=builder /app/public ./public