Skip to content

Updated vulnerable packages #1573

Merged
KambleSahil3 merged 14 commits intomainfrom
fix/docker-vulnerabilities
Mar 23, 2026
Merged

Updated vulnerable packages #1573
KambleSahil3 merged 14 commits intomainfrom
fix/docker-vulnerabilities

Conversation

@DeepakNemad
Copy link
Copy Markdown
Contributor

@DeepakNemad DeepakNemad commented Feb 25, 2026

  • Updated vulnerable packages and Updated all Dockerfiles to use Node.js 24

Summary by CodeRabbit

  • Infrastructure/DevOps

    • Upgraded container base to Node 24 Alpine, standardized multi-stage builds, reduced image size, and simplified startup to run compiled Node apps directly.
  • Security

    • Runtime switched to non-root users, tightened file ownership/permissions, and removed runtime build/migration steps.
  • Dependencies

    • Large-scale dependency and dev-tooling upgrades (including Prisma and package manager pinning) for more consistent builds.

…s 24

Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
@DeepakNemad DeepakNemad self-assigned this Feb 25, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 25, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Upgrades and standardizes many Dockerfiles to Node 24 (alpine), pins pnpm, consolidates apk/pnpm steps, moves Prisma client generation to build stage, reduces final images to built artifacts/node_modules, enforces non-root runtime users, and applies broad dependency version bumps in package.json. (≤50 words)

Changes

