Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions .github/workflows/snyk-release-monitor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
name: Snyk Release Monitor (long-lived versions)

# ============================================================================
# PURPOSE
# ============================================================================
# This workflow exists to demonstrate the "long-lived release monitoring"
# pattern Proconex asked about:
#
# - On every release tag push, we push a NEW Snyk dashboard target tagged
# with that version (--target-reference=vX.Y.Z). That target is then
# monitored INDEFINITELY for newly-disclosed CVEs against its pinned
# dependency tree.
#
# - A weekly heartbeat job re-monitors every active release branch. This
# keeps the snapshot "fresh" so it isn't auto-deactivated by any
# org-level stale-project policy, and it confirms in the dashboard /
# audit log that we are still actively tracking each released version.
#
# - Notification routing (Slack / email / Jira) for any newly-detected
# CVE on these versions is handled by Snyk org-level notification
# settings -- no code change needed here.
# ============================================================================

on:
# 1) Release pipeline: tag-driven. Any tag like v1.2.3 creates / updates
# its own Snyk monitored target.
push:
tags:
- 'v*.*.*'

# 2) Heartbeat: re-monitor every active release branch weekly so legacy
# versions don't go stale in the Snyk dashboard.
schedule:
- cron: '0 6 * * 1' # Every Monday 06:00 UTC

# 3) On-demand: lets you populate the demo dashboard from the UI.
workflow_dispatch:
inputs:
version:
description: 'Version to monitor (e.g. 1.2.0). Leave blank to read from package.json.'
required: false
default: ''

jobs:
# --------------------------------------------------------------------------
# JOB 1: Release-tag monitor.
# Fires only on tag push. Reads the tag name, monitors that exact code.
# --------------------------------------------------------------------------
monitor-release-tag:
if: startsWith(github.ref, 'refs/tags/v')
name: Monitor release ${{ github.ref_name }}
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout tagged code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Install dependencies
run: npm install --ignore-scripts

- name: Setup Snyk CLI
uses: snyk/actions/setup@master

- name: Authenticate Snyk
run: snyk auth "$SNYK_TOKEN"
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

- name: Push Snyk monitor snapshot for ${{ github.ref_name }}
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
# github.ref_name is the tag, e.g. "v1.2.0" -- strip the leading v
# so VERSION matches package.json semver.
VERSION: ${{ github.ref_name }}
run: |
VERSION="${VERSION#v}"
export VERSION
./scripts/snyk-monitor-release.sh

# --------------------------------------------------------------------------
# JOB 2: Heartbeat for legacy release branches.
# Fires on the weekly schedule (and manual dispatch). Checks out each
# active release/* branch and re-runs the monitor script so the dashboard
# target stays "live".
# --------------------------------------------------------------------------
monitor-active-releases:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
name: Heartbeat-monitor release/${{ matrix.branch }}
runs-on: ubuntu-latest
permissions:
contents: read

strategy:
fail-fast: false
matrix:
# ----------------------------------------------------------------
# Edit this list as Proconex (or you) ship new versions.
# Drop a version from the matrix when it's truly end-of-life and
# you no longer want notifications for it.
# ----------------------------------------------------------------
branch:
- v1.0
- v1.1
- v1.2
- v2.0

