Skip to content

Deploy: container/image hardening — non-root USER, pinned base digests, image vulnerability scan #267

Closed

Description

@mforce

Deployment-readiness gap (#244), RECOMMENDED — flagged by all 3 reviewers.

Problem

Container/image hardening is missing before external users:

  • Runs as root. The runtime stage sets no USER (Dockerfile:29-37); the aspnet:10.0 base ships a non-root app user (UID 1654) but does not switch to it, so the process runs as UID 0. A container escape or in-process RCE runs as root.
  • Base images float. node:22-alpine, sdk:10.0, aspnet:10.0 are pulled by floating tag, and the platform rebuilds on every push — so the running OS layer drifts and builds aren't reproducible.
  • Image never CVE-scanned. CI scans NuGet + npm application deps + CodeQL, but nothing scans the built runtime image's OS layer; Dependabot covers Actions/npm/NuGet, not Docker images.

Fix

  • Add USER $APP_UID (ensure wwwroot/sourcemaps stay readable); consider a read-only root FS + capability drop.
  • Pin base images by digest; schedule rebuilds / Docker-image update PRs for OS + runtime patches.
  • Add Trivy/Grype against the built image (+ SBOM) in CI, ideally also at deploy.

Verify

docker run … id shows a non-zero UID; the image still binds :8080 and serves the SPA + API; the scan job fails on a seeded high-severity CVE.

Part of the #244 deployment-readiness audit; tracked in epic #15.

Activity

  1. added 2 commits that reference this issue on Jul 30, 2026
  2. mforce commented on Jul 30, 2026

    @mforce
    OwnerAuthor

    Done — merged in PR #294. Delivered: non-root runtime user (uid 1654), digest-pinned base images (all three, multi-arch index digests), a Trivy CI gate failing on fixable HIGH/CRITICAL, and a Dependabot docker ecosystem to keep the pinned digests current. Plus trivy-action itself is now SHA-pinned to its v0.36.0 commit (the action was compromised in the 2026-03 supply-chain incident; a mutable tag was the exposure). Also advanced #266's app-side (CI now builds the runtime image). Fully resolved in-repo — no deploy-side remainder.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:apiAPI/endpoint layer

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions