Files
FarmaFinder/docs/superpowers/plans/2026-07-22-security-dependency-hardening.md
T
Antoni Nuñez Romeu 849763896d
Run Tests on Branches / Detect Changes (push) Successful in 12s
Run Tests on Branches / Frontend Tests (push) Successful in 2m12s
Run Tests on Branches / Frontend Mobile Tests (push) Has been skipped
Run Tests on Branches / Parapharmacy API Tests (push) Successful in 2m2s
Run Tests on Branches / PIP Platform Tests (push) Has been skipped
Run Tests on Branches / Backend Tests (push) Successful in 2m8s
security: harden production configuration and routes
2026-07-22 17:24:54 +02:00

9.4 KiB

FarmaFinder Security Dependency and Release Hardening Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Remove the remaining high/critical dependency and supply-chain risks, make Python and container builds reproducible, and establish deployment-blocking security verification after the configuration and access-control hotfixes.

Architecture: Upgrade dependencies in isolated package-family batches while preserving the existing runtime security controls. Resolve Python dependencies into a committed uv.lock, pin container inputs by immutable digests, and run dependency, image, and secret scans in CI. Any remaining advisory is recorded with its path, exploitability, mitigation, and owner.

Tech Stack: npm workspaces/package-lock, Node.js 20/24, Python 3.13, uv, pip-audit, Docker Compose, Trivy, Gitleaks, Jest, Vitest, pytest.


Files and responsibilities

  • Create docs/security/2026-07-22-dependency-hardening.md: audit baseline, selected versions/digests, residual-advisory decisions, and verification evidence.
  • Create apps/pip-platform/uv.lock: resolved, hash-pinned Python dependency graph.
  • Modify apps/backend/package.json, apps/parapharmacy-api/package.json, apps/frontend/package.json, apps/scraper/package.json, and the root package-lock.json for isolated dependency batches.
  • Modify both Node Dockerfiles, Compose files, and deployment docs for immutable images and lockfile-enforced installs.
  • Create .github/workflows/security.yml: reproducible installs, tests, audits, secret scanning, image scanning, and Compose checks.

Baseline to preserve

The preceding hotfix plan already added production secret validation, service-key middleware, protected parapharmacy mutations, internal Compose networking, production-safe Swagger behavior, and security regression tests. Do not revert those controls. The last online audit reported 56 advisories for the backend/workspace scope and 3 for the parapharmacy API; counts must be refreshed before each batch.

Task 1: Establish an auditable dependency baseline

Files: Create docs/security/2026-07-22-dependency-hardening.md.

  • Run npm ci from the repository root, then run npm audit --json, npm audit --prefix apps/backend --json, npm audit --prefix apps/parapharmacy-api --json, npm audit --prefix apps/frontend --json, and npm audit --prefix apps/scraper --json, saving reports only under /tmp and never recording secret values.
  • Record counts, direct versions, Node/npm/Python/uv/Docker versions, dependency paths, available fixes, and whether each finding reaches a production image.
  • Confirm no unrelated lockfile rewrite exists with git diff --check and git status --short.
  • Commit the ledger with git add docs/security/2026-07-22-dependency-hardening.md && git commit -m "docs: record dependency hardening baseline".

Task 2: Create and verify the Python lockfile

Files: Create apps/pip-platform/uv.lock; update PIP deployment docs if present.

  • Run cd apps/pip-platform && uv lock; do not hand-edit generated lock content.
  • Recreate from the lock with uv sync --frozen --extra dev, then run uv run pytest -q and uv run pip-audit --strict.
  • If pip-audit is absent, add it to the development dependency group, rerun uv lock, and repeat the frozen sync. Record each Python advisory with package, path, reachability, and owner.
  • Commit with git add apps/pip-platform/uv.lock && git commit -m "build: lock pip platform dependencies".

Task 3: Pin runtime container inputs immutably

Files: Root/PIP Compose files, both Node Dockerfiles, and the dependency-hardening ledger.

  • Replace every runtime :latest image with an approved release. Resolve digests with docker buildx imagetools inspect redis:7-alpine, postgres:16-alpine, mongo:7, the approved n8n release, the approved Redis exporter release, and the approved PostgreSQL exporter release.
  • Replace each reference with repository:tag@sha256: followed by the exact digest returned by docker buildx imagetools inspect, record the UTC update date and approver, and verify the digest is for the deployment platform.
  • Ensure each Node Dockerfile copies its matching package.json and lockfile before npm ci --omit=dev; build both images and run a startup/config smoke test.
  • Commit the image/Dockerfile batch separately so it can be reverted without undoing dependency code.

