diff --git a/.github/workflows/snyk.yml b/.github/workflows/snyk.yml index dd36c0b83..960a3e609 100644 --- a/.github/workflows/snyk.yml +++ b/.github/workflows/snyk.yml @@ -77,16 +77,40 @@ jobs: - name: Generate a lockfile Snyk can parse run: npm install --package-lock-only --ignore-scripts --legacy-peer-deps + # The Snyk CLI image, pinned by digest. snyk/actions/node is only a + # wrapper that runs the floating snyk/snyk:node tag, so pinning the + # action's commit would still run whatever image was pushed last, with + # SNYK_TOKEN. These steps pass what that action passes (its v1.0.0 + # action.yml). To update: take the digest of snyk/snyk:node from Docker + # Hub, check the release notes, and change both steps together. - name: Run Snyk id: snyk - uses: snyk/actions/node@master + uses: docker://snyk/snyk:node@sha256:71629f3cc12e98b9693cd59f60e81ce880745ced646e2f7cb784fa00281d0b71 env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + FORCE_COLOR: 2 + SNYK_INTEGRATION_NAME: GITHUB_ACTIONS + SNYK_INTEGRATION_VERSION: node with: # High and critical only, so the first run is actionable rather than # a wall of low-severity transitive noise. Lower it once the backlog # is clean. - args: --severity-threshold=high --file=package-lock.json + args: snyk test --severity-threshold=high --file=package-lock.json + + # Records what was just tested as a Snyk project, so the Snyk dashboard + # tracks the versions CI tests (the GitHub integration's own project + # reads package.json ranges) and alerts when a new advisory affects + # them. main only: pull requests are tested, never recorded. + - name: Record the tested dependencies in Snyk (main) + if: (success() || failure()) && github.event_name != 'pull_request' + uses: docker://snyk/snyk:node@sha256:71629f3cc12e98b9693cd59f60e81ce880745ced646e2f7cb784fa00281d0b71 + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + FORCE_COLOR: 2 + SNYK_INTEGRATION_NAME: GITHUB_ACTIONS + SNYK_INTEGRATION_VERSION: node + with: + args: snyk monitor --file=package-lock.json --project-name=reframe-oss/reframe-ci - name: Alert on High/Critical Snyk Findings if: failure() && steps.snyk.outcome == 'failure' && (github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch') diff --git a/docs/SECURITY-PIPELINE.md b/docs/SECURITY-PIPELINE.md index 8c1c2642e..f32a5375d 100644 --- a/docs/SECURITY-PIPELINE.md +++ b/docs/SECURITY-PIPELINE.md @@ -72,7 +72,15 @@ repository, `security/snyk` and `license/snyk`, and `snyk.yml` runs the CLI (`snyk test`, high and critical only) on pushes to main, on same-repo pull requests and weekly. Snyk can't read `bun.lock`, so that job tests a `package-lock.json` generated from `package.json`; the bun.lock policy above -is the exact check. +is the exact check. On main and the weekly run it also records what it +tested (`snyk monitor`) as the Snyk project `reframe-oss/reframe-ci`, so the +dashboard tracks those versions and Snyk alerts when a new advisory affects +them. + +Required on `main` (the `main-protection` ruleset): `build`, `Dependency +scan`, `Dependency policy (bun.lock)`, `Secret scan (gitleaks)`, `Workflow +lint (actionlint)` and `security/snyk`. `Dependency scan` is skipped on pull +requests from forks (no secrets there), which counts as passing. `.snyk` holds the policy: open-source ignores (none) and the paths Snyk Code skips (test-only code).