Cohort / File(s) Summary
Service Dockerfiles — build-stage & package handling
Dockerfiles/Dockerfile.agent-provisioning, Dockerfiles/Dockerfile.agent-service, Dockerfiles/Dockerfile.api-gateway, Dockerfiles/Dockerfile.cloud-wallet, Dockerfiles/Dockerfile.connection, Dockerfiles/Dockerfile.ecosystem, Dockerfiles/Dockerfile.geolocation, Dockerfiles/Dockerfile.issuance, Dockerfiles/Dockerfile.ledger, Dockerfiles/Dockerfile.notification, Dockerfiles/Dockerfile.oid4vc-issuance, Dockerfiles/Dockerfile.oid4vc-verification, Dockerfiles/Dockerfile.organization, Dockerfiles/Dockerfile.user, Dockerfiles/Dockerfile.utility, Dockerfiles/Dockerfile.verification, Dockerfiles/Dockerfile.webhook, Dockerfiles/Dockerfile.x509
Build stage base updated to node:24-alpine3.21; consolidated apk/openssl steps; pin and install pnpm@9.15.3; package manifests copied together; PUPPETEER_SKIP_DOWNLOAD=true; pnpm i --frozen-lockfile --ignore-scripts; prisma generate moved to build; service builds run in build stage.
Service Dockerfiles — final image & runtime
(same files as above)
Final base to node:24-alpine3.21; create non-root nextjs user / nodejs group (uid/gid 1001); copy production node_modules (and service dist as needed) from build; remove runtime Prisma migrate/generate; set USER nextjs; simplified CMD to ["node","dist/apps/<service>/main.js"]; add ownership/permission steps.
Special Dockerfiles — seed & oid4vc-verification specifics
Dockerfiles/Dockerfile.seed, Dockerfiles/Dockerfile.oid4vc-verification
seed: adds postgresql-client, consolidates apk/pnpm steps, ensures non-root user, CMD seeds DB via npx prisma db seed. oid4vc-verification: retains explicit ownership/permissions for copied artifacts and follows the general Node24/pnpm/prisma-in-build pattern.
Package manifest
package.json
Large dependency and devDependency version upgrades across many packages (notable: @prisma/client, AWS SDK, OpenTelemetry packages, many @types/*, tooling). No API/export signature changes detected.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

feature

Suggested reviewers

  • ajile-in
  • KambleSahil3

Poem

🐰
I hopped through layers, light and spry,
Pinned pnpm, moved Prisma to the sky,
Non-root naps in Alpine's shade,
Cleaner builds and smaller trade,
A carrot for the CI pie 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Updated vulnerable packages' is vague and generic, using a non-descriptive term that doesn't clearly convey the scope of changes. Consider a more specific title that captures the main changes, such as 'Upgrade Node.js to v24 and update dependencies' or 'Update Node.js and fix Docker vulnerabilities across all services'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/docker-vulnerabilities

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 20

♻️ Duplicate comments (5)
Dockerfiles/Dockerfile.oid4vc-issuance (1)

1-24: Same cross-cutting issues as noted in Dockerfile.oid4vc-verification apply here.

No additional unique issues beyond the unpinned pnpm, missing lockfile, prisma migrate in CMD, and full libs/ copy.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-issuance` around lines 1 - 24, The Dockerfile
repeats cross-cutting issues: pin pnpm version instead of installing latest
(replace RUN npm install -g pnpm@latest with a specific version), ensure a
lockfile is copied and used (COPY pnpm-lock.yaml before running pnpm i and run
pnpm install --frozen-lockfile), avoid copying the entire libs/ into the runtime
image (only copy necessary built artifacts from /app/dist or specific libs
needed by oid4vc-issuance instead of COPY --from=build --chown=nextjs:nodejs
/app/libs/ ./libs/), and remove runtime schema changes from CMD (do not run
prisma migrate deploy in CMD; run migrations during image build or via a
separate migration step and keep CMD to start node
dist/apps/oid4vc-issuance/main.js).
Dockerfiles/Dockerfile.organization (1)

1-24: Same cross-cutting issues as noted in Dockerfile.oid4vc-verification apply here.

The unpinned pnpm@latest, missing lockfile before pnpm i, prisma migrate deploy in CMD, misleading user names, and full libs/ copy all apply identically to this file. No additional unique issues.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.organization` around lines 1 - 24, This Dockerfile
repeats the cross-cutting issues: pin pnpm instead of using RUN npm install -g
pnpm@latest, copy the lockfile (pnpm-lock.yaml) into the build stage before RUN
pnpm i --ignore-scripts so installs are reproducible, move runtime schema
migrations out of the container CMD (the long CMD that runs "cd
libs/prisma-service && npx prisma migrate deploy && npx prisma generate && ...")
into a controlled deploy/init step or run only prisma generate at build time
(use RUN in the build stage to npx prisma generate after copying schema), avoid
copying the entire libs/ directory into the final image (replace COPY
--from=build --chown=nextjs:nodejs /app/libs/ ./libs/ with only the needed built
artifacts or the prisma service output), and replace misleading user/group names
(adduser nextjs/ nodejs) with neutral names like appuser/appgroup or align names
with project conventions; ensure ENV PUPPETEER_SKIP_DOWNLOAD is still set if
required.
Dockerfiles/Dockerfile.notification (1)

1-24: Same cross-cutting issues as noted in Dockerfile.oid4vc-verification apply here.

No additional unique issues.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.notification` around lines 1 - 24, This Dockerfile
repeats cross-cutting issues: avoid copying full dev node_modules from the build
stage and invoking npx at runtime; instead produce a production-only
node_modules in the build stage (use pnpm install --prod or pnpm prune --prod in
the build stage after building), remove dev-only tooling from the final image,
and change the startup CMD to run the app binary directly without running npx
during container start; also ensure Prisma migration/generate steps are handled
safely (either run migrations as part of CI/deploy or run migration commands
from an init container or an entrypoint script that ensures proper DB
credentials and filesystem permissions for the nextjs user) — update the
Dockerfile lines involving RUN pnpm i --ignore-scripts, COPY --from=build
--chown=nextjs:nodejs /app/node_modules, USER nextjs, and CMD ["sh", "-c", "cd
libs/prisma-service && npx prisma migrate deploy && npx prisma generate && cd
../.. && node dist/apps/notification/main.js"] accordingly.
Dockerfiles/Dockerfile.utility (1)

1-24: Same cross-cutting issues as noted in Dockerfile.oid4vc-verification apply here.

No additional unique issues.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.utility` around lines 1 - 24, The Dockerfile repeats
cross-cutting issues: remove the global pnpm install and instead enable Corepack
or use pnpm from the build base, set NODE_ENV=production, install only
production dependencies during the build (replace "RUN pnpm i --ignore-scripts"
with a deterministic production install such as "pnpm install --frozen-lockfile
--prod" in the build stage and avoid copying the entire node_modules into the
final image), ensure prisma codegen runs at build time ("RUN cd
libs/prisma-service && npx prisma generate" is fine) and remove runtime
migration/generation from the CMD (remove "npx prisma migrate deploy && npx
prisma generate" from the CMD so migrations are applied out-of-band), and keep
copying only required artifacts ("COPY --from=build --chown=nextjs:nodejs
/app/dist/apps/utility/ ./dist/apps/utility/" and needed libs) while preserving
non-root user setup (nextjs/nodejs) and minimal layers.
Dockerfiles/Dockerfile.x509 (1)

1-24: Same cross-cutting issues as noted in Dockerfile.oid4vc-verification apply here.

Unpinned pnpm, missing lockfile, prisma migrate in CMD, and full libs/ copy.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` around lines 1 - 24, Pin pnpm instead of using
npm install -g pnpm@latest (replace the npm install command with a fixed
version, e.g., npm install -g pnpm@X.Y.Z) and ensure you COPY and use the
workspace lockfile (pnpm-lock.yaml) before running pnpm install so installs are
reproducible (reference COPY package.json pnpm-workspace.yaml and RUN pnpm i
--ignore-scripts). Remove heavy COPY of the entire libs/ into the final image
and instead copy only the built output and the generated Prisma client for
prisma-service (address COPY --from=build --chown=nextjs:nodejs /app/libs/
./libs/ and RUN cd libs/prisma-service && npx prisma generate in the build
stage). Move runtime migrations out of the container CMD (do not run npx prisma
migrate deploy && npx prisma generate inside CMD); either run migrations during
image build or implement a safe startup entrypoint script that conditionally
runs migrations with proper rights (modify the CMD line referencing prisma
migrate deploy && npx prisma generate accordingly).
🧹 Nitpick comments (10)
Trivy-scann-data/Before-detailed-vulnerability-report.md (1)

1-97: Consider adding an "After" scan report to confirm remediation.

This report captures the pre-fix vulnerability state, but there's no corresponding post-fix report to verify which CVEs were actually resolved by the Node 24 upgrade and dependency updates. Including a Trivy scan of the rebuilt images would provide evidence that the changes achieved their goal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Trivy-scann-data/Before-detailed-vulnerability-report.md` around lines 1 -
97, Add a new "After" scan section to the report that shows Trivy results for
the rebuilt images (post-Node24 and dependency updates): run Trivy on the same
image list (the entries under "## Images Scanned") using the rebuilt image tags,
include scan timestamp, per-image vulnerability counts and a CVE diff table
mapping which CVEs from the "## Critical Vulnerabilities Found" and "## High
Severity Vulnerabilities Found" sections were fixed vs. still present (reference
the report headers "Docker Images Vulnerability Scan Report", "## Images
Scanned", and the listed CVEs), and include a short CI note in "##
Recommendations" describing the command used (e.g., trivy image ...) and where
the after-scan artifacts are stored.
Dockerfiles/Dockerfile.seed (1)

1-8: Single-stage build includes all build-time dependencies in the final image.

Unlike the other Dockerfiles in this PR which use multi-stage builds, this Dockerfile installs build tools (pnpm, full source) directly into the runtime image. This increases image size and attack surface. Consider using a multi-stage build consistent with the rest of the services, copying only the necessary artifacts (prisma-service, node_modules, scripts) into a clean final stage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.seed` around lines 1 - 8, Current Dockerfile.seed
creates a single-stage image that installs build-time tools like pnpm and leaves
source/dependencies in the runtime image; convert it to a multi-stage build: add
a builder stage (FROM node:24-alpine3.21 AS builder) that runs apk add and RUN
npm install -g pnpm@latest, installs dependencies and builds the prisma-service,
then create a slim final stage (FROM node:24-alpine3.21) that only copies the
built artifacts, necessary node_modules, and runtime files from the builder,
re-creates the runtime user/group (addgroup/adduser nextjs), and omits pnpm and
other build-time packages (postgresql-client/openssl) to minimize image size and
attack surface.
Dockerfiles/Dockerfile.oid4vc-verification (2)

14-18: Non-root user/group names "nextjs"/"nodejs" are misleading for non-Next.js services.

These names originate from Next.js conventions but are used here across all backend microservices (oid4vc-verification, organization, notification, etc.). Consider using generic names like appuser/appgroup for clarity. This applies to all Dockerfiles in this PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` around lines 14 - 18, The
Dockerfile uses misleading non-root user/group names "nodejs" and "nextjs" in
the addgroup and adduser commands; update these invocations (addgroup -g 1001 -S
nodejs and adduser -S nextjs -u 1001) to use generic names such as appgroup and
appuser (e.g., addgroup -g 1001 -S appgroup and adduser -S appuser -u 1001) and
apply the same rename consistently across all Dockerfiles in the PR so service
images no longer reference Next.js-specific identifiers.

20-22: Copying entire /app/libs/ into the final image may include unnecessary source files.

Line 21 copies the full libs/ directory from the build stage. If only libs/prisma-service is needed at runtime (for Prisma migrations/generation), copying everything else bloats the final image and leaks build-time source into production.

Proposed fix — copy only what's needed
-COPY --from=build --chown=nextjs:nodejs /app/libs/ ./libs/
+COPY --from=build --chown=nextjs:nodejs /app/libs/prisma-service ./libs/prisma-service
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` around lines 20 - 22, The
Dockerfile currently copies the entire /app/libs/ directory into the final image
(COPY --from=build --chown=nextjs:nodejs /app/libs/ ./libs/), which pulls
unnecessary source and bloats the image; update that COPY to only copy the
runtime-required library (e.g., COPY --from=build --chown=nextjs:nodejs
/app/libs/prisma-service ./libs/prisma-service/) and any specific subpaths it
needs (migrations, generated client, schema) so only prisma-service artifacts
are included; keep the existing node_modules and other needed COPY lines but
avoid copying the rest of /app/libs/.
Dockerfiles/Dockerfile.agent-provisioning (2)

2-2: Consider using alpine3.22 or later for improved security posture.

The current Docker Hub tags show 24-alpine3.22 and 24-alpine3.23 variants are available. Since this PR is specifically about fixing vulnerabilities, pinning to alpine3.21 (released Dec 2024) means missing Alpine security patches from later releases.

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.agent-provisioning` at line 2, The base image is
pinned to node:24-alpine3.21 which misses newer Alpine security patches; update
the FROM line in the Dockerfile(s) (the FROM instruction referencing
node:24-alpine3.21) to a newer Alpine variant such as node:24-alpine3.22 or
node:24-alpine3.23 (or later) to pick up security fixes, and apply the same
update to any other Dockerfiles using alpine3.21 (e.g., the 22-22 variant).

31-32: Misleading user/group names nextjs:nodejs for a non-Next.js project.

This is the CREDEBL platform, not a Next.js app. Using nextjs and nodejs as the user/group names is confusing and suggests this was copy-pasted from a Next.js template. Consider using descriptive names like credebl or appuser. This applies to all Dockerfiles in the PR.

Proposed fix (apply across all Dockerfiles)
-    && addgroup -g 1001 -S nodejs \
-    && adduser -S nextjs -u 1001
+    && addgroup -g 1001 -S appgroup \
+    && adduser -S appuser -u 1001

And update all --chown=nextjs:nodejs references to --chown=appuser:appgroup and USER nextjs to USER appuser.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.agent-provisioning` around lines 31 - 32, Replace the
misleading Next.js-specific user/group names: change the addgroup/adduser calls
that create "nodejs" and "nextjs" (see addgroup -g 1001 -S nodejs and adduser -S
nextjs -u 1001) to descriptive names such as "appgroup"/"appuser" or
"credebl"/"credebl"; then update all related usages across the
Dockerfiles—replace any --chown=nextjs:nodejs occurrences with
--chown=appuser:appgroup (or your chosen names) and change USER nextjs to USER
appuser so the image user/group names consistently reflect the CREDEBL project.
Trivy-scann-data/Changes-made.md (1)

46-47: Piping a remote script to sudo sh is a security anti-pattern.

While this is a documentation/report file rather than a runnable script, documenting curl ... | sudo sh as a recommended installation method normalizes an insecure practice. Consider noting that the script should be downloaded, inspected, and then executed — or use a package manager.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Trivy-scann-data/Changes-made.md` around lines 46 - 47, The documented
installation line "sudo curl -sfL
https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh |
sudo sh -s -- -b /usr/local/bin" is a security anti-pattern; update
Changes-made.md to replace that single-line recommendation with guidance to
first download the installer, inspect/verify it (or verify a
checksum/signature), then run it with elevated privileges, or alternatively
recommend installing Trivy via a supported package manager or release binary;
mention the exact snippet text so the maintainer can locate and replace it.
Dockerfiles/Dockerfile.user (1)

20-22: Entire node_modules (including devDependencies) copied to production image.

Copying the full node_modules from the build stage includes development dependencies, inflating the final image. Consider using pnpm deploy --prod or pnpm prune --prod in the build stage before copying, to include only production dependencies in the final image. This applies to all Dockerfiles in this PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.user` around lines 20 - 22, The Dockerfile is copying
the entire node_modules from the build stage (see the COPY --from=build
--chown=nextjs:nodejs /app/node_modules ./node_modules line), which brings
devDependencies into the production image; update the build stage to install
only production dependencies (e.g., run pnpm deploy --prod or pnpm prune --prod
or pnpm install --prod in the build stage) and then remove or change the final
stage copy so it only includes the pruned production node_modules (or avoid
copying node_modules and use a production-only installation in the final stage);
ensure the change is applied to the same COPY invocation and any equivalent COPY
lines across the other Dockerfiles in the PR.
package.json (1)

59-63: Move @types/* packages to devDependencies.

Lines 59–63 contain type declaration packages that belong in devDependencies, not runtime dependencies. These are used only during TypeScript compilation, not at runtime. The codebase confirms actual usage of the underlying packages (async-retry, crypto-js, json2csv), while other @types/* packages are already correctly placed in devDependencies.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` around lines 59 - 63, Package.json currently lists type
declaration packages ("@types/async-retry", "@types/crypto-js",
"@types/json2csv", "@types/pdfkit") under dependencies; move each of these
entries out of dependencies and into devDependencies (preserving their versions)
so they are only installed for TypeScript compilation. Remove the entries from
dependencies and add them to devDependencies (or run the equivalent package
manager command, e.g., npm/yarn add --save-dev) and update any lockfile
accordingly.
Dockerfiles/Dockerfile.agent-service (1)

21-27: Remove unnecessary tools from runtime image to reduce size and attack surface.

The runtime stage (Stage 2) installs aws-cli, docker, docker-compose, and openssh-client, but none of these are invoked in the agent-service code. The container only runs node dist/apps/agent-service/main.js and Prisma migrations at runtime. Removing these four tools will reduce image bloat and security risk without impacting functionality.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.agent-service` around lines 21 - 27, Remove unused
runtime packages from the Stage 2 RUN layer: eliminate aws-cli, docker,
docker-compose, and openssh-client from the apk add list in the
Dockerfile.agent-service runtime stage so the image only installs required
packages (e.g., openssl) for running node dist/apps/agent-service/main.js and
Prisma migrations; update the RUN command to only add necessary packages and
keep the rm -rf /var/cache/apk/* cleanup to minimize image size and attack
surface.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfiles/Dockerfile.agent-provisioning`:
- Line 49: The Dockerfile's startup CMD currently runs "prisma migrate deploy"
and "npx prisma generate" which can race in multi-replica starts and redundantly
regenerate the client; remove both commands from the CMD and leave only the app
start (e.g., replace CMD ["sh", "-c", "cd libs/prisma-service && npx prisma
migrate deploy && npx prisma generate && cd ../.. && node
dist/apps/agent-provisioning/main.js"] with a CMD that simply starts the built
app like node dist/apps/agent-provisioning/main.js), and instead run migrations
via a separate migration job or init container (not in application startup);
keep the generation step only in the build stage where Prisma client was already
generated.
- Line 18: Remove the debug RUN line that lists files in the image—specifically
delete the "RUN ls -R /app/apps/agent-provisioning/AFJ/" instruction from the
Dockerfile so the extra build layer is not created; ensure no other build logic
depends on that command and keep the remaining Dockerfile steps unchanged.
- Line 11: The Dockerfile currently installs pnpm with a floating tag ("RUN npm
install -g pnpm@latest --ignore-scripts"); change this to pin pnpm to the
project's exact version (replace "@latest" with the version found in
package.json's packageManager field or the lockfile, e.g., "pnpm@9.15.4") so
builds are reproducible—update the RUN line(s) across all Dockerfiles that use
"npm install -g pnpm@latest --ignore-scripts".

In `@Dockerfiles/Dockerfile.agent-service`:
- Line 35: The Docker CMD currently runs Prisma migrations at container startup
(CMD invoking "npx prisma migrate deploy" and "npx prisma generate" in the
Dockerfile agent-service), which can cause race conditions; remove the migration
step from the CMD so the container only starts the app (keep only the runtime
invocation of node dist/apps/agent-service/main.js or node startup command) and
run migrations as a separate init job/CI step or Kubernetes
initContainer/entrypoint script; also remove or separate "npx prisma migrate
deploy" from the Dockerfile's CMD while retaining any necessary "npx prisma
generate" earlier in the build stage if required for production artifacts.
- Around line 10-14: Replace the unpinned global install and the incomplete
COPY: change the RUN that currently installs pnpm@latest to install a specific
pinned pnpm version (e.g., pnpm@<desired-version>) instead of `@latest`, and
update the COPY command that currently copies package.json and
pnpm-workspace.yaml to also include pnpm-lock.yaml so the subsequent RUN pnpm i
--ignore-scripts uses the lockfile for deterministic installs.

In `@Dockerfiles/Dockerfile.connection`:
- Line 24: The Dockerfile currently runs migrations in the container CMD (the
line invoking "npx prisma migrate deploy && npx prisma generate" inside CMD),
which should be removed from the app startup path; instead create a separate
one‑shot migration job (init container or pre-deploy hook) that runs the
commands "npx prisma migrate deploy && npx prisma generate" against the same
built image or a dedicated migration image, and change the Dockerfile CMD to
only start the app (e.g., run "node dist/apps/connection/main.js"); apply this
same change to all Dockerfiles that contain the migration invocation
(agent-provisioning, agent-service, api-gateway, cloud-wallet, connection,
ecosystem, geolocation, issuance, ledger, notification, oid4vc-issuance,
oid4vc-verification, organization, user, utility, verification, webhook, x509)
so migrations run once before app replicas start.
- Around line 4-8: Replace the global "npm install -g pnpm@latest" approach with
Corepack to pin the pnpm runtime, copy the repository's pnpm-lock.yaml into the
image alongside package.json and pnpm-workspace.yaml before running install, and
change the install invocation referenced by the RUN pnpm i --ignore-scripts
command to use --frozen-lockfile so the build strictly honors pnpm-lock.yaml;
keep ENV PUPPETEER_SKIP_DOWNLOAD=true and the WORKDIR /app usage intact.

In `@Dockerfiles/Dockerfile.issuance`:
- Around line 4-8: Replace the global install of "pnpm@latest" with the pinned
version declared in package.json (pnpm@9.15.3) and ensure the lockfile is copied
and honored: copy pnpm-lock.yaml alongside package.json/pnpm-workspace.yaml (the
COPY that currently targets package.json pnpm-workspace.yaml ./) and change the
install invocation (the RUN pnpm i --ignore-scripts) to fail if the lockfile is
out of date (use pnpm install with the frozen-lockfile behavior). Keep ENV
PUPPETEER_SKIP_DOWNLOAD=true as-is; the goal is to enforce reproducible installs
by using the pinned pnpm executable and by installing strictly from the
committed pnpm-lock.yaml.
- Line 24: Remove runtime schema migration and generate commands from the image
startup command: delete the "npx prisma migrate deploy" and "npx prisma
generate" invocations from the Dockerfile CMD that currently runs in
libs/prisma-service and leave the container startup to only launch the app (node
dist/apps/issuance/main.js). Keep prisma generate in the build stage (it already
runs on line 10) and move "prisma migrate deploy" to your deployment
orchestration (an init Job, initContainer, or Helm/Kustomize pre-install hook)
so migrations run once before replicas start; apply this same change to all 19
microservice Dockerfiles that currently run migrations in CMD.

In `@Dockerfiles/Dockerfile.ledger`:
- Around line 4-8: The Dockerfile uses a non-deterministic pnpm install (RUN npm
install -g pnpm@latest) and omits the lockfile from COPY (COPY package.json
pnpm-workspace.yaml ./), which breaks reproducible builds; update the Dockerfile
to pin pnpm to a specific version instead of pnpm@latest and include the
repository's pnpm-lock.yaml in the COPY step so that the subsequent RUN pnpm i
--ignore-scripts installs deterministically while keeping ENV
PUPPETEER_SKIP_DOWNLOAD=true unchanged.
- Line 24: The Dockerfile currently runs migration and codegen at container
start via the CMD invoking "cd libs/prisma-service && npx prisma migrate deploy
&& npx prisma generate && ... node dist/apps/ledger/main.js", which causes race
conditions and tight coupling; remove the runtime migration and generation
commands from the CMD so the container just starts the app (node
dist/apps/ledger/main.js), and move "npx prisma migrate deploy" into a
centralized one-time deployment step (init container, Kubernetes Job, or
dedicated migration service) that targets the database before app pods start;
also remove redundant "npx prisma generate" at runtime since it should run
during the Dockerfile build (ensure libs/prisma-service codegen is executed in
build stage instead).

In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Line 24: The Dockerfile currently runs "npx prisma migrate deploy" in the
image CMD (the CMD line invoking prisma migrate deploy && npx prisma generate &&
node dist/apps/oid4vc-verification/main.js), which risks concurrent migrations
for multi-replica deployments; remove the migration step from the CMD so the
container only starts the app (keep npx prisma generate if you need runtime
codegen, or better run generate at build time), and instead run migrations as a
one-time operation outside the replica containers (e.g., a Kubernetes Job, Helm
pre-install hook, or an init container that is executed once), updating the
Dockerfile's CMD to only start the app (refer to the CMD invocation and the "npx
prisma migrate deploy" token to locate the change).
- Around line 4-8: Copy the repository lockfile before installing dependencies
and pin the pnpm version instead of using "latest": update the Dockerfile so the
COPY step includes pnpm-lock.yaml (e.g., change COPY package.json
pnpm-workspace.yaml ./ to COPY package.json pnpm-workspace.yaml pnpm-lock.yaml
./) and move that COPY to occur before the RUN pnpm i --ignore-scripts, and
replace RUN npm install -g pnpm@latest with a pinned version like RUN npm
install -g pnpm@<PINNED_VERSION> (use the repo's agreed pnpm version); apply the
same two changes (include pnpm-lock.yaml in the pre-install copy and pin pnpm)
to all Dockerfiles in the repo.

In `@Dockerfiles/Dockerfile.seed`:
- Around line 10-18: The Dockerfile runs COPY --chown=nextjs:nodejs but then
executes RUN pnpm i and RUN cd libs/prisma-service && npx prisma generate as
root and later switches to USER nextjs for the CMD, which causes root-owned
node_modules/ and Prisma client files; to fix, keep the install/generate steps
as root but immediately chown the installed artefacts (e.g., chown -R
nextjs:nodejs node_modules libs/prisma-service/.prisma and generated client
files) before the USER nextjs directive, and remove the redundant COPY
pnpm-workspace.yaml ./ since COPY . . already includes it so the file isn't
copied twice; reference the RUN pnpm i, RUN cd libs/prisma-service && npx prisma
generate, COPY --chown=nextjs:nodejs, USER nextjs and CMD lines to locate the
changes.

In `@Dockerfiles/Dockerfile.user`:
- Line 4: Update the RUN instruction that installs pnpm (the line containing
"RUN npm install -g pnpm@latest") to match the other Dockerfiles by pinning pnpm
to a specific version and adding the --ignore-scripts flag (i.e., replace the
unpinned global install with a pinned version plus --ignore-scripts) so
installation is consistent and scripts are not executed during global install.

In `@Dockerfiles/Dockerfile.verification`:
- Around line 4-8: The Dockerfile uses a floating pnpm tag and omits the
lockfile which breaks reproducible builds: replace the floating install (the RUN
npm install -g pnpm@latest) with a pinned version (e.g., use an ARG PNPM_VERSION
and install pnpm@$PNPM_VERSION) and update the copy step (the COPY package.json
pnpm-workspace.yaml ./) to also copy pnpm-lock.yaml so the RUN pnpm i
--ignore-scripts layer uses the lockfile; adjust the Dockerfile to expose the
ARG and use the pinned version when running the install.
- Line 24: The CMD in Dockerfile.verification runs "npx prisma migrate deploy"
and "npx prisma generate" at container startup (inside CMD ["sh", "-c", "cd
libs/prisma-service && npx prisma migrate deploy && npx prisma generate && cd
../.. && node dist/apps/verification/main.js"]), which risks concurrent
migrations; remove the migration step from the container CMD and instead run
migrations as a separate one-off init job or deployment hook (keep prisma
generate in startup only if necessary), leaving the CMD to only start the app
(node dist/apps/verification/main.js) after removing "npx prisma migrate deploy"
from the command string and ensuring migration execution is handled by your
deployment pipeline or an init container.

In `@Dockerfiles/Dockerfile.x509`:
- Line 11: The Dockerfile uses "RUN npm run build x509" inconsistent with the
rest of the images that install pnpm and run builds via pnpm; change the build
command from "npm run build x509" to "pnpm run build x509" so the
Dockerfile.x509 uses pnpm for the build step (matching the earlier "pnpm i" and
other Dockerfiles).

In `@Trivy-scann-data/Changes-made.md`:
- Line 41: The sed command in the changes notes (sed -i
's/node:20-alpine3.21/node:24-alpine3.21/g') conflicts with other documentation
that mentions upgrading from Node 18 to 24 and a separate note claiming 20→24;
verify the actual base images in your Dockerfiles and then make the docs
consistent: if you actually upgraded from node:18-alpineX, update the sed
command and any lines that say "Node.js 20" to "Node.js 18", or if the real
upgrade was 20→24, correct the PR description and AI summary to say 20→24;
ensure the sed snippet (sed -i 's/node:20-alpine3.21/node:24-alpine3.21/g') and
the textual summaries all match the verified source version.
- Around line 175-179: The Markdown list items starting with "Enhanced
Security", "Updated Dependencies", "Performance", "Visibility", and
"Verification" are missing numeric list prefixes and have mismatched bold
markup; update each line to be a properly numbered list (e.g., "1. Enhanced
Security: Eliminated critical and most high-severity vulnerabilities") ensuring
consistent numbering (1.-5.), fix the bolding so it surrounds only the intended
text (if needed use **text**), and verify blank line or two-space line breaks
are correct so the list renders as separate numbered items.

---

Duplicate comments:
In `@Dockerfiles/Dockerfile.notification`:
- Around line 1-24: This Dockerfile repeats cross-cutting issues: avoid copying
full dev node_modules from the build stage and invoking npx at runtime; instead
produce a production-only node_modules in the build stage (use pnpm install
--prod or pnpm prune --prod in the build stage after building), remove dev-only
tooling from the final image, and change the startup CMD to run the app binary
directly without running npx during container start; also ensure Prisma
migration/generate steps are handled safely (either run migrations as part of
CI/deploy or run migration commands from an init container or an entrypoint
script that ensures proper DB credentials and filesystem permissions for the
nextjs user) — update the Dockerfile lines involving RUN pnpm i
--ignore-scripts, COPY --from=build --chown=nextjs:nodejs /app/node_modules,
USER nextjs, and CMD ["sh", "-c", "cd libs/prisma-service && npx prisma migrate
deploy && npx prisma generate && cd ../.. && node
dist/apps/notification/main.js"] accordingly.

In `@Dockerfiles/Dockerfile.oid4vc-issuance`:
- Around line 1-24: The Dockerfile repeats cross-cutting issues: pin pnpm
version instead of installing latest (replace RUN npm install -g pnpm@latest
with a specific version), ensure a lockfile is copied and used (COPY
pnpm-lock.yaml before running pnpm i and run pnpm install --frozen-lockfile),
avoid copying the entire libs/ into the runtime image (only copy necessary built
artifacts from /app/dist or specific libs needed by oid4vc-issuance instead of
COPY --from=build --chown=nextjs:nodejs /app/libs/ ./libs/), and remove runtime
schema changes from CMD (do not run prisma migrate deploy in CMD; run migrations
during image build or via a separate migration step and keep CMD to start node
dist/apps/oid4vc-issuance/main.js).

In `@Dockerfiles/Dockerfile.organization`:
- Around line 1-24: This Dockerfile repeats the cross-cutting issues: pin pnpm
instead of using RUN npm install -g pnpm@latest, copy the lockfile
(pnpm-lock.yaml) into the build stage before RUN pnpm i --ignore-scripts so
installs are reproducible, move runtime schema migrations out of the container
CMD (the long CMD that runs "cd libs/prisma-service && npx prisma migrate deploy
&& npx prisma generate && ...") into a controlled deploy/init step or run only
prisma generate at build time (use RUN in the build stage to npx prisma generate
after copying schema), avoid copying the entire libs/ directory into the final
image (replace COPY --from=build --chown=nextjs:nodejs /app/libs/ ./libs/ with
only the needed built artifacts or the prisma service output), and replace
misleading user/group names (adduser nextjs/ nodejs) with neutral names like
appuser/appgroup or align names with project conventions; ensure ENV
PUPPETEER_SKIP_DOWNLOAD is still set if required.

In `@Dockerfiles/Dockerfile.utility`:
- Around line 1-24: The Dockerfile repeats cross-cutting issues: remove the
global pnpm install and instead enable Corepack or use pnpm from the build base,
set NODE_ENV=production, install only production dependencies during the build
(replace "RUN pnpm i --ignore-scripts" with a deterministic production install
such as "pnpm install --frozen-lockfile --prod" in the build stage and avoid
copying the entire node_modules into the final image), ensure prisma codegen
runs at build time ("RUN cd libs/prisma-service && npx prisma generate" is fine)
and remove runtime migration/generation from the CMD (remove "npx prisma migrate
deploy && npx prisma generate" from the CMD so migrations are applied
out-of-band), and keep copying only required artifacts ("COPY --from=build
--chown=nextjs:nodejs /app/dist/apps/utility/ ./dist/apps/utility/" and needed
libs) while preserving non-root user setup (nextjs/nodejs) and minimal layers.

In `@Dockerfiles/Dockerfile.x509`:
- Around line 1-24: Pin pnpm instead of using npm install -g pnpm@latest
(replace the npm install command with a fixed version, e.g., npm install -g
pnpm@X.Y.Z) and ensure you COPY and use the workspace lockfile (pnpm-lock.yaml)
before running pnpm install so installs are reproducible (reference COPY
package.json pnpm-workspace.yaml and RUN pnpm i --ignore-scripts). Remove heavy
COPY of the entire libs/ into the final image and instead copy only the built
output and the generated Prisma client for prisma-service (address COPY
--from=build --chown=nextjs:nodejs /app/libs/ ./libs/ and RUN cd
libs/prisma-service && npx prisma generate in the build stage). Move runtime
migrations out of the container CMD (do not run npx prisma migrate deploy && npx
prisma generate inside CMD); either run migrations during image build or
implement a safe startup entrypoint script that conditionally runs migrations
with proper rights (modify the CMD line referencing prisma migrate deploy && npx
prisma generate accordingly).

---

Nitpick comments:
In `@Dockerfiles/Dockerfile.agent-provisioning`:
- Line 2: The base image is pinned to node:24-alpine3.21 which misses newer
Alpine security patches; update the FROM line in the Dockerfile(s) (the FROM
instruction referencing node:24-alpine3.21) to a newer Alpine variant such as
node:24-alpine3.22 or node:24-alpine3.23 (or later) to pick up security fixes,
and apply the same update to any other Dockerfiles using alpine3.21 (e.g., the
22-22 variant).
- Around line 31-32: Replace the misleading Next.js-specific user/group names:
change the addgroup/adduser calls that create "nodejs" and "nextjs" (see
addgroup -g 1001 -S nodejs and adduser -S nextjs -u 1001) to descriptive names
such as "appgroup"/"appuser" or "credebl"/"credebl"; then update all related
usages across the Dockerfiles—replace any --chown=nextjs:nodejs occurrences with
--chown=appuser:appgroup (or your chosen names) and change USER nextjs to USER
appuser so the image user/group names consistently reflect the CREDEBL project.

In `@Dockerfiles/Dockerfile.agent-service`:
- Around line 21-27: Remove unused runtime packages from the Stage 2 RUN layer:
eliminate aws-cli, docker, docker-compose, and openssh-client from the apk add
list in the Dockerfile.agent-service runtime stage so the image only installs
required packages (e.g., openssl) for running node
dist/apps/agent-service/main.js and Prisma migrations; update the RUN command to
only add necessary packages and keep the rm -rf /var/cache/apk/* cleanup to
minimize image size and attack surface.

In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Around line 14-18: The Dockerfile uses misleading non-root user/group names
"nodejs" and "nextjs" in the addgroup and adduser commands; update these
invocations (addgroup -g 1001 -S nodejs and adduser -S nextjs -u 1001) to use
generic names such as appgroup and appuser (e.g., addgroup -g 1001 -S appgroup
and adduser -S appuser -u 1001) and apply the same rename consistently across
all Dockerfiles in the PR so service images no longer reference Next.js-specific
identifiers.
- Around line 20-22: The Dockerfile currently copies the entire /app/libs/
directory into the final image (COPY --from=build --chown=nextjs:nodejs
/app/libs/ ./libs/), which pulls unnecessary source and bloats the image; update
that COPY to only copy the runtime-required library (e.g., COPY --from=build
--chown=nextjs:nodejs /app/libs/prisma-service ./libs/prisma-service/) and any
specific subpaths it needs (migrations, generated client, schema) so only
prisma-service artifacts are included; keep the existing node_modules and other
needed COPY lines but avoid copying the rest of /app/libs/.

In `@Dockerfiles/Dockerfile.seed`:
- Around line 1-8: Current Dockerfile.seed creates a single-stage image that
installs build-time tools like pnpm and leaves source/dependencies in the
runtime image; convert it to a multi-stage build: add a builder stage (FROM
node:24-alpine3.21 AS builder) that runs apk add and RUN npm install -g
pnpm@latest, installs dependencies and builds the prisma-service, then create a
slim final stage (FROM node:24-alpine3.21) that only copies the built artifacts,
necessary node_modules, and runtime files from the builder, re-creates the
runtime user/group (addgroup/adduser nextjs), and omits pnpm and other
build-time packages (postgresql-client/openssl) to minimize image size and
attack surface.

In `@Dockerfiles/Dockerfile.user`:
- Around line 20-22: The Dockerfile is copying the entire node_modules from the
build stage (see the COPY --from=build --chown=nextjs:nodejs /app/node_modules
./node_modules line), which brings devDependencies into the production image;
update the build stage to install only production dependencies (e.g., run pnpm
deploy --prod or pnpm prune --prod or pnpm install --prod in the build stage)
and then remove or change the final stage copy so it only includes the pruned
production node_modules (or avoid copying node_modules and use a production-only
installation in the final stage); ensure the change is applied to the same COPY
invocation and any equivalent COPY lines across the other Dockerfiles in the PR.

In `@package.json`:
- Around line 59-63: Package.json currently lists type declaration packages
("@types/async-retry", "@types/crypto-js", "@types/json2csv", "@types/pdfkit")
under dependencies; move each of these entries out of dependencies and into
devDependencies (preserving their versions) so they are only installed for
TypeScript compilation. Remove the entries from dependencies and add them to
devDependencies (or run the equivalent package manager command, e.g., npm/yarn
add --save-dev) and update any lockfile accordingly.

In `@Trivy-scann-data/Before-detailed-vulnerability-report.md`:
- Around line 1-97: Add a new "After" scan section to the report that shows
Trivy results for the rebuilt images (post-Node24 and dependency updates): run
Trivy on the same image list (the entries under "## Images Scanned") using the
rebuilt image tags, include scan timestamp, per-image vulnerability counts and a
CVE diff table mapping which CVEs from the "## Critical Vulnerabilities Found"
and "## High Severity Vulnerabilities Found" sections were fixed vs. still
present (reference the report headers "Docker Images Vulnerability Scan Report",
"## Images Scanned", and the listed CVEs), and include a short CI note in "##
Recommendations" describing the command used (e.g., trivy image ...) and where
the after-scan artifacts are stored.

In `@Trivy-scann-data/Changes-made.md`:
- Around line 46-47: The documented installation line "sudo curl -sfL
https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh |
sudo sh -s -- -b /usr/local/bin" is a security anti-pattern; update
Changes-made.md to replace that single-line recommendation with guidance to
first download the installer, inspect/verify it (or verify a
checksum/signature), then run it with elevated privileges, or alternatively
recommend installing Trivy via a supported package manager or release binary;
mention the exact snippet text so the maintainer can locate and replace it.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e516d40 and 857ad18.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (23)
  • Dockerfiles/Dockerfile.agent-provisioning
  • Dockerfiles/Dockerfile.agent-service
  • Dockerfiles/Dockerfile.api-gateway
  • Dockerfiles/Dockerfile.cloud-wallet
  • Dockerfiles/Dockerfile.connection
  • Dockerfiles/Dockerfile.ecosystem
  • Dockerfiles/Dockerfile.geolocation
  • Dockerfiles/Dockerfile.issuance
  • Dockerfiles/Dockerfile.ledger
  • Dockerfiles/Dockerfile.notification
  • Dockerfiles/Dockerfile.oid4vc-issuance
  • Dockerfiles/Dockerfile.oid4vc-verification
  • Dockerfiles/Dockerfile.organization
  • Dockerfiles/Dockerfile.seed
  • Dockerfiles/Dockerfile.user
  • Dockerfiles/Dockerfile.utility
  • Dockerfiles/Dockerfile.verification
  • Dockerfiles/Dockerfile.webhook
  • Dockerfiles/Dockerfile.x509
  • Trivy-scann-data/After-vulnerability-scan-report.md
  • Trivy-scann-data/Before-detailed-vulnerability-report.md
  • Trivy-scann-data/Changes-made.md
  • package.json

Comment thread Dockerfiles/Dockerfile.agent-provisioning Outdated
Comment thread Dockerfiles/Dockerfile.agent-provisioning
Comment thread Dockerfiles/Dockerfile.agent-provisioning
Comment thread Dockerfiles/Dockerfile.agent-service Outdated
Comment thread Dockerfiles/Dockerfile.agent-service Outdated
Comment thread Dockerfiles/Dockerfile.verification Outdated
Comment thread Dockerfiles/Dockerfile.verification Outdated
Comment thread Dockerfiles/Dockerfile.x509 Outdated
Comment thread Trivy-scann-data/Changes-made.md Outdated
Comment thread Trivy-scann-data/Changes-made.md Outdated
Comment on lines +175 to +179
1. Enhanced Security**: Eliminated critical and most high-severity vulnerabilities
2. Updated Dependencies**: All packages updated to latest secure versions
3. Performance**: Node.js 24 provides better performance and security
4. Visibility**: Comprehensive vulnerability scanning and reporting implemented
5. Verification**: Confirmed fixes through post-remediation scanning
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Broken Markdown list formatting — missing list number prefix.

Lines 175–179 appear to have lost their numbered list prefix. They start with emoji but lack the 1., 2., etc., making them render as a single paragraph instead of a list.

Proposed fix
-1.  Enhanced Security**: Eliminated critical and most high-severity vulnerabilities
-2.  Updated Dependencies**: All packages updated to latest secure versions  
-3.  Performance**: Node.js 24 provides better performance and security
-4.  Visibility**: Comprehensive vulnerability scanning and reporting implemented
-5.  Verification**: Confirmed fixes through post-remediation scanning
+1. **Enhanced Security**: Eliminated critical and most high-severity vulnerabilities
+2. **Updated Dependencies**: All packages updated to latest secure versions  
+3. **Performance**: Node.js 24 provides better performance and security
+4. **Visibility**: Comprehensive vulnerability scanning and reporting implemented
+5. **Verification**: Confirmed fixes through post-remediation scanning
📝 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
1. Enhanced Security**: Eliminated critical and most high-severity vulnerabilities
2. Updated Dependencies**: All packages updated to latest secure versions
3. Performance**: Node.js 24 provides better performance and security
4. Visibility**: Comprehensive vulnerability scanning and reporting implemented
5. Verification**: Confirmed fixes through post-remediation scanning
1. **Enhanced Security**: Eliminated critical and most high-severity vulnerabilities
2. **Updated Dependencies**: All packages updated to latest secure versions
3. **Performance**: Node.js 24 provides better performance and security
4. **Visibility**: Comprehensive vulnerability scanning and reporting implemented
5. **Verification**: Confirmed fixes through post-remediation scanning
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Trivy-scann-data/Changes-made.md` around lines 175 - 179, The Markdown list
items starting with "Enhanced Security", "Updated Dependencies", "Performance",
"Visibility", and "Verification" are missing numeric list prefixes and have
mismatched bold markup; update each line to be a properly numbered list (e.g.,
"1. Enhanced Security: Eliminated critical and most high-severity
vulnerabilities") ensuring consistent numbering (1.-5.), fix the bolding so it
surrounds only the intended text (if needed use **text**), and verify blank line
or two-space line breaks are correct so the list renders as separate numbered
items.

Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Comment thread package.json Fixed
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 19

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

♻️ Duplicate comments (6)
Dockerfiles/Dockerfile.connection (1)

8-8: ⚠️ Potential issue | 🟠 Major

Enforce lockfile during install for deterministic builds.

Line 8 installs dependencies without --frozen-lockfile, so builds can still drift despite copying pnpm-lock.yaml.

🔧 Proposed fix
-RUN pnpm i --ignore-scripts
+RUN pnpm i --frozen-lockfile --ignore-scripts
#!/bin/bash
# Verify lockfile enforcement and install command in Dockerfile.connection
rg -nP 'COPY\s+package\.json\s+pnpm-lock\.yaml\s+pnpm-workspace\.yaml' Dockerfiles/Dockerfile.connection
rg -nP 'RUN\s+pnpm\s+i\b(?!.*--frozen-lockfile).*' Dockerfiles/Dockerfile.connection

Expected: first command matches; second command should return no matches after the fix.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.connection` at line 8, The Dockerfile currently runs
"RUN pnpm i --ignore-scripts" which ignores the lockfile and can cause
non-deterministic installs; update the RUN invocation that installs dependencies
(the line containing "RUN pnpm i --ignore-scripts") to enforce the lockfile by
adding the --frozen-lockfile flag (e.g., use pnpm install with --frozen-lockfile
and keep --ignore-scripts if needed) so installs fail when pnpm-lock.yaml is out
of sync.
Dockerfiles/Dockerfile.user (1)

4-4: ⚠️ Potential issue | 🟡 Minor

Add --ignore-scripts to global pnpm install.

Line 4 still allows lifecycle scripts during global install, which weakens container hardening.

Proposed fix
-RUN npm install -g pnpm@9.15.3
+RUN npm install -g pnpm@9.15.3 --ignore-scripts
#!/bin/bash
set -euo pipefail
# Verify global pnpm install commands and whether ignore-scripts is consistently applied
rg -nP 'RUN\s+npm\s+install\s+-g\s+pnpm@' Dockerfiles
rg -nP 'RUN\s+npm\s+install\s+-g\s+pnpm@.*--ignore-scripts' Dockerfiles
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.user` at line 4, The global pnpm install invocation in
the Dockerfile (the RUN npm install -g pnpm@9.15.3 command) allows lifecycle
scripts to run; update that RUN command to include the --ignore-scripts flag so
the global install is hardened (e.g., change the RUN that references pnpm@9.15.3
to include --ignore-scripts), and then scan other Dockerfiles for any other
occurrences of RUN npm install -g pnpm@... to apply the same --ignore-scripts
protection consistently.
Dockerfiles/Dockerfile.oid4vc-verification (1)

8-8: --frozen-lockfile still missing on pnpm i.

pnpm-lock.yaml is now copied before install (resolving half of the previously flagged issue), but the absence of --frozen-lockfile means pnpm can still silently update the lockfile during the build, producing non-deterministic installs.

🐛 Proposed fix
-RUN pnpm i --ignore-scripts
+RUN pnpm i --frozen-lockfile --ignore-scripts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` at line 8, The pnpm install step
(RUN pnpm i --ignore-scripts) can mutate pnpm-lock.yaml during image build;
update the Dockerfile's RUN invocation to include the --frozen-lockfile flag
(e.g., change RUN pnpm i --ignore-scripts to include --frozen-lockfile) so the
build fails if the lockfile would be altered and ensures deterministic installs.
Dockerfiles/Dockerfile.x509 (1)

11-11: pnpm run build x509 — previous inconsistency resolved.

The build command now correctly uses pnpm instead of npm.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` at line 11, The Dockerfile build step should
consistently use pnpm: update the RUN instruction so it reads "RUN pnpm run
build x509" (see the RUN pnpm run build x509 line) and propagate this change to
any other Dockerfiles or CI scripts still calling npm; also remove any stray
review-marker tokens like "[duplicate_comment]" or "[approve_code_changes]" left
in the commit/comments to avoid clutter.
Dockerfiles/Dockerfile.verification (1)

8-8: ⚠️ Potential issue | 🟠 Major

Install step should fail on lockfile drift.

Line 8 should use frozen lockfile mode so Docker builds remain deterministic.

Suggested fix
-RUN pnpm i --ignore-scripts
+RUN pnpm install --frozen-lockfile --ignore-scripts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.verification` at line 8, The Dockerfile uses a
non-deterministic install command (RUN pnpm i --ignore-scripts); update this to
run pnpm in frozen lockfile mode so builds fail on lockfile drift by replacing
that command with the equivalent frozen-lockfile invocation (e.g., use the
--frozen-lockfile flag alongside --ignore-scripts) in the Dockerfile's RUN
instruction.
Dockerfiles/Dockerfile.issuance (1)

8-8: ⚠️ Potential issue | 🟠 Major

Enforce lockfile during dependency install.

Line 8 still allows dependency resolution drift. For deterministic and auditable builds, install with a frozen lockfile.

Suggested fix
-RUN pnpm i --ignore-scripts
+RUN pnpm install --frozen-lockfile --ignore-scripts
#!/bin/bash
# Verify all Dockerfiles still using pnpm install without frozen lockfile
rg -nP 'RUN\s+pnpm\s+(?:i|install)\b(?!.*--frozen-lockfile).*--ignore-scripts' Dockerfiles/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.issuance` at line 8, Replace the Dockerfile RUN entry
that currently reads "RUN pnpm i --ignore-scripts" to enforce the lockfile by
adding pnpm's frozen-lockfile option so installs fail when the lockfile is out
of sync; update the RUN pnpm i --ignore-scripts line to include the
frozen-lockfile flag (so the build is deterministic and auditable).
🟡 Minor comments (5)
Dockerfiles/Dockerfile.connection-22-22 (1)

22-22: ⚠️ Potential issue | 🟡 Minor

Reduce runtime image size and attack surface by copying production dependencies only.

Line 22 copies the full node_modules from the build stage, which includes devDependencies and unnecessary files. Add a production-only pruning step after the build to reduce the runtime image footprint and vulnerability surface.

♻️ Suggested refinement
 RUN pnpm run build connection
+RUN pnpm prune --prod
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.connection` at line 22, The Dockerfile currently
copies the entire node_modules from the build stage via the COPY --from=build
/app/node_modules ./node_modules instruction which pulls devDependencies and
extras into the runtime image; update the build pipeline so that only production
dependencies are present before that COPY (for example run a production prune or
install step in the build stage such as npm ci --only=production or npm prune
--production) and then keep the COPY --from=build /app/node_modules
./node_modules as-is to copy only the pruned production deps; ensure the step
runs in the same build stage referenced as "build" so the runtime image size and
attack surface are reduced.
Dockerfiles/Dockerfile.oid4vc-verification-15-18 (1)

15-18: ⚠️ Potential issue | 🟡 Minor

nodejs group is never used; nextjs user name is mismatched for this service.

Two distinct problems:

  1. addgroup -g 1001 -S nodejs creates a group named nodejs, but adduser -S nextjs -u 1001 does not assign the user to that group. The nodejs group is orphaned and unused.
  2. The user name nextjs is semantically associated with Next.js applications, not an oid4vc-verification service. This is likely a copy-paste artefact from another service's Dockerfile and will cause confusion during incident response or audits.
🐛 Proposed fix
 RUN apk update && apk upgrade && apk add --no-cache openssl \
     && rm -rf /var/cache/apk/* \
-    && addgroup -g 1001 -S nodejs \
-    && adduser -S nextjs -u 1001
+    && addgroup -g 1001 -S nodejs \
+    && adduser -S oid4vc -u 1001 -G nodejs

Then update the downstream references:

-USER nextjs
+USER oid4vc
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` around lines 15 - 18, The
Dockerfile creates an unused group "nodejs" with addgroup and a mismatched user
"nextjs" with adduser; change them so the user and group are consistent and
semantically correct for this service: replace addgroup -g 1001 -S nodejs and
adduser -S nextjs -u 1001 with a single consistent pair (e.g., addgroup -g 1001
-S oid4vc && adduser -S oid4vc -u 1001 -G oid4vc or ensure adduser specifies -G
nodejs to join the nodejs group), and then update any downstream references that
assume the username/group to the new name (look for usages of "nextjs",
"nodejs", addgroup/adduser in this Dockerfile and related service configs).
Dockerfiles/Dockerfile.oid4vc-verification-20-22 (1)

20-22: ⚠️ Potential issue | 🟡 Minor

Files copied before USER nextjs are owned by root — add --chown to all COPY directives.

The three COPY --from=build instructions on lines 20–22 execute before USER nextjs is set, so all copied files are owned by root. If the app writes to any of these paths at runtime (e.g., Prisma's query engine extracting a binary, or log output), it will fail with a permission error because the non-root user has no write access.

The AI-generated summary also states that artifacts were "reduced to only node_modules", but dist/apps/oid4vc-verification/ and libs/ are still copied on lines 20–21.

🐛 Proposed fix
-COPY --from=build /app/dist/apps/oid4vc-verification/ ./dist/apps/oid4vc-verification/
-COPY --from=build /app/libs/ ./libs/
-COPY --from=build /app/node_modules ./node_modules
+COPY --chown=nextjs:nodejs --from=build /app/dist/apps/oid4vc-verification/ ./dist/apps/oid4vc-verification/
+COPY --chown=nextjs:nodejs --from=build /app/libs/ ./libs/
+COPY --chown=nextjs:nodejs --from=build /app/node_modules ./node_modules
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` around lines 20 - 22, The three
COPY --from=build instructions that copy /app/dist/apps/oid4vc-verification/,
/app/libs/, and /app/node_modules are executed as root before USER nextjs, so
change each COPY to include --chown=nextjs:nextjs (or the correct non-root
user/group used by USER nextjs) to ensure files are owned by the runtime user;
update the COPY lines that reference those paths (the COPY --from=build entries)
to add the --chown flag so runtime writes (e.g., Prisma extraction, logs) won’t
fail due to root-only ownership.
Dockerfiles/Dockerfile.x509-17-18 (1)

17-18: ⚠️ Potential issue | 🟡 Minor

nextjs user is not added to the nodejs group.

adduser -S nextjs -u 1001 creates the user without -G nodejs, leaving the nodejs group unused and group-based file permission checks broken for this user. The common pattern used across Next.js and NestJS Dockerfiles pairs these two commands explicitly.

🔧 Proposed fix
-    && adduser -S nextjs -u 1001
+    && adduser -S -G nodejs nextjs -u 1001
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` around lines 17 - 18, The Dockerfile creates a
nodejs group and a nextjs user but doesn't add nextjs to the nodejs group;
update the user creation command so nextjs is a member of nodejs (replace
"adduser -S nextjs -u 1001" with a command that includes the group, e.g.
"adduser -S -G nodejs nextjs -u 1001" or equivalent) so group-based file
permission checks work as expected; look for the commands that create the group
and user (addgroup -g 1001 -S nodejs and adduser -S nextjs -u 1001) and make
them consistent.
Dockerfiles/Dockerfile.x509-4-4 (1)

4-4: ⚠️ Potential issue | 🟡 Minor

Correct the pnpm version claim; the latest release is 10.29.3 (February 2026), not 10.30.2.

The Dockerfile pins pnpm@9.15.3, which the repository has explicitly declared in package.json with a corepack integrity hash. While v9 is now ~14 months behind the latest v10.29.3, this pinning appears intentional.

The main v10 breaking change—dependency lifecycle scripts disabled by default—is already mitigated in the Dockerfile via the --ignore-scripts flag on line 8, which is a best practice. If the team intends to remain on v9, the current setup is sound; if upgrading to v10 is planned, verify that native dependencies and postinstall hooks don't fail without explicit allowlisting in pnpm.onlyBuiltDependencies.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` at line 4, Update the pinned pnpm version in the
Dockerfile RUN instruction from 9.15.3 to 10.29.3 (the current v10 release) or
explicitly document/confirm intent to remain on v9; if upgrading, also update
the repo's package.json/corepack integrity entry to match v10.29.3 and run a
test build to ensure native/postinstall hooks still work given the v10 default
of disabling lifecycle scripts (verify pnpm.onlyBuiltDependencies or
allowlisting for required scripts); otherwise add a comment next to the RUN
pnpm@... line referencing the intentional pin to v9 and why it’s required.
🧹 Nitpick comments (13)
Dockerfiles/Dockerfile.seed (2)

8-8: Optional: use Corepack instead of npm install -g pnpm.

Node 24 ships with Corepack. corepack enable && corepack prepare pnpm@9.15.3 --activate avoids a global npm install and aligns with Node's built-in package manager toolchain.

♻️ Proposed change
-RUN npm install -g pnpm@9.15.3
+RUN corepack enable && corepack prepare pnpm@9.15.3 --activate
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.seed` at line 8, Replace the global npm install of
pnpm (the RUN npm install -g pnpm@9.15.3 line) with Node's Corepack workflow:
enable Corepack and prepare/activate the desired pnpm version (e.g., run
corepack enable && corepack prepare pnpm@9.15.3 --activate) so the Dockerfile
uses the built-in package manager management instead of installing pnpm
globally.

1-1: Consider upgrading the Alpine base to node:24-alpine3.23.

The current Docker Hub tags for node:24 LTS include 24-alpine3.22, 24-alpine3.23, and the floating 24-alpinealpine3.21 is the oldest pinned variant for node:24 and receives no further OS-level security patches. Pinning to node:24-alpine3.23 provides the same reproducibility with a more up-to-date OS base.

♻️ Proposed change
-FROM node:24-alpine3.21
+FROM node:24-alpine3.23
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.seed` at line 1, Update the Docker base image pin used
in the seed Dockerfile: replace the current FROM node:24-alpine3.21 reference
with FROM node:24-alpine3.23 so the container uses the newer Alpine OS variant;
ensure the single FROM line in Dockerfiles/Dockerfile.seed (the literal "FROM
node:24-alpine3.21") is changed to "FROM node:24-alpine3.23" to keep
reproducibility while picking up newer OS security patches.
Dockerfiles/Dockerfile.oid4vc-verification (2)

2-2: Consider upgrading to a more current Alpine variant.

node:24-alpine3.21 is an older Alpine variant; the current Node.js 24 LTS images on Docker Hub are 24-alpine3.22 and 24-alpine3.23. Using a newer Alpine base reduces the exposure to known OS-level CVEs and keeps the apk package index more current.

♻️ Suggested update (apply to both stages)
-FROM node:24-alpine3.21 AS build
+FROM node:24-alpine3.23 AS build
 ...
-FROM node:24-alpine3.21
+FROM node:24-alpine3.23
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` at line 2, Update the Docker base
image from the older Alpine variant to a current one by replacing all
occurrences of "FROM node:24-alpine3.21" (e.g., the "FROM node:24-alpine3.21 AS
build" line and any other FROM lines using that tag) with a newer tag such as
"node:24-alpine3.22" or "node:24-alpine3.23" in the Dockerfile so both build and
runtime stages use the updated Alpine variant.

4-4: Consider upgrading pnpm to v10.30.2 — The pinned version 9.15.3 is outdated. The current stable major version is 10.x (latest: 10.30.2), which includes improvements in security, performance, and efficiency. Review v10's release notes before upgrading if you're concerned about breaking changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` at line 4, Update the pinned pnpm
version in the Dockerfile by replacing the existing global install command that
references pnpm@9.15.3 (the RUN npm install -g pnpm@9.15.3 line) to use
pnpm@10.30.2; after changing the version, rebuild the image and run your
standard dependency/install workflows to verify there are no breaking changes
from v10, and consult v10 release notes if any test failures occur.
Dockerfiles/Dockerfile.webhook (2)

8-8: Add --frozen-lockfile to ensure reproducible dependency installs.

The --frozen-lockfile flag prevents updates to the lockfile during CI builds; the pnpm-lock.yaml file ensures reproducible builds by capturing exact dependency versions, preventing "works on my machine" problems by guaranteeing every environment uses identical dependencies. Without it, pnpm can silently resolve different versions inside the Docker layer if the lockfile drifts from package.json.

♻️ Proposed fix
-RUN pnpm i --ignore-scripts
+RUN pnpm i --frozen-lockfile --ignore-scripts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.webhook` at line 8, Update the Dockerfile command that
installs JS dependencies to use pnpm's frozen lockfile mode: modify the RUN pnpm
i --ignore-scripts invocation (in Dockerfile.webhook) to include the
--frozen-lockfile flag so the build will fail if pnpm-lock.yaml and package.json
disagree, ensuring reproducible installs in CI.

4-4: Consider using corepack to manage pnpm instead of a global npm install.

corepack is bundled with Node.js 24 but requires explicit activation. Using corepack enable && corepack prepare pnpm@9.15.3 --activate is the modern, idiomatic approach for managing pinned package manager versions without separate npm install -g steps.

♻️ Suggested alternative
-RUN npm install -g pnpm@9.15.3
+RUN corepack enable && corepack prepare pnpm@9.15.3 --activate
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.webhook` at line 4, Replace the global npm install
command with Corepack activation and preparation to pin pnpm: instead of running
"npm install -g pnpm@9.15.3" use Corepack flow by running "corepack enable" and
then "corepack prepare pnpm@9.15.3 --activate" so the Dockerfile uses Corepack
to manage the pnpm version; ensure Node runtime in the image supports Corepack
(Node 24+) or enable Corepack beforehand and verify the RUN step references the
same pnpm version (9.15.3) used elsewhere.
Dockerfiles/Dockerfile.geolocation (3)

8-8: Add --frozen-lockfile to ensure reproducible builds.

Without --frozen-lockfile, pnpm can silently modify pnpm-lock.yaml during install if it detects drift, producing non-deterministic images across builds.

♻️ Proposed fix
-RUN pnpm i --ignore-scripts
+RUN pnpm i --frozen-lockfile --ignore-scripts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.geolocation` at line 8, Update the
Dockerfile.geolocation RUN command that currently invokes "pnpm i
--ignore-scripts" to add the --frozen-lockfile flag so installs fail if
pnpm-lock.yaml is out of sync; locate the RUN line with "pnpm i
--ignore-scripts" and modify it to include --frozen-lockfile to enforce
reproducible, deterministic builds.

15-18: nodejs group is created but never associated with the nextjs user.

adduser -S nextjs -u 1001 creates the nextjs user with a primary group also named nextjs, not nodejs. The nodejs group (GID 1001) is unused. Either add the user to the nodejs group or rename the group to match the user for clarity.

♻️ Proposed fix (consistent naming)
 RUN apk update && apk upgrade && apk add --no-cache openssl \
     && rm -rf /var/cache/apk/* \
-    && addgroup -g 1001 -S nodejs \
-    && adduser -S nextjs -u 1001
+    && addgroup -g 1001 -S nodejs \
+    && adduser -S nextjs -u 1001 -G nodejs
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.geolocation` around lines 15 - 18, The Dockerfile
creates a group with addgroup -g 1001 -S nodejs but then creates a user with
adduser -S nextjs -u 1001 which results in a separate primary group named
nextjs; update the user/group pairing so they match by either creating the group
with the same name as the user (change addgroup to use nextjs) or explicitly add
the nextjs user to the nodejs group (use adduser/addgroup flags to set the
primary/group membership), ensuring the symbols addgroup, adduser, nodejs, and
nextjs are adjusted consistently.

2-2: Update node:24-alpine3.21 to node:24-alpine3.23 on both build and final stages.

Node 24 currently tracks Alpine 3.23. Alpine 3.21 reached support status with "main-only" patches until 2026-11-01, while 3.23 receives "main + community" patches until 2027-11-01, providing longer security coverage and broader patch availability. Upgrading both FROM instructions to node:24-alpine3.23 aligns with the current LTS default.

Also applies to: 14-14

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.geolocation` at line 2, Update the Dockerfile base
image tags: replace the FROM image tag node:24-alpine3.21 with
node:24-alpine3.23 in both occurrences (the build stage and the final stage FROM
lines) so both stages use node:24-alpine3.23 to align with current Node 24
Alpine tracking and extended patch support.
Dockerfiles/Dockerfile.utility (1)

15-18: Bind nextjs to the created nodejs group explicitly.

addgroup is created but not explicitly used by adduser; making membership explicit avoids UID/GID ambiguity across environments.

Proposed fix
 RUN apk update && apk upgrade && apk add --no-cache openssl \
     && rm -rf /var/cache/apk/* \
     && addgroup -g 1001 -S nodejs \
-    && adduser -S nextjs -u 1001
+    && adduser -S nextjs -u 1001 -G nodejs
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.utility` around lines 15 - 18, The created group
nodejs is not being used when creating the nextjs user; update the adduser
invocation so nextjs is explicitly added to the nodejs group (e.g., use the
adduser flag to set primary group to nodejs) to avoid UID/GID ambiguity — change
the adduser command that currently references nextjs and UID 1001 to include the
nodejs group reference so nextjs is bound to nodejs.
Dockerfiles/Dockerfile.x509 (2)

20-22: Add --chown=nextjs:nodejs to all COPY instructions before the USER switch.

Without --chown, all copied files are owned by root:root. The nextjs user can still read them (world-readable defaults), but any runtime write (e.g., caches, temp files under /app) will fail. Applying --chown is the canonical pattern for least-privilege containers.

🔧 Proposed fix
-COPY --from=build /app/dist/apps/x509/ ./dist/apps/x509/
-COPY --from=build /app/libs/ ./libs/
-COPY --from=build /app/node_modules ./node_modules
+COPY --chown=nextjs:nodejs --from=build /app/dist/apps/x509/ ./dist/apps/x509/
+COPY --chown=nextjs:nodejs --from=build /app/libs/ ./libs/
+COPY --chown=nextjs:nodejs --from=build /app/node_modules ./node_modules
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` around lines 20 - 22, The three COPY
instructions (COPY --from=build /app/dist/apps/x509/ ./dist/apps/x509/, COPY
--from=build /app/libs/ ./libs/, COPY --from=build /app/node_modules
./node_modules) should include ownership flag --chown=nextjs:nodejs so files
aren't root-owned when the Dockerfile later switches to the USER; update those
COPY lines to add --chown=nextjs:nodejs (before the USER switch) to ensure
nextjs can write caches/temp files at runtime.

8-8: Use --frozen-lockfile to prevent silent lockfile drift in CI/Docker builds.

pnpm i without --frozen-lockfile will silently update pnpm-lock.yaml if it's out of sync, producing a non-reproducible image. In a Dockerfile, the lockfile should always be the source of truth.

🔧 Proposed fix
-RUN pnpm i --ignore-scripts
+RUN pnpm i --frozen-lockfile --ignore-scripts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` at line 8, Replace the plain pnpm install
invocation in the Dockerfile RUN step with one that enforces the lockfile to
avoid drift: change the RUN command that currently calls "pnpm i" (the RUN pnpm
i --ignore-scripts step) to include the --frozen-lockfile flag (you can keep
--ignore-scripts if needed), so the build fails when pnpm-lock.yaml is out of
sync rather than silently updating it.
Dockerfiles/Dockerfile.agent-service (1)

21-27: Re-validate runtime need for Docker/AWS tooling in final stage.

Lines 21-27 install aws-cli, docker, docker-compose, and openssh-client in the runtime image. If the service doesn’t execute these binaries at runtime, remove them to reduce attack surface and patch churn.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.agent-service` around lines 21 - 27, The runtime
image's RUN layer that installs openssl, openssh-client, aws-cli, docker, and
docker-compose should be reviewed and trimmed: verify whether any runtime code
calls these binaries (search for usage of aws, docker, docker-compose, ssh in
entrypoint, service code, or health scripts) and if they are not required at
runtime remove them from the RUN install line (keep only openssl if TLS/crypto
libs are needed), thereby deleting the aws-cli, docker, docker-compose, and
openssh-client packages from the final image to reduce attack surface; if any
are required, document their usage in the Dockerfile comments and consider
moving build-only tools into a separate build stage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfiles/Dockerfile.agent-provisioning`:
- Line 15: Update the Dockerfile RUN invocation that currently uses "pnpm i
--ignore-scripts" to enforce the committed lockfile during image builds: change
the command to include the --frozen-lockfile flag so pnpm fails if the lockfile
and package manifests diverge (i.e., replace the existing RUN pnpm i
--ignore-scripts invocation in the Dockerfile with one that adds
--frozen-lockfile).

In `@Dockerfiles/Dockerfile.agent-service`:
- Line 14: The runtime image currently contains dev dependencies because the
build stage runs "pnpm i --ignore-scripts" and the node_modules are copied into
the final image; to fix this, in the build stage (the stage that runs "RUN pnpm
i --ignore-scripts" and performs the build) add a step to prune dev dependencies
by running "pnpm prune --prod" after the build is complete and before
node_modules are copied to the final image so only production dependencies
remain in the final image.
- Line 14: Replace the non-deterministic install command in the Dockerfile where
RUN pnpm i --ignore-scripts is used: change the invocation to enforce the
lockfile by adding --frozen-lockfile so pnpm will fail if package.json and the
lockfile diverge, ensuring reproducible builds; update the RUN line that
currently invokes pnpm i --ignore-scripts to include --frozen-lockfile (and keep
--ignore-scripts if needed).

In `@Dockerfiles/Dockerfile.api-gateway`:
- Line 8: Update the Dockerfile RUN invocation that currently executes "RUN pnpm
i --ignore-scripts" to enforce lockfile fidelity by adding the --frozen-lockfile
flag; specifically, modify the RUN command used to install node dependencies
(the line invoking pnpm install with --ignore-scripts) so it includes
--frozen-lockfile to fail the build if pnpm-lock.yaml is out of sync and ensure
reproducible installs.

In `@Dockerfiles/Dockerfile.cloud-wallet`:
- Line 8: The Dockerfile currently runs "pnpm i --ignore-scripts" which allows
installs to ignore the committed lockfile; update the RUN step to enforce the
lockfile by adding pnpm's frozen lockfile option so the build uses the committed
lockfile (i.e., run pnpm install with --frozen-lockfile alongside
--ignore-scripts in the same RUN instruction).

In `@Dockerfiles/Dockerfile.ecosystem`:
- Line 8: The Dockerfile's pnpm install command (RUN pnpm i --ignore-scripts)
doesn't enforce a frozen lockfile; update that command to include the
--frozen-lockfile flag so installs fail if package-lock changes (e.g., change
RUN pnpm i --ignore-scripts to include --frozen-lockfile) to ensure reproducible
builds and prevent accidental lockfile modifications.

In `@Dockerfiles/Dockerfile.geolocation`:
- Line 22: The final image currently copies the full build-stage node_modules
(COPY --from=build /app/node_modules ./node_modules) which includes
devDependencies installed by pnpm i; instead remove that COPY and perform a
production-only install in the final stage (e.g., run pnpm deploy or run pnpm
install with production flags / NODE_ENV=production) so only runtime deps are
included, or alternatively run a separate pnpm i --prod (or pnpm install
--frozen-lockfile --prod) in the final stage; update the Dockerfile.geolocation
final stage to stop copying node_modules from build and invoke the production
install command (keep existing build-stage pnpm i for building artifacts).

In `@Dockerfiles/Dockerfile.oid4vc-issuance`:
- Line 8: The production image currently installs dev deps (RUN pnpm i
--ignore-scripts) and then copies the full /app/node_modules into the final
stage (COPY --from=builder /app/node_modules), so dev packages remain in the
runtime image; after the build step in the builder stage and before the final
stage copies node_modules, run pnpm prune --prod (or pnpm prune --prod --filter
.) to remove devDependencies from node_modules so only production dependencies
are copied into the final image.

In `@Dockerfiles/Dockerfile.organization`:
- Line 22: The runtime image is copying the full node_modules (COPY --from=build
/app/node_modules ./node_modules) which includes devDependencies installed by
pnpm i --ignore-scripts; to fix, add a step in the build stage to prune
devDependencies before the runtime COPY by running pnpm prune --prod (or pnpm
prune --prod --no-optional if desired) after the build completes and before the
node_modules are copied, so the build stage's node_modules only contains
production deps when used by the runtime stage.
- Line 8: The Dockerfile uses a non-deterministic install command: locate the
RUN layer that invokes pnpm (currently written as "pnpm i --ignore-scripts") and
change it to use pnpm's frozen-lockfile mode while preserving ignore-scripts
(i.e., run pnpm install with the --frozen-lockfile flag and keep
--ignore-scripts) so builds use the committed pnpm-lock.yaml and are
reproducible.

In `@Dockerfiles/Dockerfile.seed`:
- Around line 16-18: The CMD currently only runs "npx prisma db seed" (in the
container after chown -R nextjs:nodejs and USER nextjs), which drops the
previous migration step; restore the missing migration by updating the CMD to
run "npx prisma migrate deploy" before "npx prisma db seed" (targeting the same
libs/prisma-service working dir) so migrations are applied prior to seeding;
ensure both commands run as the nextjs user and execute in libs/prisma-service
(e.g., combine or chain migrate deploy then db seed in the CMD).

In `@Dockerfiles/Dockerfile.user`:
- Line 24: The Dockerfile.user currently starts the app directly via CMD
["node", "dist/apps/user/main.js"], which bypasses the package.json "start"
script that runs migrations; update the Dockerfile.user to run migrations before
starting the app (e.g. invoke npx prisma migrate deploy or the "start" script)
or ensure CI/CD runs npx prisma migrate deploy prior to image deployment, or
alternatively implement an init container/job in docker-compose/Kubernetes to
run npx prisma migrate deploy; locate the CMD in Dockerfile.user and replace or
wrap it so migrations (npx prisma migrate deploy) complete successfully before
launching the main process.

In `@Dockerfiles/Dockerfile.utility`:
- Around line 20-22: The runtime image is carrying devDependencies because the
build stage copies the full node_modules into the runtime (see COPY --from=build
/app/node_modules ./node_modules); after the build step in the build stage
(before those COPYs) run a production prune (e.g., execute pnpm prune --prod or
equivalent) to remove devDependencies from /app/node_modules, then ensure the
Dockerfile still uses COPY --from=build /app/node_modules ./node_modules so only
production deps are copied into the runtime image.
- Line 24: The Dockerfile currently sets CMD ["node",
"dist/apps/utility/main.js"] which bypasses the npm start script that runs
prisma migrate deploy, so migrations are never executed; fix by ensuring
migrations run before the app process starts — either change the container
startup to invoke the start script (use the package.json "start" script instead
of directly running node), add an init container that runs npm run start:migrate
or prisma migrate deploy prior to launching the utility container, or add a
pre-deployment step in continuous-delivery.yml to run prisma migrate deploy;
update docker-compose.yml or CI config accordingly to call the start script or
explicit migration command so the database schema is applied before the service
runs.
- Line 8: Replace the existing RUN command "RUN pnpm i --ignore-scripts" with a
frozen-lockfile install; update it to "RUN pnpm i --frozen-lockfile
--ignore-scripts" (or "pnpm install --frozen-lockfile --ignore-scripts") so the
build uses the checked-in pnpm-lock.yaml for deterministic installs while
preserving the original --ignore-scripts behavior.

In `@Dockerfiles/Dockerfile.webhook`:
- Line 2: The Dockerfile uses the superseded base image tag "FROM
node:24-alpine3.21"; update both occurrences of that FROM line to
"node:24-alpine3.23" (or use the floating "node:24-alpine" alias if you want
automatic patch updates) so the build uses the current Alpine variant with
downstream CVE fixes; ensure any other identical FROM lines (e.g., the second
stage) are changed as well.
- Line 22: The final image is copying the full node_modules from the build stage
(COPY --from=build /app/node_modules ./node_modules) which includes
devDependencies; before performing that COPY, run a production prune in the
build stage (e.g., invoke pnpm prune --prod after install/build) or replace the
current build stage with a dedicated production-install stage that installs only
prod deps and then COPY --from=prod-stage /app/node_modules ./node_modules;
update the Dockerfile so the node_modules copied into the final image contains
only production dependencies.

In `@Dockerfiles/Dockerfile.x509`:
- Line 22: The final image is copying /app/node_modules from the build stage
(COPY --from=build /app/node_modules ./node_modules) but the build stage runs
pnpm i without production pruning, so devDependencies are included; update the
build stage to perform a production-only install (e.g., run pnpm install --prod
or set NODE_ENV=production and run pnpm install, or run pnpm prune --prod after
install) so that /app/node_modules in the build stage contains only production
deps before the COPY; ensure the command in the Dockerfile that currently runs
pnpm i is replaced or followed by the production-prune step so the final COPY
only brings production packages.
- Line 24: The container currently bypasses migrations by using the raw CMD
["node", "dist/apps/x509/main.js"] while the package.json "start" script runs
npx prisma migrate deploy; fix by ensuring prisma migrations run before app
start: either (A) change the image entry to run the existing "start" script (use
npm start) or add an entrypoint that runs npx prisma migrate deploy
--schema=./libs/prisma-service/prisma/schema.prisma before launching node, or
(B) move migrations out of the container and add a dedicated deployment step (CI
job), a Kubernetes initContainer, or a Helm pre-upgrade hook that executes
prisma migrate deploy; pick one approach and apply consistently across all
services (replace the raw CMD in Dockerfile.x509 and analogous Dockerfiles or
add the CI/K8s/Helm migration step).

---

Minor comments:
In `@Dockerfiles/Dockerfile.connection`:
- Line 22: The Dockerfile currently copies the entire node_modules from the
build stage via the COPY --from=build /app/node_modules ./node_modules
instruction which pulls devDependencies and extras into the runtime image;
update the build pipeline so that only production dependencies are present
before that COPY (for example run a production prune or install step in the
build stage such as npm ci --only=production or npm prune --production) and then
keep the COPY --from=build /app/node_modules ./node_modules as-is to copy only
the pruned production deps; ensure the step runs in the same build stage
referenced as "build" so the runtime image size and attack surface are reduced.

In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Around line 15-18: The Dockerfile creates an unused group "nodejs" with
addgroup and a mismatched user "nextjs" with adduser; change them so the user
and group are consistent and semantically correct for this service: replace
addgroup -g 1001 -S nodejs and adduser -S nextjs -u 1001 with a single
consistent pair (e.g., addgroup -g 1001 -S oid4vc && adduser -S oid4vc -u 1001
-G oid4vc or ensure adduser specifies -G nodejs to join the nodejs group), and
then update any downstream references that assume the username/group to the new
name (look for usages of "nextjs", "nodejs", addgroup/adduser in this Dockerfile
and related service configs).
- Around line 20-22: The three COPY --from=build instructions that copy
/app/dist/apps/oid4vc-verification/, /app/libs/, and /app/node_modules are
executed as root before USER nextjs, so change each COPY to include
--chown=nextjs:nextjs (or the correct non-root user/group used by USER nextjs)
to ensure files are owned by the runtime user; update the COPY lines that
reference those paths (the COPY --from=build entries) to add the --chown flag so
runtime writes (e.g., Prisma extraction, logs) won’t fail due to root-only
ownership.

In `@Dockerfiles/Dockerfile.x509`:
- Around line 17-18: The Dockerfile creates a nodejs group and a nextjs user but
doesn't add nextjs to the nodejs group; update the user creation command so
nextjs is a member of nodejs (replace "adduser -S nextjs -u 1001" with a command
that includes the group, e.g. "adduser -S -G nodejs nextjs -u 1001" or
equivalent) so group-based file permission checks work as expected; look for the
commands that create the group and user (addgroup -g 1001 -S nodejs and adduser
-S nextjs -u 1001) and make them consistent.
- Line 4: Update the pinned pnpm version in the Dockerfile RUN instruction from
9.15.3 to 10.29.3 (the current v10 release) or explicitly document/confirm
intent to remain on v9; if upgrading, also update the repo's
package.json/corepack integrity entry to match v10.29.3 and run a test build to
ensure native/postinstall hooks still work given the v10 default of disabling
lifecycle scripts (verify pnpm.onlyBuiltDependencies or allowlisting for
required scripts); otherwise add a comment next to the RUN pnpm@... line
referencing the intentional pin to v9 and why it’s required.

---

Duplicate comments:
In `@Dockerfiles/Dockerfile.connection`:
- Line 8: The Dockerfile currently runs "RUN pnpm i --ignore-scripts" which
ignores the lockfile and can cause non-deterministic installs; update the RUN
invocation that installs dependencies (the line containing "RUN pnpm i
--ignore-scripts") to enforce the lockfile by adding the --frozen-lockfile flag
(e.g., use pnpm install with --frozen-lockfile and keep --ignore-scripts if
needed) so installs fail when pnpm-lock.yaml is out of sync.

In `@Dockerfiles/Dockerfile.issuance`:
- Line 8: Replace the Dockerfile RUN entry that currently reads "RUN pnpm i
--ignore-scripts" to enforce the lockfile by adding pnpm's frozen-lockfile
option so installs fail when the lockfile is out of sync; update the RUN pnpm i
--ignore-scripts line to include the frozen-lockfile flag (so the build is
deterministic and auditable).

In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Line 8: The pnpm install step (RUN pnpm i --ignore-scripts) can mutate
pnpm-lock.yaml during image build; update the Dockerfile's RUN invocation to
include the --frozen-lockfile flag (e.g., change RUN pnpm i --ignore-scripts to
include --frozen-lockfile) so the build fails if the lockfile would be altered
and ensures deterministic installs.

In `@Dockerfiles/Dockerfile.user`:
- Line 4: The global pnpm install invocation in the Dockerfile (the RUN npm
install -g pnpm@9.15.3 command) allows lifecycle scripts to run; update that RUN
command to include the --ignore-scripts flag so the global install is hardened
(e.g., change the RUN that references pnpm@9.15.3 to include --ignore-scripts),
and then scan other Dockerfiles for any other occurrences of RUN npm install -g
pnpm@... to apply the same --ignore-scripts protection consistently.

In `@Dockerfiles/Dockerfile.verification`:
- Line 8: The Dockerfile uses a non-deterministic install command (RUN pnpm i
--ignore-scripts); update this to run pnpm in frozen lockfile mode so builds
fail on lockfile drift by replacing that command with the equivalent
frozen-lockfile invocation (e.g., use the --frozen-lockfile flag alongside
--ignore-scripts) in the Dockerfile's RUN instruction.

In `@Dockerfiles/Dockerfile.x509`:
- Line 11: The Dockerfile build step should consistently use pnpm: update the
RUN instruction so it reads "RUN pnpm run build x509" (see the RUN pnpm run
build x509 line) and propagate this change to any other Dockerfiles or CI
scripts still calling npm; also remove any stray review-marker tokens like
"[duplicate_comment]" or "[approve_code_changes]" left in the commit/comments to
avoid clutter.

---

Nitpick comments:
In `@Dockerfiles/Dockerfile.agent-service`:
- Around line 21-27: The runtime image's RUN layer that installs openssl,
openssh-client, aws-cli, docker, and docker-compose should be reviewed and
trimmed: verify whether any runtime code calls these binaries (search for usage
of aws, docker, docker-compose, ssh in entrypoint, service code, or health
scripts) and if they are not required at runtime remove them from the RUN
install line (keep only openssl if TLS/crypto libs are needed), thereby deleting
the aws-cli, docker, docker-compose, and openssh-client packages from the final
image to reduce attack surface; if any are required, document their usage in the
Dockerfile comments and consider moving build-only tools into a separate build
stage.

In `@Dockerfiles/Dockerfile.geolocation`:
- Line 8: Update the Dockerfile.geolocation RUN command that currently invokes
"pnpm i --ignore-scripts" to add the --frozen-lockfile flag so installs fail if
pnpm-lock.yaml is out of sync; locate the RUN line with "pnpm i
--ignore-scripts" and modify it to include --frozen-lockfile to enforce
reproducible, deterministic builds.
- Around line 15-18: The Dockerfile creates a group with addgroup -g 1001 -S
nodejs but then creates a user with adduser -S nextjs -u 1001 which results in a
separate primary group named nextjs; update the user/group pairing so they match
by either creating the group with the same name as the user (change addgroup to
use nextjs) or explicitly add the nextjs user to the nodejs group (use
adduser/addgroup flags to set the primary/group membership), ensuring the
symbols addgroup, adduser, nodejs, and nextjs are adjusted consistently.
- Line 2: Update the Dockerfile base image tags: replace the FROM image tag
node:24-alpine3.21 with node:24-alpine3.23 in both occurrences (the build stage
and the final stage FROM lines) so both stages use node:24-alpine3.23 to align
with current Node 24 Alpine tracking and extended patch support.

In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Line 2: Update the Docker base image from the older Alpine variant to a
current one by replacing all occurrences of "FROM node:24-alpine3.21" (e.g., the
"FROM node:24-alpine3.21 AS build" line and any other FROM lines using that tag)
with a newer tag such as "node:24-alpine3.22" or "node:24-alpine3.23" in the
Dockerfile so both build and runtime stages use the updated Alpine variant.
- Line 4: Update the pinned pnpm version in the Dockerfile by replacing the
existing global install command that references pnpm@9.15.3 (the RUN npm install
-g pnpm@9.15.3 line) to use pnpm@10.30.2; after changing the version, rebuild
the image and run your standard dependency/install workflows to verify there are
no breaking changes from v10, and consult v10 release notes if any test failures
occur.

In `@Dockerfiles/Dockerfile.seed`:
- Line 8: Replace the global npm install of pnpm (the RUN npm install -g
pnpm@9.15.3 line) with Node's Corepack workflow: enable Corepack and
prepare/activate the desired pnpm version (e.g., run corepack enable && corepack
prepare pnpm@9.15.3 --activate) so the Dockerfile uses the built-in package
manager management instead of installing pnpm globally.
- Line 1: Update the Docker base image pin used in the seed Dockerfile: replace
the current FROM node:24-alpine3.21 reference with FROM node:24-alpine3.23 so
the container uses the newer Alpine OS variant; ensure the single FROM line in
Dockerfiles/Dockerfile.seed (the literal "FROM node:24-alpine3.21") is changed
to "FROM node:24-alpine3.23" to keep reproducibility while picking up newer OS
security patches.

In `@Dockerfiles/Dockerfile.utility`:
- Around line 15-18: The created group nodejs is not being used when creating
the nextjs user; update the adduser invocation so nextjs is explicitly added to
the nodejs group (e.g., use the adduser flag to set primary group to nodejs) to
avoid UID/GID ambiguity — change the adduser command that currently references
nextjs and UID 1001 to include the nodejs group reference so nextjs is bound to
nodejs.

In `@Dockerfiles/Dockerfile.webhook`:
- Line 8: Update the Dockerfile command that installs JS dependencies to use
pnpm's frozen lockfile mode: modify the RUN pnpm i --ignore-scripts invocation
(in Dockerfile.webhook) to include the --frozen-lockfile flag so the build will
fail if pnpm-lock.yaml and package.json disagree, ensuring reproducible installs
in CI.
- Line 4: Replace the global npm install command with Corepack activation and
preparation to pin pnpm: instead of running "npm install -g pnpm@9.15.3" use
Corepack flow by running "corepack enable" and then "corepack prepare
pnpm@9.15.3 --activate" so the Dockerfile uses Corepack to manage the pnpm
version; ensure Node runtime in the image supports Corepack (Node 24+) or enable
Corepack beforehand and verify the RUN step references the same pnpm version
(9.15.3) used elsewhere.

In `@Dockerfiles/Dockerfile.x509`:
- Around line 20-22: The three COPY instructions (COPY --from=build
/app/dist/apps/x509/ ./dist/apps/x509/, COPY --from=build /app/libs/ ./libs/,
COPY --from=build /app/node_modules ./node_modules) should include ownership
flag --chown=nextjs:nodejs so files aren't root-owned when the Dockerfile later
switches to the USER; update those COPY lines to add --chown=nextjs:nodejs
(before the USER switch) to ensure nextjs can write caches/temp files at
runtime.
- Line 8: Replace the plain pnpm install invocation in the Dockerfile RUN step
with one that enforces the lockfile to avoid drift: change the RUN command that
currently calls "pnpm i" (the RUN pnpm i --ignore-scripts step) to include the
--frozen-lockfile flag (you can keep --ignore-scripts if needed), so the build
fails when pnpm-lock.yaml is out of sync rather than silently updating it.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 857ad18 and aaed3a4.

📒 Files selected for processing (19)
  • Dockerfiles/Dockerfile.agent-provisioning
  • Dockerfiles/Dockerfile.agent-service
  • Dockerfiles/Dockerfile.api-gateway
  • Dockerfiles/Dockerfile.cloud-wallet
  • Dockerfiles/Dockerfile.connection
  • Dockerfiles/Dockerfile.ecosystem
  • Dockerfiles/Dockerfile.geolocation
  • Dockerfiles/Dockerfile.issuance
  • Dockerfiles/Dockerfile.ledger
  • Dockerfiles/Dockerfile.notification
  • Dockerfiles/Dockerfile.oid4vc-issuance
  • Dockerfiles/Dockerfile.oid4vc-verification
  • Dockerfiles/Dockerfile.organization
  • Dockerfiles/Dockerfile.seed
  • Dockerfiles/Dockerfile.user
  • Dockerfiles/Dockerfile.utility
  • Dockerfiles/Dockerfile.verification
  • Dockerfiles/Dockerfile.webhook
  • Dockerfiles/Dockerfile.x509
🚧 Files skipped from review as they are similar to previous changes (1)
  • Dockerfiles/Dockerfile.notification

Comment thread Dockerfiles/Dockerfile.agent-provisioning
Comment thread Dockerfiles/Dockerfile.agent-service Outdated
Comment thread Dockerfiles/Dockerfile.api-gateway Outdated
Comment thread Dockerfiles/Dockerfile.cloud-wallet Outdated
Comment thread Dockerfiles/Dockerfile.ecosystem Outdated
CMD ["sh", "-c", "cd libs/prisma-service && npx prisma migrate deploy && npx prisma generate && cd ../.. && node dist/apps/utility/main.js"]
COPY --from=build /app/node_modules ./node_modules
USER nextjs
CMD ["node", "dist/apps/utility/main.js"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for migration commands across the repo
rg -n -C2 -g '!**/node_modules/**' -e 'prisma migrate deploy' -e 'npx prisma migrate' -e 'pnpm.*migrate' -e 'db:migrate'

Repository: credebl/platform

Length of output: 544


🏁 Script executed:

# Also search for Docker-related deployment files and scripts
fd -e 'yml' -e 'yaml' -e 'sh' -e 'ts' -e 'js' | grep -E '(docker-compose|deploy|pipeline|manifest|scripts)' | head -20

Repository: credebl/platform

Length of output: 549


🏁 Script executed:

# Look for the Dockerfile.utility and understand the project structure
git ls-files | grep -i dockerfile

Repository: credebl/platform

Length of output: 709


🏁 Script executed:

# Read the Dockerfile.utility to see the full context
cat -n Dockerfiles/Dockerfile.utility

Repository: credebl/platform

Length of output: 1068


🏁 Script executed:

# Check the docker-compose file for utility service configuration
cat -n docker-compose.yml

Repository: credebl/platform

Length of output: 5817


🏁 Script executed:

# Look for any utility-specific deployment or initialization scripts
fd -e 'sh' -e 'yml' -e 'yaml' | xargs rg -l 'utility' | head -20

Repository: credebl/platform

Length of output: 101


🏁 Script executed:

# Search for Kubernetes manifests or deployment configs
fd -e 'yml' -e 'yaml' | xargs grep -l 'utility\|migrate' 2>/dev/null | head -20

Repository: credebl/platform

Length of output: 116


🏁 Script executed:

# Search for CI/CD workflows (GitHub, GitLab, etc.)
fd -type f \( -name '*.yml' -o -name '*.yaml' -o -name 'Makefile' \) | xargs grep -l 'prisma migrate\|db.*migrate' 2>/dev/null | head -20

Repository: credebl/platform

Length of output: 230


🏁 Script executed:

# Check for any deployment or initialization documentation
fd -type f \( -name 'README*' -o -name 'DEPLOY*' -o -name '*deploy*' \) | head -10

Repository: credebl/platform

Length of output: 230


🏁 Script executed:

# Check the docker-compose-dev.yml for utility service
cat -n docker-compose-dev.yml | grep -A 10 -B 2 'utility'

Repository: credebl/platform

Length of output: 873


🏁 Script executed:

# Search for GitHub workflows or other CI/CD configs
find . -name '*.yml' -o -name '*.yaml' | grep -E '(\.github|\.gitlab|workflow|ci|pipeline)' | head -20

Repository: credebl/platform

Length of output: 278


🏁 Script executed:

# Look for any initialization or migration scripts in the repo
fd -e 'sh' -e 'js' -e 'ts' | xargs grep -l 'prisma migrate\|db.*migrate\|migration' 2>/dev/null | head -15

Repository: credebl/platform

Length of output: 42


🏁 Script executed:

# Check the continuous delivery workflow for migration steps
cat -n .github/workflows/continuous-delivery.yml

Repository: credebl/platform

Length of output: 2339


Migrations are not being executed in the current deployment setup.

The Dockerfile.utility CMD bypasses the start script which contains prisma migrate deploy. Neither docker-compose.yml nor the CI/CD pipeline (continuous-delivery.yml) execute migrations before starting the service. Add migration execution either via:

  • An init container that runs migrations before the app container starts
  • A pre-deployment step in your CD pipeline
  • Override the CMD in docker-compose to use the start script (which includes migrations)

Without this, the utility service will start with an uninitialized or out-of-sync database schema.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.utility` at line 24, The Dockerfile currently sets CMD
["node", "dist/apps/utility/main.js"] which bypasses the npm start script that
runs prisma migrate deploy, so migrations are never executed; fix by ensuring
migrations run before the app process starts — either change the container
startup to invoke the start script (use the package.json "start" script instead
of directly running node), add an init container that runs npm run start:migrate
or prisma migrate deploy prior to launching the utility container, or add a
pre-deployment step in continuous-delivery.yml to run prisma migrate deploy;
update docker-compose.yml or CI config accordingly to call the start script or
explicit migration command so the database schema is applied before the service
runs.

Comment thread Dockerfiles/Dockerfile.webhook
Comment thread Dockerfiles/Dockerfile.webhook
Comment thread Dockerfiles/Dockerfile.x509
CMD ["sh", "-c", "cd libs/prisma-service && npx prisma migrate deploy && npx prisma generate && cd ../.. && node dist/apps/x509/main.js"] No newline at end of file
COPY --from=build /app/node_modules ./node_modules
USER nextjs
CMD ["node", "dist/apps/x509/main.js"] No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Search for prisma migrate deploy invocations across the repo
rg -rn "prisma migrate deploy" --glob "!node_modules"

Repository: credebl/platform

Length of output: 159


🏁 Script executed:

# Search for other migration-related patterns and mechanisms
rg -rn "prisma migrate" --glob "!node_modules" | head -50

Repository: credebl/platform

Length of output: 166


🏁 Script executed:

# Look for Kubernetes manifests that might contain init containers
fd -e yaml -e yml | grep -E "(k8s|kubernetes|helm|deployment)" | head -20

Repository: credebl/platform

Length of output: 42


🏁 Script executed:

# Search for CI/CD configuration files
fd -e yaml -e yml -e json -e sh | grep -E "^\.github|\.gitlab-ci|\.circleci|Makefile|package.json" | head -20

Repository: credebl/platform

Length of output: 150


🏁 Script executed:

# Search for .github workflows directory
find . -path "./.github/workflows" -type d 2>/dev/null

Repository: credebl/platform

Length of output: 79


🏁 Script executed:

# Search for docker-compose files
fd "docker-compose" --type f

Repository: credebl/platform

Length of output: 150


🏁 Script executed:

# Look at all Dockerfiles to see the full context
fd "Dockerfile" --type f | head -20

Repository: credebl/platform

Length of output: 709


🏁 Script executed:

# Get more context around the package.json "start" script
cat -n package.json | grep -A 2 -B 2 "start"

Repository: credebl/platform

Length of output: 654


🏁 Script executed:

# Search for any CI/CD related files (.gitlab-ci.yml, .circleci, jenkins, etc.)
fd -e yml -e yaml | grep -iE "(github|gitlab|circleci|jenkins|ci)"

Repository: credebl/platform

Length of output: 42


🏁 Script executed:

# Search for migration-related scripts or entrypoints
rg -rn "migrate" --glob "!node_modules" | head -30

Repository: credebl/platform

Length of output: 1171


🏁 Script executed:

# List workflow files
ls -la .github/workflows/

Repository: credebl/platform

Length of output: 306


🏁 Script executed:

# Check docker-compose.yml for migration steps
cat docker-compose.yml | head -100

Repository: credebl/platform

Length of output: 2399


🏁 Script executed:

# Check how many other Dockerfiles have the same bypass pattern (direct node call instead of npm start)
for f in $(fd "Dockerfile" --type f); do
  echo "=== $f ==="; 
  grep -E "^CMD|^ENTRYPOINT" "$f";
done

Repository: credebl/platform

Length of output: 1747


🏁 Script executed:

# Check if there are any init containers or pre-deployment scripts in the repo
rg -rn "initContainers|preUpgrade|pre-upgrade" --glob "!node_modules"

Repository: credebl/platform

Length of output: 42


🏁 Script executed:

cat .github/workflows/continuous-delivery.yml

Repository: credebl/platform

Length of output: 1828


Add Prisma migration step to deployment pipeline.

prisma migrate deploy was removed from container startup, and no alternative migration mechanism exists in the deployment pipeline. The npm start script includes migrations ("start": "npx prisma migrate deploy --schema=./libs/prisma-service/prisma/schema.prisma & nest start"), but all Dockerfiles bypass this with direct node calls. Neither the CI workflow, docker-compose setup, nor Kubernetes manifests handle schema migrations, so new database schema changes will be silently skipped on deployment. This affects all 18+ services.

Add migrations via one of: init container, pre-upgrade Helm hook, or dedicated CI step that runs before deployment.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` at line 24, The container currently bypasses
migrations by using the raw CMD ["node", "dist/apps/x509/main.js"] while the
package.json "start" script runs npx prisma migrate deploy; fix by ensuring
prisma migrations run before app start: either (A) change the image entry to run
the existing "start" script (use npm start) or add an entrypoint that runs npx
prisma migrate deploy --schema=./libs/prisma-service/prisma/schema.prisma before
launching node, or (B) move migrations out of the container and add a dedicated
deployment step (CI job), a Kubernetes initContainer, or a Helm pre-upgrade hook
that executes prisma migrate deploy; pick one approach and apply consistently
across all services (replace the raw CMD in Dockerfile.x509 and analogous
Dockerfiles or add the CI/K8s/Helm migration step).

Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Comment thread package.json Fixed
Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

♻️ Duplicate comments (15)
Dockerfiles/Dockerfile.ecosystem (1)

11-11: devDependencies still shipped in production.

Same as previously flagged — add RUN pnpm prune --prod after the build.

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.ecosystem` at line 11, The Dockerfile currently runs
the build step with "RUN pnpm run build ecosystem" but still leaves
devDependencies in the image; after the build instruction add a "RUN pnpm prune
--prod" step to remove devDependencies (i.e., place the pnpm prune --prod
command immediately following the RUN pnpm run build ecosystem instruction so
only production deps remain).
Dockerfiles/Dockerfile.utility (2)

11-11: Production image still includes devDependencies.

Same issue as flagged previously — add RUN pnpm prune --prod after the build step to strip devDependencies before copying node_modules to the final image.

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.utility` at line 11, The production Dockerfile
currently runs the build step (RUN pnpm run build utility) but still copies full
node_modules including devDependencies into the final image; after the build
step add a pruning step (RUN pnpm prune --prod) to remove devDependencies before
copying node_modules into the final image (or ensure the multi-stage copy pulls
node_modules from the stage where pnpm prune --prod ran), updating the stage
that runs RUN pnpm run build utility to include the pnpm prune --prod command so
the final image contains only production deps.

24-24: Prisma migrations not executed before application startup.

As flagged in a previous review, the CMD bypasses the start script which previously ran prisma migrate deploy. Ensure migrations are handled by your deployment orchestration (init container, CI job, etc.) before replicas start.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.utility` at line 24, The Dockerfile currently uses the
direct CMD ["node", "dist/apps/utility/main.js"], which bypasses the start
script that runs prisma migrate deploy; change the container startup strategy so
migrations run before the app: either restore the image to invoke the
package.json start script (so start runs prisma migrate deploy) or ensure your
deployment orchestration (init container, CI job, or startup hook) executes
prisma migrate deploy prior to replicas starting; update references to CMD and
the start script/prisma migrate deploy flow accordingly.
Dockerfiles/Dockerfile.oid4vc-verification (1)

11-11: devDependencies still shipped in production.

Same as previously flagged across other Dockerfiles — add RUN pnpm prune --prod after pnpm run build.

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` at line 11, The image still
contains devDependencies because you run the build but don't prune them; after
the RUN pnpm run build oid4vc-verification step add a RUN pnpm prune --prod to
remove devDependencies so only production deps remain (update the Dockerfile
step following the existing RUN pnpm run build oid4vc-verification command).
Dockerfiles/Dockerfile.organization (1)

11-11: devDependencies still shipped in production — pnpm prune --prod missing.

Same as flagged previously. Add RUN pnpm prune --prod after the build step.

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.organization` at line 11, The Dockerfile currently
runs the build with the command "RUN pnpm run build organization" but does not
remove devDependencies, causing devDependencies to be shipped to production; add
a step immediately after that command to run "RUN pnpm prune --prod" (i.e.,
insert a RUN pnpm prune --prod line right after the RUN pnpm run build
organization statement) so the production image only keeps production
dependencies.
Dockerfiles/Dockerfile.oid4vc-issuance (1)

11-11: Production image ships devDependencies — add pnpm prune --prod after the build step.

No pruning step exists between pnpm run build and the final-stage COPY --from=build /app/node_modules. All devDependencies (TypeScript, test utilities, build tools) end up in the production image, increasing attack surface and image size.

Proposed fix
 RUN pnpm run build oid4vc-issuance
+RUN pnpm prune --prod

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-issuance` at line 11, The production image is
including devDependencies because there is no pruning step after the build;
after the existing RUN pnpm run build oid4vc-issuance in the build stage, add a
step to run pnpm prune --prod (or equivalent pnpm install --prod/prune command)
so that node_modules only contains production deps before the final-stage COPY
--from=build /app/node_modules; apply the same change to the other identical
build step referenced in the review to ensure devDependencies are not copied
into the final image.
Dockerfiles/Dockerfile.seed (1)

18-18: prisma migrate deploy still missing before prisma db seed.

As flagged in a previous review, the CMD only runs prisma db seed without applying migrations first. If the database schema isn't already up-to-date (fresh environment, rollback, standalone execution), the seed will fail. Either restore prisma migrate deploy before the seed command or ensure migrations are guaranteed to run upstream.

Proposed fix if migrations should be self-contained
-CMD ["sh", "-c", "cd libs/prisma-service && npx prisma db seed"]
+CMD ["sh", "-c", "cd libs/prisma-service && npx prisma migrate deploy && npx prisma db seed"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.seed` at line 18, The Docker CMD currently only runs
"npx prisma db seed" in libs/prisma-service which can fail if migrations haven't
been applied; update the startup command for the container to run "npx prisma
migrate deploy" before "npx prisma db seed" (e.g., combine or sequence the
commands in the CMD that changes in Dockerfiles/Dockerfile.seed) so migrations
are applied first, or alternatively ensure upstream orchestration runs "prisma
migrate deploy" prior to invoking the existing CMD; target the CMD that
currently executes in libs/prisma-service and add the "prisma migrate deploy"
step before the seed.
Dockerfiles/Dockerfile.user (2)

11-11: devDependencies still shipped in production.

Same as previously flagged.

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.user` at line 11, The Dockerfile currently runs "RUN
pnpm run build user" but ends up shipping devDependencies into the production
image; change to a multi-stage build: create a builder stage that installs all
deps (pnpm install) and runs "pnpm run build user" (e.g., stage name "builder"),
then create a slim final stage that copies only the build artifacts and
package.json/pnpm-lock.yaml and runs "pnpm install --prod" (or "pnpm install
--frozen-lockfile --prod") to install only production deps; ensure the final
image does not run a full install of devDependencies or copy node_modules from
the builder stage.

24-24: Prisma migrations not executed before application startup.

As flagged in a previous review, ensure migrations are handled externally.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.user` at line 24, The Dockerfile must not trigger
Prisma migrations at container start—ensure all migrations are applied
externally by the deployment pipeline; confirm that CMD ["node",
"dist/apps/user/main.js"] only starts the app and remove any automatic migration
invocations (e.g., calls to prisma migrate or use of an entrypoint script that
runs migrations) from the Docker image or startup code (inspect
dist/apps/user/main.js and any entrypoint scripts) so the container solely runs
the application and migration orchestration happens outside the container.
Dockerfiles/Dockerfile.issuance (1)

11-11: devDependencies still shipped in production.

Same as previously flagged.

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.issuance` at line 11, The Dockerfile is installing
devDependencies into the production image because the RUN pnpm run build
issuance step runs with dev deps present; change the Dockerfile to build in a
separate builder stage and only copy the built artifacts and production
dependencies into the final image (or, at minimum, run pnpm install --prod /
pnpm install --prod --frozen-lockfile in the final stage before copying
artifacts) so devDependencies are not shipped; target the RUN pnpm run build
issuance step (and the npm/pnpm install steps surrounding it) to implement a
multi-stage build that installs devDependencies only in the builder stage and
installs only production deps in the runtime stage.
Dockerfiles/Dockerfile.x509 (2)

24-24: ⚠️ Potential issue | 🟠 Major

Confirm migrations run in deployment before app startup.

Line 24 bypasses the npm start script migration path. If no pre-deploy migration job exists, schema updates can be skipped.

#!/bin/bash
set -euo pipefail
echo "Docker CMD patterns:"
rg -n 'CMD \["node", "dist/apps/.+/main\.js"\]' Dockerfiles

echo
echo "Where prisma migrate deploy is invoked:"
rg -n "prisma migrate deploy" -g '!**/node_modules/**'

echo
echo "Potential deployment hooks for migrations:"
rg -n "initContainer|pre-upgrade|migration job|db-migration" -g '!**/node_modules/**'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` at line 24, The Dockerfile's direct CMD ["node",
"dist/apps/x509/main.js"] bypasses the npm start script (and any migration
steps), so ensure migrations run before app startup by invoking the project's
migration path; either replace the direct node CMD with the npm start entrypoint
that runs migrations, or add a startup wrapper that runs "prisma migrate deploy"
(or the project's migration command) before launching dist/apps/x509/main.js;
update the Dockerfile's CMD or ENTRYPOINT accordingly and reference the existing
CMD ["node", "dist/apps/x509/main.js"] when making the change so deployments
always run migrations prior to starting the app.

22-22: ⚠️ Potential issue | 🟠 Major

Prune devDependencies before copying node_modules to runtime.

Line 22 copies the full build-stage node_modules; without pruning, devDependencies are shipped in production.

🔧 Proposed fix
 RUN cd libs/prisma-service && npx prisma generate
 RUN pnpm run build x509
+RUN pnpm prune --prod
#!/bin/bash
set -euo pipefail
f="Dockerfiles/Dockerfile.x509"
echo "Inspecting ${f}"
rg -n "pnpm i|pnpm install|pnpm prune --prod|node_modules" "$f"
if rg -q "pnpm prune --prod" "$f"; then
  echo "✅ prune step present"
else
  echo "❌ Missing pnpm prune --prod before copying node_modules"
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` at line 22, The Dockerfile currently copies the
entire build-stage node_modules (COPY --from=build /app/node_modules
./node_modules) which includes devDependencies; modify the build stage in
Dockerfiles/Dockerfile.x509 to prune devDependencies before that COPY by running
a production-only prune/install (e.g., run pnpm prune --prod or reinstall
production deps) so that node_modules only contains production packages, then
keep the existing COPY --from=build /app/node_modules ./node_modules to pull the
slimmed modules into the runtime image.
Dockerfiles/Dockerfile.agent-service (1)

33-33: ⚠️ Potential issue | 🟠 Major

Prune devDependencies before runtime copy.

Line 33 pulls full node_modules from build stage; this typically includes devDependencies.

🔧 Proposed fix
 RUN cd libs/prisma-service && npx prisma generate
 RUN pnpm run build agent-service
+RUN pnpm prune --prod
#!/bin/bash
set -euo pipefail
f="Dockerfiles/Dockerfile.agent-service"
rg -n "pnpm i|pnpm install|pnpm prune --prod|node_modules" "$f"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.agent-service` at line 33, The Dockerfile copies the
entire node_modules from the build stage (COPY --from=build /app/node_modules
./node_modules), which may include devDependencies; change the build/runtime
flow to produce a production-only node_modules before copying — for example, run
a production install or prune step in the build stage (e.g., use pnpm install
--prod or pnpm prune --prod after installing dev deps) or perform a
production-only install in the final stage so that the node_modules copied by
COPY --from=build are pruned of devDependencies; update the Dockerfile around
the install/prune steps and the COPY --from=build reference (the COPY line and
the install/prune commands are the unique symbols to modify).
Dockerfiles/Dockerfile.webhook (1)

22-22: ⚠️ Potential issue | 🟠 Major

Prune build dependencies before final node_modules copy.

Line 22 copies build-stage node_modules directly, which likely carries devDependencies into production.

🔧 Proposed fix
 RUN cd libs/prisma-service && npx prisma generate
 RUN pnpm run build webhook
+RUN pnpm prune --prod
#!/bin/bash
set -euo pipefail
f="Dockerfiles/Dockerfile.webhook"
rg -n "pnpm i|pnpm install|pnpm prune --prod|node_modules" "$f"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.webhook` at line 22, The Dockerfile currently copies
the build-stage node_modules wholesale via the COPY --from=build
/app/node_modules ./node_modules instruction, which carries devDependencies into
the final image; to fix, prune or produce a production-only node_modules before
copying by either running pnpm prune --prod (or npm ci --only=production) in the
build stage after the build completes, or add a dedicated production install
stage that runs pnpm install --prod --frozen-lockfile and then COPY from that
stage (i.e., replace COPY --from=build /app/node_modules ./node_modules with a
copy from the pruned/prod-install stage or ensure the build stage runs pnpm
prune --prod and then copy the pruned node_modules).
Dockerfiles/Dockerfile.geolocation (1)

22-22: Final image still copies full devDependencies.

The existing review comment on this line has not been addressed — node_modules from the build stage still includes devDependencies.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.geolocation` at line 22, The Dockerfile currently
copies the entire node_modules from the build stage ("COPY --from=build
/app/node_modules ./node_modules"), which includes devDependencies; update the
build/final steps so only production deps are copied: either install only
production packages in the build stage (use npm ci --only=production or
NODE_ENV=production npm ci) or run npm prune --production in the build stage
before the COPY, or alternatively stop copying node_modules and instead COPY
package*.json then run npm ci --only=production in the final stage; apply the
change around the "COPY --from=build /app/node_modules ./node_modules" line.
🧹 Nitpick comments (4)
Dockerfiles/Dockerfile.geolocation (1)

2-2: node:24-alpine3.21 is superseded — consider bumping to alpine3.22.

Same concern as the other Dockerfiles in this PR: the current Node 24 Alpine pairings on Docker Hub are 24-alpine3.22 and 24-alpine3.23, both of which receive ongoing OS-level patches that alpine3.21 no longer receives.

♻️ Proposed fix
-FROM node:24-alpine3.21 AS build
+FROM node:24-alpine3.22 AS build
 ...
-FROM node:24-alpine3.21
+FROM node:24-alpine3.22

Also applies to: 14-14

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.geolocation` at line 2, Update the Docker base image
reference FROM node:24-alpine3.21 to a supported Alpine patch (e.g.
node:24-alpine3.22 or node:24-alpine3.23) in the Dockerfile where the FROM
node:24-alpine3.21 line appears so the image receives current OS-level security
patches; change the image tag consistently for other Dockerfiles that use the
same FROM node:24-alpine3.21 reference.
Dockerfiles/Dockerfile.api-gateway (1)

2-2: node:24-alpine3.21 is superseded — consider bumping to alpine3.22.

Same concern as the other Dockerfiles in this PR: Alpine 3.21 is no longer the current patch base for Node 24. Docker Hub now lists 24-alpine3.22 and 24-alpine3.23 as the current Node 24 Alpine variants.

♻️ Proposed fix
-FROM node:24-alpine3.21 AS build
+FROM node:24-alpine3.22 AS build
 ...
-FROM node:24-alpine3.21
+FROM node:24-alpine3.22

Also applies to: 14-14

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.api-gateway` at line 2, Replace the superseded base
image tag "node:24-alpine3.21" used in the Dockerfile (the FROM
node:24-alpine3.21 AS build line) with the current Alpine patch variant, e.g.
"node:24-alpine3.22" (or 24-alpine3.23), and apply the same change to other
Dockerfiles that use the same tag (the occurrences noted as 14-14) so all Node
24 Alpine base images are updated consistently.
Dockerfiles/Dockerfile.agent-provisioning (1)

2-2: node:24-alpine3.21 is superseded — consider updating to a newer Alpine variant.

The current latest Node 24 Alpine pairings on Docker Hub are 24-alpine3.22 and 24-alpine3.23. Alpine 3.21 no longer receives upstream patch updates, meaning OS-level CVE fixes are only published against newer Alpine releases. Since the intent of this PR is to remediate vulnerabilities, pinning to a stale Alpine base undermines that goal.

♻️ Proposed fix — upgrade Alpine base
-FROM  node:24-alpine3.21 AS build
+FROM  node:24-alpine3.22 AS build
 ...
-FROM  node:24-alpine3.21
+FROM  node:24-alpine3.22

Also applies to: 21-21

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.agent-provisioning` at line 2, Replace the pinned base
image string "FROM node:24-alpine3.21" with a current Alpine variant such as
"FROM node:24-alpine3.23" (or at minimum "node:24-alpine3.22") to ensure
upstream CVE/patch fixes are included; update the same FROM string in any other
Dockerfiles referencing "node:24-alpine3.21" (e.g., the other Dockerfile noted
as 21-21) and rebuild images to verify no downstream breakages from the base
image bump.
Dockerfiles/Dockerfile.notification (1)

2-2: node:24-alpine3.21 is superseded — consider bumping to alpine3.22.

Docker Hub now lists 24-alpine3.22 and 24-alpine3.23 as the current Node 24 Alpine variants. Pinning to alpine3.21 limits the OS-level CVE coverage that this PR aims to improve.

♻️ Proposed fix
-FROM node:24-alpine3.21 AS build
+FROM node:24-alpine3.22 AS build
 ...
-FROM node:24-alpine3.21
+FROM node:24-alpine3.22

Also applies to: 14-14

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.notification` at line 2, Update the pinned base image
string "node:24-alpine3.21" to a current Alpine variant (e.g.,
"node:24-alpine3.22" or "node:24-alpine3.23") wherever it appears (the
Dockerfile FROM line using that tag), and do the same for the analogous legacy
image tag (e.g., "node:14-alpine3.21") referenced in the other Dockerfile;
ensure both FROM lines are changed so the build uses the newer alpine3.22/3.23
variant to improve OS-level CVE coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfiles/Dockerfile.agent-provisioning`:
- Line 38: The final image currently copies the entire build-stage node_modules
via the COPY --from=build /app/node_modules ./node_modules line, which brings
devDependencies into the runtime image; replace that approach by installing only
production deps in the final stage: copy package.json (and
package-lock.json/yarn.lock) into the final stage and run a production install
(e.g., npm ci --only=production or npm ci && npm prune --production) or use
NODE_ENV=production during install so devDependencies are excluded; update the
Dockerfile to remove the COPY --from=build /app/node_modules ./node_modules and
perform the production-only install in the final stage (referencing the
Dockerfile final stage where node_modules is populated).
- Around line 22-29: The Dockerfile currently installs heavy runtime packages
(aws-cli, docker, docker-compose) that are used by shell scripts
(start_agent_ecs.sh, start_agent.sh) and by the walletProvision method in
agent-provisioning.service.ts via exec(); confirm whether these commands truly
must run inside the container at runtime and if not remove them from the final
image or replace with lighter alternatives (use AWS SDK calls from
walletProvision instead of aws-cli, call remote Docker daemon or include only
the docker client binary, or move tooling to a sidecar/host or a build-stage so
final image size/CVE surface is reduced); update the Dockerfile and the
referenced scripts/service accordingly and document the chosen operational model
if you keep the packages.

In `@Dockerfiles/Dockerfile.api-gateway`:
- Line 22: The final image currently copies the entire workspace node_modules
via "COPY --from=build /app/node_modules ./node_modules", pulling
devDependencies into production; instead, in the final stage remove that COPY
and perform a production-only install/prune there (e.g., run a production
npm/yarn install or npm prune --production) so only production deps are
present—update the Dockerfile final stage around the COPY --from=build
/app/node_modules ./node_modules to replace the copy with a production
install/prune step.

In `@Dockerfiles/Dockerfile.cloud-wallet`:
- Line 22: The Dockerfile copies the entire build-stage node_modules (COPY
--from=build /app/node_modules ./node_modules), which includes devDependencies
because the build stage ran pnpm i --frozen-lockfile --ignore-scripts without
pruning; fix by pruning devDependencies before copying or installing only
production deps in the final image—either run pnpm prune --prod (or pnpm prune
--prod --offline as appropriate) in the build stage and then copy the pruned
/app/node_modules, or replace the copy with a production install in the final
stage (e.g., run pnpm install --prod --frozen-lockfile in the final stage) so
that node_modules in the final image contains only production dependencies.

In `@Dockerfiles/Dockerfile.connection`:
- Line 22: The final image currently copies the entire node_modules from the
build stage (COPY --from=build /app/node_modules ./node_modules), which includes
devDependencies; fix it by running pnpm prune --prod in the build stage before
copying so dev-only packages are removed (add a RUN pnpm prune --prod step in
the build stage after install/build and before the COPY --from=build reference)
ensuring the final image only contains production dependencies.

In `@Dockerfiles/Dockerfile.ecosystem`:
- Around line 14-18: The Dockerfile creates the nodejs group (addgroup -g 1001
-S nodejs) but fails to assign the nextjs user to that group; update the user
creation command (adduser) to include the group flag so nextjs is added to
nodejs (use the -G nodejs option on the adduser command) so the new user is
properly associated with the created group.

In `@Dockerfiles/Dockerfile.issuance`:
- Around line 14-18: The Dockerfile's user creation omits adding the new user to
the nodejs group; update the adduser invocation (the adduser command in this
Dockerfile) to include the -G nodejs flag so the created nextjs user is added to
the nodejs group (keep existing -S and -u 1001 flags intact).

In `@Dockerfiles/Dockerfile.ledger`:
- Line 22: The final image currently copies all node_modules from the build
stage via COPY --from=build /app/node_modules ./node_modules which includes
devDependencies; remove devDeps before that copy by pruning production-only
packages in the build stage (e.g., run npm prune --production or npm ci
--only=production in a dedicated step/stage after the build) or install
production deps in a separate stage and COPY from that stage, ensuring only
production dependencies end up in the final image.

In `@Dockerfiles/Dockerfile.notification`:
- Line 22: The final Docker image currently copies the entire workspace
node_modules from the build stage via the COPY --from=build /app/node_modules
./node_modules line, which brings devDependencies into the image; change the
final stage to perform a production-only install instead — e.g., copy
package.json/package-lock.json (or yarn.lock) into the final stage and run npm
ci --only=production (or npm prune --production) there, or run a production
install in the build stage and copy only the production node_modules to replace
the current COPY --from=build /app/node_modules ./node_modules usage so
devDependencies are excluded.

In `@Dockerfiles/Dockerfile.oid4vc-issuance`:
- Around line 14-18: The adduser invocation for the nextjs user is not adding it
to the nodejs group; update the Dockerfile by modifying the adduser command (the
adduser call that creates "nextjs") to include the group flag "-G nodejs" so the
nextjs user is a member of the nodejs group created by the addgroup call
(symbols to change: addgroup -g 1001 -S nodejs and adduser -S nextjs -u 1001 →
ensure adduser includes -G nodejs).

In `@Dockerfiles/Dockerfile.organization`:
- Around line 14-18: The Dockerfile creates the nodejs group with addgroup -g
1001 -S nodejs but then adds the nextjs user without assigning it to that group;
update the adduser invocation (the one creating nextjs) to include the group
flag so nextjs is added to nodejs (use adduser -S nextjs -u 1001 -G nodejs) to
match other Dockerfiles and ensure correct group membership.

In `@Dockerfiles/Dockerfile.seed`:
- Around line 1-8: The adduser invocation currently creates the nextjs user
without assigning it to the previously-created nodejs group, so chown -R
nextjs:nodejs won't give the user group membership; update the adduser command
(the line that calls adduser -S nextjs -u 1001) to include the nodejs group
(e.g., adduser -S nextjs -u 1001 -G nodejs) so the nextjs user is created as a
member of group nodejs and the subsequent chown -R nextjs:nodejs will grant the
intended access.

In `@Dockerfiles/Dockerfile.user`:
- Around line 14-18: The adduser invocation in the Dockerfile is missing the
group flag, causing the new user not to be placed into the nodejs group; update
the adduser command (the line that currently calls adduser -S nextjs -u 1001) to
include -G nodejs so the created user is assigned to the addgroup-created nodejs
group (refer to the addgroup and adduser commands in the diff).

In `@Dockerfiles/Dockerfile.verification`:
- Line 22: The final image currently copies the full build-stage node_modules
(COPY --from=build /app/node_modules ./node_modules), which includes
devDependencies; before that COPY run pnpm prune --prod in the build stage (or
create a dedicated pruned step) so devDependencies are removed and only
production deps remain, then copy the pruned /app/node_modules into the final
image.

---

Duplicate comments:
In `@Dockerfiles/Dockerfile.agent-service`:
- Line 33: The Dockerfile copies the entire node_modules from the build stage
(COPY --from=build /app/node_modules ./node_modules), which may include
devDependencies; change the build/runtime flow to produce a production-only
node_modules before copying — for example, run a production install or prune
step in the build stage (e.g., use pnpm install --prod or pnpm prune --prod
after installing dev deps) or perform a production-only install in the final
stage so that the node_modules copied by COPY --from=build are pruned of
devDependencies; update the Dockerfile around the install/prune steps and the
COPY --from=build reference (the COPY line and the install/prune commands are
the unique symbols to modify).

In `@Dockerfiles/Dockerfile.ecosystem`:
- Line 11: The Dockerfile currently runs the build step with "RUN pnpm run build
ecosystem" but still leaves devDependencies in the image; after the build
instruction add a "RUN pnpm prune --prod" step to remove devDependencies (i.e.,
place the pnpm prune --prod command immediately following the RUN pnpm run build
ecosystem instruction so only production deps remain).

In `@Dockerfiles/Dockerfile.geolocation`:
- Line 22: The Dockerfile currently copies the entire node_modules from the
build stage ("COPY --from=build /app/node_modules ./node_modules"), which
includes devDependencies; update the build/final steps so only production deps
are copied: either install only production packages in the build stage (use npm
ci --only=production or NODE_ENV=production npm ci) or run npm prune
--production in the build stage before the COPY, or alternatively stop copying
node_modules and instead COPY package*.json then run npm ci --only=production in
the final stage; apply the change around the "COPY --from=build
/app/node_modules ./node_modules" line.

In `@Dockerfiles/Dockerfile.issuance`:
- Line 11: The Dockerfile is installing devDependencies into the production
image because the RUN pnpm run build issuance step runs with dev deps present;
change the Dockerfile to build in a separate builder stage and only copy the
built artifacts and production dependencies into the final image (or, at
minimum, run pnpm install --prod / pnpm install --prod --frozen-lockfile in the
final stage before copying artifacts) so devDependencies are not shipped; target
the RUN pnpm run build issuance step (and the npm/pnpm install steps surrounding
it) to implement a multi-stage build that installs devDependencies only in the
builder stage and installs only production deps in the runtime stage.

In `@Dockerfiles/Dockerfile.oid4vc-issuance`:
- Line 11: The production image is including devDependencies because there is no
pruning step after the build; after the existing RUN pnpm run build
oid4vc-issuance in the build stage, add a step to run pnpm prune --prod (or
equivalent pnpm install --prod/prune command) so that node_modules only contains
production deps before the final-stage COPY --from=build /app/node_modules;
apply the same change to the other identical build step referenced in the review
to ensure devDependencies are not copied into the final image.

In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Line 11: The image still contains devDependencies because you run the build
but don't prune them; after the RUN pnpm run build oid4vc-verification step add
a RUN pnpm prune --prod to remove devDependencies so only production deps remain
(update the Dockerfile step following the existing RUN pnpm run build
oid4vc-verification command).

In `@Dockerfiles/Dockerfile.organization`:
- Line 11: The Dockerfile currently runs the build with the command "RUN pnpm
run build organization" but does not remove devDependencies, causing
devDependencies to be shipped to production; add a step immediately after that
command to run "RUN pnpm prune --prod" (i.e., insert a RUN pnpm prune --prod
line right after the RUN pnpm run build organization statement) so the
production image only keeps production dependencies.

In `@Dockerfiles/Dockerfile.seed`:
- Line 18: The Docker CMD currently only runs "npx prisma db seed" in
libs/prisma-service which can fail if migrations haven't been applied; update
the startup command for the container to run "npx prisma migrate deploy" before
"npx prisma db seed" (e.g., combine or sequence the commands in the CMD that
changes in Dockerfiles/Dockerfile.seed) so migrations are applied first, or
alternatively ensure upstream orchestration runs "prisma migrate deploy" prior
to invoking the existing CMD; target the CMD that currently executes in
libs/prisma-service and add the "prisma migrate deploy" step before the seed.

In `@Dockerfiles/Dockerfile.user`:
- Line 11: The Dockerfile currently runs "RUN pnpm run build user" but ends up
shipping devDependencies into the production image; change to a multi-stage
build: create a builder stage that installs all deps (pnpm install) and runs
"pnpm run build user" (e.g., stage name "builder"), then create a slim final
stage that copies only the build artifacts and package.json/pnpm-lock.yaml and
runs "pnpm install --prod" (or "pnpm install --frozen-lockfile --prod") to
install only production deps; ensure the final image does not run a full install
of devDependencies or copy node_modules from the builder stage.
- Line 24: The Dockerfile must not trigger Prisma migrations at container
start—ensure all migrations are applied externally by the deployment pipeline;
confirm that CMD ["node", "dist/apps/user/main.js"] only starts the app and
remove any automatic migration invocations (e.g., calls to prisma migrate or use
of an entrypoint script that runs migrations) from the Docker image or startup
code (inspect dist/apps/user/main.js and any entrypoint scripts) so the
container solely runs the application and migration orchestration happens
outside the container.

In `@Dockerfiles/Dockerfile.utility`:
- Line 11: The production Dockerfile currently runs the build step (RUN pnpm run
build utility) but still copies full node_modules including devDependencies into
the final image; after the build step add a pruning step (RUN pnpm prune --prod)
to remove devDependencies before copying node_modules into the final image (or
ensure the multi-stage copy pulls node_modules from the stage where pnpm prune
--prod ran), updating the stage that runs RUN pnpm run build utility to include
the pnpm prune --prod command so the final image contains only production deps.
- Line 24: The Dockerfile currently uses the direct CMD ["node",
"dist/apps/utility/main.js"], which bypasses the start script that runs prisma
migrate deploy; change the container startup strategy so migrations run before
the app: either restore the image to invoke the package.json start script (so
start runs prisma migrate deploy) or ensure your deployment orchestration (init
container, CI job, or startup hook) executes prisma migrate deploy prior to
replicas starting; update references to CMD and the start script/prisma migrate
deploy flow accordingly.

In `@Dockerfiles/Dockerfile.webhook`:
- Line 22: The Dockerfile currently copies the build-stage node_modules
wholesale via the COPY --from=build /app/node_modules ./node_modules
instruction, which carries devDependencies into the final image; to fix, prune
or produce a production-only node_modules before copying by either running pnpm
prune --prod (or npm ci --only=production) in the build stage after the build
completes, or add a dedicated production install stage that runs pnpm install
--prod --frozen-lockfile and then COPY from that stage (i.e., replace COPY
--from=build /app/node_modules ./node_modules with a copy from the
pruned/prod-install stage or ensure the build stage runs pnpm prune --prod and
then copy the pruned node_modules).

In `@Dockerfiles/Dockerfile.x509`:
- Line 24: The Dockerfile's direct CMD ["node", "dist/apps/x509/main.js"]
bypasses the npm start script (and any migration steps), so ensure migrations
run before app startup by invoking the project's migration path; either replace
the direct node CMD with the npm start entrypoint that runs migrations, or add a
startup wrapper that runs "prisma migrate deploy" (or the project's migration
command) before launching dist/apps/x509/main.js; update the Dockerfile's CMD or
ENTRYPOINT accordingly and reference the existing CMD ["node",
"dist/apps/x509/main.js"] when making the change so deployments always run
migrations prior to starting the app.
- Line 22: The Dockerfile currently copies the entire build-stage node_modules
(COPY --from=build /app/node_modules ./node_modules) which includes
devDependencies; modify the build stage in Dockerfiles/Dockerfile.x509 to prune
devDependencies before that COPY by running a production-only prune/install
(e.g., run pnpm prune --prod or reinstall production deps) so that node_modules
only contains production packages, then keep the existing COPY --from=build
/app/node_modules ./node_modules to pull the slimmed modules into the runtime
image.

---

Nitpick comments:
In `@Dockerfiles/Dockerfile.agent-provisioning`:
- Line 2: Replace the pinned base image string "FROM node:24-alpine3.21" with a
current Alpine variant such as "FROM node:24-alpine3.23" (or at minimum
"node:24-alpine3.22") to ensure upstream CVE/patch fixes are included; update
the same FROM string in any other Dockerfiles referencing "node:24-alpine3.21"
(e.g., the other Dockerfile noted as 21-21) and rebuild images to verify no
downstream breakages from the base image bump.

In `@Dockerfiles/Dockerfile.api-gateway`:
- Line 2: Replace the superseded base image tag "node:24-alpine3.21" used in the
Dockerfile (the FROM node:24-alpine3.21 AS build line) with the current Alpine
patch variant, e.g. "node:24-alpine3.22" (or 24-alpine3.23), and apply the same
change to other Dockerfiles that use the same tag (the occurrences noted as
14-14) so all Node 24 Alpine base images are updated consistently.

In `@Dockerfiles/Dockerfile.geolocation`:
- Line 2: Update the Docker base image reference FROM node:24-alpine3.21 to a
supported Alpine patch (e.g. node:24-alpine3.22 or node:24-alpine3.23) in the
Dockerfile where the FROM node:24-alpine3.21 line appears so the image receives
current OS-level security patches; change the image tag consistently for other
Dockerfiles that use the same FROM node:24-alpine3.21 reference.

In `@Dockerfiles/Dockerfile.notification`:
- Line 2: Update the pinned base image string "node:24-alpine3.21" to a current
Alpine variant (e.g., "node:24-alpine3.22" or "node:24-alpine3.23") wherever it
appears (the Dockerfile FROM line using that tag), and do the same for the
analogous legacy image tag (e.g., "node:14-alpine3.21") referenced in the other
Dockerfile; ensure both FROM lines are changed so the build uses the newer
alpine3.22/3.23 variant to improve OS-level CVE coverage.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aaed3a4 and 4e06601.

📒 Files selected for processing (20)
  • Dockerfiles/Dockerfile.agent-provisioning
  • Dockerfiles/Dockerfile.agent-service
  • Dockerfiles/Dockerfile.api-gateway
  • Dockerfiles/Dockerfile.cloud-wallet
  • Dockerfiles/Dockerfile.connection
  • Dockerfiles/Dockerfile.ecosystem
  • Dockerfiles/Dockerfile.geolocation
  • Dockerfiles/Dockerfile.issuance
  • Dockerfiles/Dockerfile.ledger
  • Dockerfiles/Dockerfile.notification
  • Dockerfiles/Dockerfile.oid4vc-issuance
  • Dockerfiles/Dockerfile.oid4vc-verification
  • Dockerfiles/Dockerfile.organization
  • Dockerfiles/Dockerfile.seed
  • Dockerfiles/Dockerfile.user
  • Dockerfiles/Dockerfile.utility
  • Dockerfiles/Dockerfile.verification
  • Dockerfiles/Dockerfile.webhook
  • Dockerfiles/Dockerfile.x509
  • package.json

Comment on lines +22 to +29
RUN apk update && apk upgrade && apk add --no-cache \
openssl \
openssh-client \
aws-cli \
docker \
docker-compose \
jq \
&& rm -rf /var/cache/apk/* \
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find apps/agent-provisioning -type f \( -name "*.ts" -o -name "*.js" -o -name "*.sh" \) | head -20

Repository: credebl/platform

Length of output: 655


🏁 Script executed:

rg -n '\b(docker|aws)\b' apps/agent-provisioning/ --type=ts -C2

Repository: credebl/platform

Length of output: 42


🏁 Script executed:

rg -n 'docker|docker-compose|aws' apps/agent-provisioning/AFJ/ -C2

Repository: credebl/platform

Length of output: 13892


🏁 Script executed:

rg -n '\bexec(Sync)?\(' apps/agent-provisioning/ --type=ts -A2 | grep -E '(docker|aws)'

Repository: credebl/platform

Length of output: 42


🏁 Script executed:

rg -n 'spawn|exec|shell' apps/agent-provisioning/src/ --type=ts -B2 -A2

Repository: credebl/platform

Length of output: 2358


🏁 Script executed:

rg -n "import.*child_process" apps/agent-provisioning/src/ --type=ts

Repository: credebl/platform

Length of output: 157


🏁 Script executed:

cat apps/agent-provisioning/src/agent-provisioning.service.ts | head -100

Repository: credebl/platform

Length of output: 4118


Confirm runtime dependency of aws-cli, docker, and docker-compose packages.

The agent-provisioning service invokes these tools at runtime via shell scripts (start_agent_ecs.sh, start_agent.sh) executed during wallet provisioning requests. The walletProvision method in agent-provisioning.service.ts calls exec() to spin up agent containers and register ECS task definitions. These packages are justified runtime dependencies, though they significantly increase final image size and CVE surface. Consider evaluating whether to use lightweight alternatives or if image size/security posture is acceptable for this service's operational model.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.agent-provisioning` around lines 22 - 29, The
Dockerfile currently installs heavy runtime packages (aws-cli, docker,
docker-compose) that are used by shell scripts (start_agent_ecs.sh,
start_agent.sh) and by the walletProvision method in
agent-provisioning.service.ts via exec(); confirm whether these commands truly
must run inside the container at runtime and if not remove them from the final
image or replace with lighter alternatives (use AWS SDK calls from
walletProvision instead of aws-cli, call remote Docker daemon or include only
the docker client binary, or move tooling to a sidecar/host or a build-stage so
final image size/CVE surface is reduced); update the Dockerfile and the
referenced scripts/service accordingly and document the chosen operational model
if you keep the packages.

Comment thread Dockerfiles/Dockerfile.agent-provisioning Outdated
Comment thread Dockerfiles/Dockerfile.api-gateway
Comment thread Dockerfiles/Dockerfile.cloud-wallet
Comment thread Dockerfiles/Dockerfile.connection
Comment thread Dockerfiles/Dockerfile.oid4vc-issuance
Comment thread Dockerfiles/Dockerfile.organization
Comment thread Dockerfiles/Dockerfile.seed
Comment thread Dockerfiles/Dockerfile.user
Comment thread Dockerfiles/Dockerfile.verification
Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
Dockerfiles/Dockerfile.x509 (2)

24-24: ⚠️ Potential issue | 🔴 Critical

Ensure Prisma migrations are executed before service startup.

Directly starting Node at Line 24 can skip prisma migrate deploy if your deployment pipeline does not run migrations elsewhere, which can break on schema drift.

#!/bin/bash
# Verify whether migrations are executed outside container startup (read-only checks).

rg -n --glob '!**/node_modules/**' 'prisma migrate deploy|prisma migrate|migrate deploy'
rg -n --glob '!**/node_modules/**' 'initContainers|helm\.sh/hook|pre-upgrade|pre-install'
rg -n '"start"\s*:\s*".*prisma migrate deploy' package.json
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` at line 24, The Dockerfile currently starts the
service directly with CMD ["node", "dist/apps/x509/main.js"], which can skip
running Prisma migrations; change startup to run migrations first (e.g., run
`prisma migrate deploy` or `npm exec prisma migrate deploy`) before starting
Node by replacing the direct CMD with an ENTRYPOINT/CMD that executes a small
startup script or command sequence that runs migrations (using prisma via npm
exec/npx if Prisma binary isn't globally installed), then execs node
dist/apps/x509/main.js; ensure the startup script references the same
environment variables used by Prisma (DATABASE_URL, etc.) and that the image
includes/install Prisma tooling so migrate deploy can run at container start.

8-8: ⚠️ Potential issue | 🟠 Major

Prune dev dependencies before copying node_modules to the runtime image.

pnpm i in the build stage installs devDependencies, and Line 22 copies that full tree into production. That undermines the vulnerability-reduction goal and inflates runtime attack surface.

Suggested fix
 RUN pnpm i --frozen-lockfile --ignore-scripts
 COPY . .
 RUN cd libs/prisma-service && npx prisma generate
 RUN pnpm run build x509
+RUN pnpm prune --prod

Also applies to: 22-22

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.x509` at line 8, The build stage runs "RUN pnpm i
--frozen-lockfile --ignore-scripts" which installs devDependencies but later the
full node_modules tree is copied into the runtime image (the COPY of
node_modules from the build stage), so remove devDeps before that copy: either
run "pnpm install --frozen-lockfile --prod" in place of the current install or
run "pnpm prune --prod" immediately after "RUN pnpm i --frozen-lockfile
--ignore-scripts" so the subsequent COPY of node_modules only includes
production dependencies.
🧹 Nitpick comments (1)
Dockerfiles/Dockerfile.oid4vc-verification (1)

4-4: Consider upgrading to pnpm v10.

The current npm latest tag for pnpm is 10.30.2. pnpm@9.15.3 is the final v9 patch and pnpm v10 has been the actively maintained line for some time. Staying on v9 means missing security and performance improvements. Consider bumping to a pinned v10 release across all Dockerfiles.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` at line 4, Update the RUN
installation to pin pnpm v10 instead of v9: replace the RUN line that installs
pnpm (currently "RUN npm install -g pnpm@9.15.3 --ignore-scripts") with a pinned
v10 release (e.g., "pnpm@10.x" or a specific v10 patch like "pnpm@10.30.2")
across all Dockerfiles so the installer uses the maintained v10 line and gets
security/performance fixes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Around line 21-22: The COPY commands that set --chmod=444 for node_modules and
libs strip execute bits and break native binaries (e.g., Prisma query engine)
and directory traversal; update the two COPY lines that reference "/app/libs/
./libs/" and "/app/node_modules ./node_modules" to avoid forcing 444 — either
remove the --chmod flag for those COPYs or use a mode that preserves exec bits
(e.g., 0755) so binaries and directories remain executable at runtime.

---

Duplicate comments:
In `@Dockerfiles/Dockerfile.x509`:
- Line 24: The Dockerfile currently starts the service directly with CMD
["node", "dist/apps/x509/main.js"], which can skip running Prisma migrations;
change startup to run migrations first (e.g., run `prisma migrate deploy` or
`npm exec prisma migrate deploy`) before starting Node by replacing the direct
CMD with an ENTRYPOINT/CMD that executes a small startup script or command
sequence that runs migrations (using prisma via npm exec/npx if Prisma binary
isn't globally installed), then execs node dist/apps/x509/main.js; ensure the
startup script references the same environment variables used by Prisma
(DATABASE_URL, etc.) and that the image includes/install Prisma tooling so
migrate deploy can run at container start.
- Line 8: The build stage runs "RUN pnpm i --frozen-lockfile --ignore-scripts"
which installs devDependencies but later the full node_modules tree is copied
into the runtime image (the COPY of node_modules from the build stage), so
remove devDeps before that copy: either run "pnpm install --frozen-lockfile
--prod" in place of the current install or run "pnpm prune --prod" immediately
after "RUN pnpm i --frozen-lockfile --ignore-scripts" so the subsequent COPY of
node_modules only includes production dependencies.

---

Nitpick comments:
In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Line 4: Update the RUN installation to pin pnpm v10 instead of v9: replace the
RUN line that installs pnpm (currently "RUN npm install -g pnpm@9.15.3
--ignore-scripts") with a pinned v10 release (e.g., "pnpm@10.x" or a specific
v10 patch like "pnpm@10.30.2") across all Dockerfiles so the installer uses the
maintained v10 line and gets security/performance fixes.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e06601 and 24ad3df.

📒 Files selected for processing (2)
  • Dockerfiles/Dockerfile.oid4vc-verification
  • Dockerfiles/Dockerfile.x509

Comment thread Dockerfiles/Dockerfile.oid4vc-verification Outdated
@ajile-in
Copy link
Copy Markdown
Member

@KambleSahil3 pls review

Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
Dockerfiles/Dockerfile.seed (1)

18-18: ⚠️ Potential issue | 🟠 Major

Guarantee migrate-before-seed, or restore it here.

libs/prisma-service/prisma/seed.ts:807-839 seeds application data but never applies migrations. With this CMD, a fresh database will fail unless deployment always runs npx prisma migrate deploy first. Either chain migrate deploy back into this command or verify/document that the orchestration enforces that ordering.

Proposed fix
-CMD ["sh", "-c", "cd libs/prisma-service && npx prisma db seed"]
+CMD ["sh", "-c", "cd libs/prisma-service && npx prisma migrate deploy && npx prisma db seed"]

Run this to confirm the execution path:

#!/bin/bash
set -euo pipefail

echo "Seed image / seed command references:"
rg -n -C2 'Dockerfile\.seed|prisma db seed|db seed' -g '!**/node_modules/**' -g '!**/dist/**'

echo
echo "Migration command references:"
rg -n -C2 'prisma migrate deploy|migrate deploy' -g '!**/node_modules/**' -g '!**/dist/**'

echo
echo "Expected: every path that invokes the seed image has a preceding migration step."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.seed` at line 18, The Dockerfile seed CMD currently
runs "cd libs/prisma-service && npx prisma db seed" which can fail on a fresh DB
because migrations aren't applied; update the seed image to ensure migrations
run first by chaining or replacing the CMD to run "npx prisma migrate deploy"
before "npx prisma db seed" (targeting the same working dir in
libs/prisma-service), or alternatively add a clear runtime check/documentation
that every invocation of this Dockerfile.seed image is preceded by a migration
step; locate the CMD in Dockerfiles/Dockerfile.seed and the seeding logic in
libs/prisma-service (seed.ts) and implement the migrate->seed ordering using npx
prisma migrate deploy followed by npx prisma db seed.
Dockerfiles/Dockerfile.oid4vc-issuance (1)

22-22: ⚠️ Potential issue | 🟠 Major

Prune devDependencies before exporting node_modules.

Line 22 copies the full workspace install from the build stage. Without a prod-only prune first, the runtime image still ships the dev toolchain and its extra CVE surface.

🔧 Proposed fix
 RUN cd libs/prisma-service && npx prisma generate
 RUN pnpm run build oid4vc-issuance
+RUN pnpm prune --prod
 
 # Stage 2: Create the final image
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-issuance` at line 22, The Dockerfile currently
copies the complete node_modules from the build stage (COPY --from=build
/app/node_modules ./node_modules) which includes devDependencies; before that
COPY, modify the build stage so it prunes dev deps (e.g., run npm ci --omit=dev
or npm prune --production or set NODE_ENV=production and run npm ci) so the
/app/node_modules produced in the build stage contains only production packages,
then keep the existing COPY --from=build /app/node_modules ./node_modules to
export the pruned modules into the runtime image.
🧹 Nitpick comments (2)
Dockerfiles/Dockerfile.oid4vc-verification (1)

17-18: Consider renaming the user for clarity.

The user is named nextjs, but this is an oid4vc-verification service, not a Next.js application. This appears to be copy-pasted from a template and may cause confusion during debugging or auditing.

♻️ Suggested fix for naming consistency
-    && adduser -S nextjs -u 1001 -G nodejs
+    && adduser -S appuser -u 1001 -G nodejs

Then update the USER directive accordingly:

-USER nextjs
+USER appuser
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.oid4vc-verification` around lines 17 - 18, The
Dockerfile creates a service user named "nextjs" via the adduser call which is
misleading for the oid4vc-verification service; change the username passed to
adduser (and any matching addgroup if desired) to a name reflecting the service
(e.g., "oid4vc" or "verification"), and update the USER directive elsewhere to
use that new username; specifically edit the adduser invocation that currently
uses "nextjs" and any references to "nextjs" (including the USER directive) to
maintain consistent, clear naming.
Dockerfiles/Dockerfile.agent-provisioning (1)

2-2: Minor: Extra space in FROM statements.

Lines 2 and 21 have FROM node:24-alpine3.21 with two spaces. Consider normalizing to single space for consistency.

Suggested fix
-FROM  node:24-alpine3.21 AS build
+FROM node:24-alpine3.21 AS build
-FROM  node:24-alpine3.21
+FROM node:24-alpine3.21

Also applies to: 21-21

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.agent-provisioning` at line 2, Normalize the extra
space in the Dockerfile FROM directives by replacing the double-space
occurrences of the FROM instruction (e.g., the lines that read "FROM 
node:24-alpine3.21") with a single space so they read "FROM node:24-alpine3.21";
update both occurrences found in the Dockerfiles/Dockerfile.agent-provisioning
file to ensure consistent formatting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfiles/Dockerfile.issuance`:
- Line 22: The runtime image is copying the full build-stage node_modules
(including devDependencies); run a prod-only prune in the build stage before the
COPY so only runtime deps needed by dist/apps/issuance/main.js are copied.
Modify the build-stage steps that produce /app/node_modules to run a production
prune (e.g., npm prune --production or npm ci --omit=dev / npm install
--only=production) after build, then keep the existing COPY --from=build
/app/node_modules ./node_modules so the runtime image gets only production
packages.

In `@Dockerfiles/Dockerfile.notification`:
- Around line 22-25: The final Docker stage is missing the generated Prisma
client because it either performs a fresh install with --ignore-scripts or
doesn't copy node_modules from the build stage; fix by either adding a RUN npx
prisma generate in the final stage after pnpm install, or remove
--ignore-scripts from the pnpm install command so the `@prisma/client` postinstall
runs, or instead copy /app/node_modules (including
/app/node_modules/.prisma/client) from the build stage into the final image so
imports of `@prisma/client` resolve at runtime.

In `@Dockerfiles/Dockerfile.user`:
- Line 22: The runtime image currently copies the entire node_modules from the
build stage (COPY --from=build /app/node_modules ./node_modules), which includes
devDependencies; update the build-stage so dev deps are removed before export
(e.g., run npm ci/install and then prune devDependencies or install only
production deps) and then copy the pruned/production-only node_modules into the
runtime image; modify the Dockerfile build-stage commands that prepare
/app/node_modules and keep the runtime COPY pointing at that pruned location.

---

Duplicate comments:
In `@Dockerfiles/Dockerfile.oid4vc-issuance`:
- Line 22: The Dockerfile currently copies the complete node_modules from the
build stage (COPY --from=build /app/node_modules ./node_modules) which includes
devDependencies; before that COPY, modify the build stage so it prunes dev deps
(e.g., run npm ci --omit=dev or npm prune --production or set
NODE_ENV=production and run npm ci) so the /app/node_modules produced in the
build stage contains only production packages, then keep the existing COPY
--from=build /app/node_modules ./node_modules to export the pruned modules into
the runtime image.

In `@Dockerfiles/Dockerfile.seed`:
- Line 18: The Dockerfile seed CMD currently runs "cd libs/prisma-service && npx
prisma db seed" which can fail on a fresh DB because migrations aren't applied;
update the seed image to ensure migrations run first by chaining or replacing
the CMD to run "npx prisma migrate deploy" before "npx prisma db seed"
(targeting the same working dir in libs/prisma-service), or alternatively add a
clear runtime check/documentation that every invocation of this Dockerfile.seed
image is preceded by a migration step; locate the CMD in
Dockerfiles/Dockerfile.seed and the seeding logic in libs/prisma-service
(seed.ts) and implement the migrate->seed ordering using npx prisma migrate
deploy followed by npx prisma db seed.

---

Nitpick comments:
In `@Dockerfiles/Dockerfile.agent-provisioning`:
- Line 2: Normalize the extra space in the Dockerfile FROM directives by
replacing the double-space occurrences of the FROM instruction (e.g., the lines
that read "FROM  node:24-alpine3.21") with a single space so they read "FROM
node:24-alpine3.21"; update both occurrences found in the
Dockerfiles/Dockerfile.agent-provisioning file to ensure consistent formatting.

In `@Dockerfiles/Dockerfile.oid4vc-verification`:
- Around line 17-18: The Dockerfile creates a service user named "nextjs" via
the adduser call which is misleading for the oid4vc-verification service; change
the username passed to adduser (and any matching addgroup if desired) to a name
reflecting the service (e.g., "oid4vc" or "verification"), and update the USER
directive elsewhere to use that new username; specifically edit the adduser
invocation that currently uses "nextjs" and any references to "nextjs"
(including the USER directive) to maintain consistent, clear naming.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1503808d-9575-419f-8da8-65e83d7cc058

📥 Commits

Reviewing files that changed from the base of the PR and between 24ad3df and fe80364.

📒 Files selected for processing (15)
  • Dockerfiles/Dockerfile.agent-provisioning
  • Dockerfiles/Dockerfile.api-gateway
  • Dockerfiles/Dockerfile.cloud-wallet
  • Dockerfiles/Dockerfile.connection
  • Dockerfiles/Dockerfile.ecosystem
  • Dockerfiles/Dockerfile.issuance
  • Dockerfiles/Dockerfile.ledger
  • Dockerfiles/Dockerfile.notification
  • Dockerfiles/Dockerfile.oid4vc-issuance
  • Dockerfiles/Dockerfile.oid4vc-verification
  • Dockerfiles/Dockerfile.organization
  • Dockerfiles/Dockerfile.seed
  • Dockerfiles/Dockerfile.user
  • Dockerfiles/Dockerfile.verification
  • Dockerfiles/Dockerfile.x509
🚧 Files skipped from review as they are similar to previous changes (2)
  • Dockerfiles/Dockerfile.ecosystem
  • Dockerfiles/Dockerfile.connection

Comment thread Dockerfiles/Dockerfile.issuance
Comment thread Dockerfiles/Dockerfile.notification Outdated
Comment on lines +22 to +25
COPY --from=build /app/package.json /app/pnpm-lock.yaml /app/pnpm-workspace.yaml ./
RUN npm install -g pnpm@9.15.3 --ignore-scripts \
&& pnpm install --frozen-lockfile --ignore-scripts --prod \
&& npm uninstall -g pnpm
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

schema="$(fd '^schema\.prisma$' libs/prisma-service | head -n1)"
if [[ -z "${schema:-}" ]]; then
  echo "schema.prisma not found under libs/prisma-service"
  exit 1
fi

echo "=== Prisma generator block ==="
sed -n '/^generator /,/^}/p' "$schema"

echo
echo "=== Prisma client import sites ==="
rg -n '@prisma/client|PrismaClient' -g '!**/node_modules/**' .

Repository: credebl/platform

Length of output: 13002


🏁 Script executed:

cat -n Dockerfiles/Dockerfile.notification

Repository: credebl/platform

Length of output: 1320


🏁 Script executed:

rg -A 5 'prisma' package.json | head -20

Repository: credebl/platform

Length of output: 734


🏁 Script executed:

rg '"(postinstall|prepare)"' package.json

Repository: credebl/platform

Length of output: 90


🏁 Script executed:

cat -n libs/prisma-service/prisma/schema.prisma | head -30

Repository: credebl/platform

Length of output: 1798


Add prisma generate to the final stage or reuse the build-stage node_modules.

The build stage explicitly runs npx prisma generate (line 10), which creates the generated Prisma client at /app/node_modules/.prisma/client. However, the final stage does not copy /app/node_modules from the build stage. Instead, it performs a fresh pnpm install --frozen-lockfile --ignore-scripts --prod, which installs the @prisma/client npm package but does not regenerate the client (since --ignore-scripts disables postinstall hooks).

The application imports from @prisma/client throughout the codebase, so the missing generated client will cause runtime failures.

Fix one of the following:

  • Add RUN npx prisma generate after line 24 in the final stage, or
  • Change line 24 to remove --ignore-scripts to allow the postinstall hook to regenerate the client, or
  • Copy the build-stage node_modules instead of performing a fresh install.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfiles/Dockerfile.notification` around lines 22 - 25, The final Docker
stage is missing the generated Prisma client because it either performs a fresh
install with --ignore-scripts or doesn't copy node_modules from the build stage;
fix by either adding a RUN npx prisma generate in the final stage after pnpm
install, or remove --ignore-scripts from the pnpm install command so the
`@prisma/client` postinstall runs, or instead copy /app/node_modules (including
/app/node_modules/.prisma/client) from the build stage into the final image so
imports of `@prisma/client` resolve at runtime.

Comment thread Dockerfiles/Dockerfile.user
Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
…heir specific functionality requirements. The changes make the containers more secure and reduce potential vulnerabilities that would

be flagged by Trivy scans.

Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
@DeepakNemad DeepakNemad force-pushed the fix/docker-vulnerabilities branch from b85207d to 8092250 Compare March 20, 2026 12:00
Copy link
Copy Markdown
Member

@ajile-in ajile-in left a comment

Choose a reason for hiding this comment

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

Anchor to specific version of OpenSSL

Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
Signed-off-by: DeepakNemad <deepak.nemade@ayanworks.com>
@sonarqubecloud
Copy link
Copy Markdown

@ajile-in
Copy link
Copy Markdown
Member

LGTM

@DeepakNemad DeepakNemad requested a review from ajile-in March 23, 2026 10:24
Copy link
Copy Markdown
Contributor

@KambleSahil3 KambleSahil3 left a comment

Choose a reason for hiding this comment

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

LG

@DeepakNemad DeepakNemad requested a review from sujitaw March 23, 2026 10:28
Copy link
Copy Markdown
Contributor

@sujitaw sujitaw left a comment

Choose a reason for hiding this comment

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

LGTM

@KambleSahil3 KambleSahil3 merged commit 7eb63c6 into main Mar 23, 2026
8 checks passed
@KambleSahil3 KambleSahil3 deleted the fix/docker-vulnerabilities branch March 23, 2026 10:32
@coderabbitai coderabbitai Bot mentioned this pull request Apr 1, 2026
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.

5 participants