Skip to content
40 changes: 35 additions & 5 deletions .github/workflows/snyk-security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,22 @@ jobs:
# A personal access token (unlike a legacy per-account API key) isn't
# tied to a single default org, so the CLI can't infer which org to
# act against without this — omitting it 403s with an empty org name.
# Note: the CLI still calls GET /rest/orgs/{id} regardless of whether
# this is the org ID or its slug (tried both — same 403 either way),
# to resolve/validate the org. That call 403s because the PAT wasn't
# granted a scope covering it; it's cosmetic — the actual scan/monitor
# both succeed regardless. Fix at the source by granting that scope
# (or regenerating the PAT with it) at
# https://app.snyk.io/account/personal-access-tokens.
SNYK_CFG_ORG: "08ee9b45-66fd-4689-b808-50fc0e58ce15"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# Snyk Open Source resolves frontend/'s dependency tree via its
# node_modules, so it needs to be installed first.
# Snyk Open Source resolves each project's dependency tree from an
# actual installed environment, not just the manifest — so both the
# Python (root + tests/) and Node (frontend/) dependencies need to
# be installed first, or `snyk monitor` reports "Missing required
# packages" for whichever ecosystem wasn't set up.
- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
Expand All @@ -62,18 +72,38 @@ jobs:
working-directory: frontend
run: npm ci

- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.12"
- name: Install Python dependencies
run: pip install -r requirements.txt -r tests/requirements.txt

- name: Set up Snyk CLI to check for security issues
# Snyk can be used to break the build when it detects security issues.
# In this case we want to upload the SAST issues to GitHub Code Scanning
uses: snyk/actions/setup@8e119fbb6c251787721d34ba683ed48eba792766

# Runs Snyk Code (SAST) analysis and uploads result into GitHub.
# Use || true to not fail the pipeline
#
# --sarif-file-output (not `--sarif > file`): the latter redirects
# ALL output into the SARIF file, so a failed run's log shows only
# "Process completed with exit code 1" and nothing about why —
# --sarif-file-output writes the SARIF to disk while still printing
# the normal human-readable findings list to the job log.
- name: Snyk Code test
run: snyk code test --sarif > snyk-code.sarif # || true
run: snyk code test --sarif-file-output=snyk-code.sarif # || true

# Runs Snyk Open Source (SCA) analysis and uploads result to Snyk.
# Independent of Snyk Code above — a Code finding failing that step
# shouldn't stop dependency monitoring from running and reporting.
# success() || failure(), not always(): always() also fires on job
# cancellation, and cancel-in-progress above cancels superseded PR
# runs — we don't want a cancelled run still pushing a `snyk
# monitor` snapshot (a persistent record, unlike `snyk test`).
- name: Snyk Open Source monitor
if: success() || failure()
run: snyk monitor --all-projects
Comment thread
AviBackToBlack marked this conversation as resolved.

# `snyk code test` above still fails the job on real findings (the
Expand All @@ -83,7 +113,7 @@ jobs:
# file actually contains parseable SARIF.
- name: Check SARIF output is valid
id: sarif-check
if: always()
if: success() || failure()
run: |
if [ -s snyk-code.sarif ] && jq empty snyk-code.sarif >/dev/null 2>&1; then
echo "valid=true" >> "$GITHUB_OUTPUT"
Expand All @@ -93,7 +123,7 @@ jobs:

# Push the Snyk Code results into GitHub Code Scanning tab.
- name: Upload result to GitHub Code Scanning
if: always() && steps.sarif-check.outputs.valid == 'true'
if: (success() || failure()) && steps.sarif-check.outputs.valid == 'true'
uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3
with:
sarif_file: snyk-code.sarif
Loading