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 rootpackage-lock.jsonfor 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 cifrom the repository root, then runnpm audit --json,npm audit --prefix apps/backend --json,npm audit --prefix apps/parapharmacy-api --json,npm audit --prefix apps/frontend --json, andnpm audit --prefix apps/scraper --json, saving reports only under/tmpand 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 --checkandgit 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 runuv run pytest -qanduv run pip-audit --strict. - If
pip-auditis absent, add it to the development dependency group, rerunuv 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
:latestimage with an approved release. Resolve digests withdocker 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 bydocker 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.jsonand lockfile beforenpm 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 ciandnpm test --prefix apps/backend -- --runInBandbefore 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
bcryptandsqlite3; verify native installs under Node 20 and 24, session/database tests,npm ls tar node-gyp, andnpm 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-uriresolves outside the audited range. - Run
npm test --prefix apps/parapharmacy-api -- --runInBand __tests__/security.test.jsandnpm audit --prefix apps/parapharmacy-api --audit-level=high. - Upgrade scraper Puppeteer dependencies only after recording the current executable path. Preserve
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=trueand/usr/bin/chromium; verify withnode -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, andnpm 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 ciplus all Node tests/builds; workspace/appnpm audit --audit-level=high;uv sync --frozen, pytest, andpip-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
.envfiles 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, anduv 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.envis 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.