Skip to content

feature:Dev Dockerfiles run as root with an unpinned base image - #1140

Merged
Ejirowebfi merged 1 commit into
Favourorg:mainfrom
joshkirojohn212-jpg:Stellar-forge1116
Aug 24, 2026
Merged

feature:Dev Dockerfiles run as root with an unpinned base image#1140
Ejirowebfi merged 1 commit into
Favourorg:mainfrom
joshkirojohn212-jpg:Stellar-forge1116

Conversation

@joshkirojohn212-jpg

Copy link
Copy Markdown
Contributor

closes #1116

Docker Dev Hardening — Audit Issue 28/30

Area: Infra (frontend/Dockerfile.dev, contracts/Dockerfile.dev, docker-compose.yml)
Severity: Low
Scope: Development-only (not production images; prod deploys via Vercel/Netlify/static hosting per README)
Date: 2026-08-22

Problem

  • frontend/Dockerfile.dev and contracts/Dockerfile.dev ran their build/dev tooling as root by default (no USER directive).
  • docker-compose.yml bind-mounts live source into the frontend container (./frontend:/app); a compromised transitive build dependency (npm ci, cargo build) would run as root with write access to the bind-mounted host source tree.
  • contracts/Dockerfile.dev pinned its base image to a mutable, dated tag (rust:1.75-slim) with no digest pin.

Changes

frontend/Dockerfile.dev

  • Added USER node, using the pre-existing non-root node user shipped by node:18-alpine.
  • Added RUN chown -R node:node /app so the anonymous node_modules volume — where Vite writes its dev cache (node_modules/.vite) — is owned by the runtime user.
  • Hot reload is preserved: CHOKIDAR_USEPOLLING=true (set in docker-compose.yml) lets Vite watch the bind-mounted, host-owned source via polling (read-only on source; writes go to the node-owned node_modules volume).

contracts/Dockerfile.dev

  • Pinned the base image by digest instead of the mutable tag:
    rust:1.75-slim@sha256:70c2a016184099262fd7cee46f3d35fec3568c45c62f87e37f7f665f766b1f74
    This is the immutable multi-arch index digest, so the tag can no longer be silently re-pushed to change the build base while still resolving on both amd64 and arm64 dev machines.
  • Added RUN useradd -m -s /bin/bash builder to create a non-root build user.
  • Added RUN chown -R builder:builder /contracts /usr/local/cargo so cargo build can write its output to the persisted contracts_target volume and to CARGO_HOME without root.
  • Added USER builder so the dev/build process runs unprivileged.

docker-compose.yml required no changes — CHOKIDAR_USEPOLLING=true and the volume mounts already support non-root operation once ownership is correct in the images.

Verification

Run in a Docker-enabled environment:

docker compose up -d --build
docker compose exec frontend whoami          # expected: node
docker compose exec contract-builder whoami  # expected: builder

Acceptance criteria:

  • docker compose up -d still functions identically for local dev (hot reload + contract building).
  • Neither container runs its main process as root (whoami returns node / builder).
  • Rust base image is pinned by digest.

Note: verification was not executed in the editing environment because Docker is not installed there; commands above must be run where Docker is available.

@Ejirowebfi
Ejirowebfi merged commit b70c586 into Favourorg:main Aug 24, 2026
20 of 21 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.8.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🔵 Dev Dockerfiles run as root with an unpinned base image

3 participants