fix(ci): run scanners before pnpm install to avoid node_modules false positives #51

Merged
julien merged 1 commits from fix/ci/scan-before-install into main 2026-05-08 00:18:58 +02:00
Owner

Summary

First successful gitleaks run flagged 381 "leaks" — all inside node_modules/ and .pnpm-store/, populated by the pnpm install --frozen-lockfile step that ran earlier in the job. Upstream npm packages routinely embed demo RSA keys / fake API tokens in their READMEs and test fixtures, and gitleaks correctly (by its rules) flags them.

Same class of false-positive Trivy hit in #49 — solved there by --scanners vuln. Here, the cleanest solution is reordering: run the scanners before pnpm install, so the working tree contains only our committed source.

  • Trivy scans pnpm-lock.yaml (committed) — doesn't need install.
  • Gitleaks scans the working tree (--no-git --source . in ci.yml) — doesn't need install.
  • pnpm audit reads pnpm-lock.yaml against the advisory DB — also doesn't need install. The install before audit remains for the workspace-integrity sanity check.

The ordering rationale is committed as a comment at the top of each job's steps: block, so a future contributor doesn't innocently shuffle the steps and re-flood the gate with FPs.

Same reordering applied to .gitea/workflows/security-scheduled.yml for consistency, even though its deep-history gitleaks scan doesn't suffer this issue (node_modules is .gitignored from day one — never in history).

Test plan

  • scan job goes green end-to-end on this PR — gitleaks reports 0 leaks (or only real ones from our source, none expected).
  • On push to main post-merge, scan stays green.
  • Trigger security-scheduled manually before next Monday's cron to verify the same ordering doesn't break the deep scan.

After this PR

With #43 (TS/ESLint reverts), #45 (Trivy install), #49 (Trivy --scanners vuln), #50 (gitleaks install), and now this — every gate of the CI pipeline should be green end-to-end. Phase-1 CI bring-up is then complete and we can move to A — local infra recipe (Postgres + Redis + OTel Collector).

## Summary First successful gitleaks run flagged **381 "leaks"** — all inside `node_modules/` and `.pnpm-store/`, populated by the `pnpm install --frozen-lockfile` step that ran earlier in the job. Upstream npm packages routinely embed demo RSA keys / fake API tokens in their READMEs and test fixtures, and gitleaks correctly (by its rules) flags them. Same class of false-positive Trivy hit in #49 — solved there by `--scanners vuln`. Here, the cleanest solution is **reordering**: run the scanners *before* `pnpm install`, so the working tree contains only our committed source. - **Trivy** scans `pnpm-lock.yaml` (committed) — doesn't need install. - **Gitleaks** scans the working tree (`--no-git --source .` in ci.yml) — doesn't need install. - **pnpm audit** reads `pnpm-lock.yaml` against the advisory DB — also doesn't need install. The install before audit remains for the workspace-integrity sanity check. The ordering rationale is committed as a comment at the top of each job's `steps:` block, so a future contributor doesn't innocently shuffle the steps and re-flood the gate with FPs. Same reordering applied to `.gitea/workflows/security-scheduled.yml` for consistency, even though its deep-history gitleaks scan doesn't suffer this issue (`node_modules` is `.gitignore`d from day one — never in history). ## Test plan - [ ] `scan` job goes green end-to-end on this PR — gitleaks reports 0 leaks (or only real ones from our source, none expected). - [ ] On `push` to main post-merge, scan stays green. - [ ] Trigger `security-scheduled` manually before next Monday's cron to verify the same ordering doesn't break the deep scan. ## After this PR With #43 (TS/ESLint reverts), #45 (Trivy install), #49 (Trivy `--scanners vuln`), #50 (gitleaks install), and now this — every gate of the CI pipeline should be green end-to-end. Phase-1 CI bring-up is then complete and we can move to **A — local infra recipe** (Postgres + Redis + OTel Collector).
julien added 1 commit 2026-05-08 00:18:31 +02:00
fix(ci): run scanners before pnpm install to avoid node_modules false positives
CI / commits (pull_request) Successful in 1m52s
CI / check (pull_request) Successful in 2m1s
CI / scan (pull_request) Successful in 2m3s
CI / a11y (pull_request) Successful in 2m15s
CI / perf (pull_request) Successful in 4m40s
f35045f3e8
First successful gitleaks run flagged 381 "leaks" — all of them
inside `node_modules/` and `.pnpm-store/`, populated by the
`pnpm install --frozen-lockfile` step that runs earlier in the
job. Upstream packages routinely embed demo RSA keys / fake API
tokens in their READMEs and test fixtures, and gitleaks
(correctly, by its rules) flags them all. This is the same class
of false-positive Trivy hit before us in #49.

Move both scanners (Trivy + gitleaks) to BEFORE `pnpm install`:

- Trivy scans `pnpm-lock.yaml` for vulns; the lockfile is
  committed, no install required.
- Gitleaks scans the working tree (`--no-git --source .` in
  ci.yml; deep history in security-scheduled.yml). Without
  `pnpm install`, the only files present are our own source
  code, which is what we actually want to scan.
- `pnpm audit` reads `pnpm-lock.yaml` against the advisory DB —
  also doesn't need node_modules. The install before audit
  remains for the workspace-integrity sanity check.

Net result: clean scans, no allowlist file to maintain, scanners
run faster (smaller tree to walk).

The ordering rationale is documented inline at the top of each
job's `steps:` block so a future contributor doesn't innocently
shuffle the steps and re-introduce the false-positive flood.

Apply the same reordering to `security-scheduled.yml` for
consistency, even though its deep-history gitleaks scan does not
suffer the same false positives (history does not contain
node_modules; gitignored from day one).
julien merged commit a0e8e095d0 into main 2026-05-08 00:18:58 +02:00
julien deleted branch fix/ci/scan-before-install 2026-05-08 00:18:58 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#51