Task 4: Upgrade backend dependency families independently

Files: apps/backend/package.json, root package-lock.json, existing backend tests.

  • Run npm ci and npm test --prefix apps/backend -- --runInBand before changing versions.
  • Upgrade all direct OpenTelemetry packages as one compatible family: API, auto-instrumentations, exporters, instrumentation-pino, resources, SDKs, and semantic conventions. Do not upgrade only auto-instrumentations-node.
  • Regenerate only through npm, inspect the lockfile for unrelated upgrades, and rerun the backend suite.
  • In a separate batch, upgrade bcrypt and sqlite3; verify native installs under Node 20 and 24, session/database tests, npm ls tar node-gyp, and npm audit --prefix apps/backend --audit-level=high.
  • Never use npm audit fix --force; any major upgrade requires a compatibility note and review. Commit each family separately.

Task 5: Upgrade parapharmacy and scraper dependency families

Files: apps/parapharmacy-api/package.json, apps/scraper/package.json, root package-lock.json, security tests.

  • Upgrade Mongoose within its supported major, regenerate the lockfile, and confirm npm ls fast-uri resolves outside the audited range.
  • Run npm test --prefix apps/parapharmacy-api -- --runInBand __tests__/security.test.js and npm audit --prefix apps/parapharmacy-api --audit-level=high.
  • Upgrade scraper Puppeteer dependencies only after recording the current executable path. Preserve PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true and /usr/bin/chromium; verify with node -e "console.log(process.env.PUPPETEER_EXECUTABLE_PATH || '/usr/bin/chromium')".
  • Run scraper module-load/available tests and commit Mongoose and scraper batches separately.

Task 6: Upgrade frontend tooling without exposing Vitest UI

Files: apps/frontend/package.json, root package-lock.json, Vite/Vitest config, CI workflow.

  • Confirm no production or CI command uses Vitest UI with rg -n "vitest( --ui|.*ui)" apps/frontend package.json .github.
  • Upgrade Vite, Rollup/esbuild, and Vitest as a compatible toolchain; keep React plugin, jsdom, and testing-library versions compatible with the selected Vitest major.
  • Regenerate the lockfile and run npm test --prefix apps/frontend, npm run build --prefix apps/frontend, and npm audit --prefix apps/frontend --audit-level=high.
  • Record any development-only residual advisory and commit this batch separately.

Task 7: Add deployment-blocking CI gates

Files: Create .github/workflows/security.yml.

  • Add pull-request/protected-branch jobs for npm ci plus all Node tests/builds; workspace/app npm audit --audit-level=high; uv sync --frozen, pytest, and pip-audit --strict; Gitleaks full-history scanning; Trivy high/critical image scanning; and root/PIP Compose rendering.
  • The Compose job must use fixture values and assert that only intended frontend/API ports are published, no internal database/exporter ports are published, and no production-secret ${...:-placeholder} fallback remains.
  • Build production images with committed lockfiles, scan image digests, upload JSON reports as artifacts, and never upload .env files or secret values.
  • Pin third-party actions to reviewed immutable commit SHAs and grant read-only repository permissions. Commit with git add .github/workflows/security.yml && git commit -m "ci: enforce dependency and image security gates".

Task 8: Run final verification and residual-advisory review

Files: Update the dependency-hardening ledger only if verification exposes a regression or documented exception.

  • Run npm ci, backend tests, parapharmacy security tests, frontend tests/build, uv sync --frozen --extra dev, uv run pytest, and uv run pip-audit --strict.
  • Render all Compose files with production-like fixture variables; inspect for placeholders, mutable tags, public database/exporter ports, and missing required secrets.
  • Build all production images and black-box test public GETs, 401 unauthenticated mutations, 403 invalid keys, absent production Swagger, and absent host-published internal infrastructure.
  • Re-run all audits. Every remaining high/critical item must list package, dependency path, production reachability, exploitability, mitigation, owner, and review/expiry date; unexplained high/critical findings block deployment.
  • Run git diff --check, confirm no real .env is tracked, attach command counts to the ledger, and commit the final evidence.

Self-review

This plan covers the remaining audit findings: dependency-family upgrades, Python locking/auditing, immutable images, lockfile-enforced Docker installs, secret scanning, image scanning, frontend/Vitest exposure, and residual-advisory review. It deliberately avoids forced major upgrades and keeps each risky family in a reversible batch.