steps:
- name: Checkout release/${{ matrix.branch }}
uses: actions/checkout@v4
with:
ref: release/${{ matrix.branch }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Install dependencies
run: npm install --ignore-scripts

- name: Setup Snyk CLI
uses: snyk/actions/setup@master

- name: Authenticate Snyk
run: snyk auth "$SNYK_TOKEN"
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

- name: Heartbeat monitor for release/${{ matrix.branch }}
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
run: ./scripts/snyk-monitor-release.sh
185 changes: 185 additions & 0 deletions .github/workflows/snyk-sca-sast-demo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
name: Snyk SCA and SAST Security Pipeline

# ============================================================================
# TRIGGER CONFIGURATION
# ============================================================================
# This workflow runs on:
# - Every push to main/master branches (typical for production deployments)
# - Pull requests targeting main/master (for pre-merge security validation)
# - Manual trigger via workflow_dispatch (for on-demand testing)
on:
push:
branches: [ main, master ]
# pull_request:
# branches: [ main, master ]
workflow_dispatch:

# ============================================================================
# SNYK OPEN SOURCE (SCA) SCAN JOB
# ============================================================================
# Software Composition Analysis (SCA) scans your open-source dependencies
# for known vulnerabilities in third-party packages
jobs:
snyk-sca-scan:
name: SCA - Snyk Open Source Scan
runs-on: ubuntu-latest

# Required permissions for GitHub integration
permissions:
contents: read
security-events: write

steps:
# Step 1: Check out the repository code
- name: Checkout code
uses: actions/checkout@v4

# Step 2: Set up Node.js environment (required for npm projects)
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

# Step 3: Install project dependencies
# This ensures Snyk can analyze the actual dependency tree
- name: Install dependencies
run: npm install

# Step 4: Install and configure Snyk CLI
- name: Setup Snyk CLI
uses: snyk/actions/setup@master

# Step 5: Authenticate with Snyk using organization token
# SNYK_TOKEN should be configured as a GitHub secret
- name: Authenticate Snyk
run: snyk auth ${{ secrets.SNYK_TOKEN }}
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

# Step 6: Run Snyk Open Source TEST
# This scans dependencies and BLOCKS the pipeline if high/critical vulns are found
# --severity-threshold=high: Only fail on high or critical severity issues
# --all-projects: Scan all package manager manifests in the repo
#
# BLOCKING MODE (COMMENTED OUT FOR DEMO)
# Uncomment the step below to enable pipeline blocking on high/critical vulnerabilities
# Remove 'continue-on-error: true' to enforce the block
# - name: Snyk Open Source Test (Block on High+)
# run: |
# snyk test \
# --severity-threshold=high \
# --report \
# --org=2c2549f7-de55-4c31-aaea-bea685244487 \
# --project-name="nodejs-goof-sca" \
# --target-reference=${{ github.ref_name }}
# env:
# SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

# REPORT-ONLY MODE (CURRENTLY ACTIVE)
# This version runs the test, reports to dashboard, but doesn't block the pipeline
# --report: Sends results to Snyk Dashboard for continuous monitoring
# --project-name: Custom name visible in Snyk UI
# --target-reference: Git branch/tag for tracking different environments
- name: Snyk Open Source Test & Report (Send to Dashboard)
continue-on-error: true
run: |
snyk test \
--severity-threshold=high \
--report \
--org=2c2549f7-de55-4c31-aaea-bea685244487 \
--project-name="nodejs-goof-sca" \
--target-reference=${{ github.ref_name }}
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

# ============================================================================
# SNYK CODE (SAST) SCAN JOB
# ============================================================================
# Static Application Security Testing (SAST) analyzes your first-party code
# for security vulnerabilities and code quality issues
snyk-code-scan:
name: SAST - Snyk Code Scan
runs-on: ubuntu-latest

# Required permissions for GitHub integration
permissions:
contents: read
security-events: write

steps:
# Step 1: Check out the repository code
- name: Checkout code
uses: actions/checkout@v4

# Step 2: Install and configure Snyk CLI
- name: Setup Snyk CLI
uses: snyk/actions/setup@master

# Step 3: Authenticate with Snyk using organization token
- name: Authenticate Snyk
run: snyk auth ${{ secrets.SNYK_TOKEN }}
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

# Step 4: Run Snyk Code TEST
# This scans your source code and BLOCKS the pipeline if high/critical vulns are found
# --severity-threshold=high: Only fail on high or critical severity issues
# Snyk Code analyzes: JavaScript, TypeScript, Python, Java, C#, Go, PHP, Ruby, etc.
#
# BLOCKING MODE (COMMENTED OUT FOR DEMO)
# Uncomment the step below to enable pipeline blocking on high/critical vulnerabilities
# Remove 'continue-on-error: true' to enforce the block
# - name: Snyk Code Test (Block on High+)
# run: |
# snyk code test \
# --severity-threshold=high \
# --report \
# --org=2c2549f7-de55-4c31-aaea-bea685244487 \
# --project-name="nodejs-goof-sast"
# env:
# SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

# REPORT-ONLY MODE (CURRENTLY ACTIVE)
# This version runs the test, reports to dashboard, but doesn't block the pipeline
# --report: Sends SAST results to Snyk Dashboard for continuous monitoring
# --project-name: Custom name visible in Snyk UI (required for --report)
- name: Snyk Code Test & Report (Send to Dashboard)
continue-on-error: true
run: |
snyk code test \
--severity-threshold=high \
--report \
--org=2c2549f7-de55-4c31-aaea-bea685244487 \
--project-name="nodejs-goof-sast"
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

# Step 5: SAST Results Sent to Dashboard
# The --report flag above sends Snyk Code results to the Snyk Dashboard
# Results will appear at: https://app.snyk.io/org/varner-tech-engineering/projects
# Look for project name: nodejs-goof-sast

# ============================================================================
# REQUIRED GITHUB SECRETS
# ============================================================================
# To use this pipeline, configure these secrets in your GitHub repository:
# Settings > Secrets and variables > Actions > New repository secret
#
# 1. SNYK_TOKEN: Your Snyk API token
# - Get from: https://app.snyk.io/account (Account Settings > API Token)
# - Format: UUID string (e.g., 12345678-1234-1234-1234-123456789abc)
#
# 2. SNYK_ORG_ID: Your Snyk Organization ID (optional but recommended)
# - Get from: https://app.snyk.io/org/YOUR_ORG/manage/settings
# - Format: UUID string or organization slug
# - If not set, uses your default organization
#
# ============================================================================
# DEMO TALKING POINTS
# ============================================================================
# 1. SHIFT-LEFT SECURITY: Scans run on every commit and PR before merge
# 2. DUAL SCANNING: Both SCA (dependencies) and SAST (your code) in one pipeline
# 3. FAIL-FAST: Pipeline blocks on high/critical vulnerabilities
# 4. CONTINUOUS MONITORING: Results sent to Snyk Dashboard for tracking over time
# 5. DEVELOPER FRIENDLY: Clear feedback in PR checks and GitHub Actions UI
# 6. CUSTOMIZABLE: Adjust severity thresholds, add more Snyk scans (Container, IaC)
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ npm-debug.log

# Snyk Security Extension - AI Rules (auto-generated)
.github/instructions/snyk_rules.instructions.md

# Snyk Security Extension - AI Rules (auto-generated)
.cursor/rules/snyk_rules.mdc
44 changes: 44 additions & 0 deletions .snyk
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Snyk (https://snyk.io) policy file
# See https://docs.snyk.io/manage-risk/policies/the-.snyk-file for details
version: v1.25.0

# =============================================================================
# EXCLUDE: Prevent files/directories from being scanned by Snyk Code (SAST)
# =============================================================================
# Patterns follow .gitignore syntax. These files will be completely skipped
# during SAST analysis.
exclude:
global:
# Skip intentionally vulnerable demo files
# - routes/xss-vulnerable.js

# Skip test files — they often contain mock payloads that trigger false positives
- tests/**

# =============================================================================
# IGNORE: Suppress specific Open Source (SCA) vulnerabilities
# =============================================================================
# Use this when a vulnerability has been reviewed and accepted as low risk,
# is not exploitable in your context, or has no available fix.
# Each entry requires an expiry date and a reason for audit trail purposes.
ignore:
# --- Critical: Zip Slip in adm-zip (accepted risk — no user-uploaded zips) ---
'npm:adm-zip:20180415':
- '*':
reason: 'Accepted risk — application does not process user-uploaded zip files'
expires: 2026-03-07T00:00:00.000Z
created: 2026-02-27T00:00:00.000Z

# # --- High: Prototype Pollution in lodash (deep dependency, no direct usage) ---
# SNYK-JS-LODASH-567746:
# - '*':
# reason: 'Transitive dependency — lodash merge/defaults not called with user input'
# expires: 2026-06-01T00:00:00.000Z
# created: 2026-02-27T00:00:00.000Z

# # --- Medium: Prototype Pollution in js-yaml (dev/config only) ---
# SNYK-JS-JSYAML-13961110:
# - '*':
# reason: 'js-yaml only parses trusted config files, not user-supplied input'
# expires: 2026-06-01T00:00:00.000Z
# created: 2026-01-27T00:00:00.000Z
Loading