Skip to content

Security Scanning

Security Scanning #195

Workflow file for this run

name: Security Scanning
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# Daily at 02:00 UTC — catches newly published CVEs between dependency bumps
- cron: "0 2 * * *"
workflow_dispatch:
permissions:
contents: read
security-events: write # SARIF upload to GitHub Security tab
concurrency:
group: security-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
# ── Go: govulncheck (Go vulnerability database) ──────────────────────────
govulncheck:
name: govulncheck (Go)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: services/merrymaker-go/go.mod
check-latest: true
cache: true
cache-dependency-path: services/merrymaker-go/go.sum
- name: Setup Bun (needed to build embed targets before govulncheck)
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: "1.3.13"
- name: Build frontend assets
working-directory: services/merrymaker-go/frontend
run: |
bun install --frozen-lockfile
bun run build
- name: Install govulncheck
# Run directly rather than via golang/govulncheck-action to avoid the
# action's internal git-checkout conflicting with our already-authenticated
# checkout (produces a duplicate Authorization header → HTTP 400).
# GOTOOLCHAIN=auto allows Go to fetch a newer toolchain if govulncheck@latest
# requires a Go version newer than the one declared in go.mod.
env:
GOTOOLCHAIN: auto
working-directory: services/merrymaker-go
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run govulncheck
# Pre-existing Go vulnerabilities (GO-2026-4982/4980/4971) in existing
# code — not introduced by this PR. Remove continue-on-error once
# remediated via Dependabot or patch PRs.
continue-on-error: true
working-directory: services/merrymaker-go
run: govulncheck ./...
# ── npm audit (puppeteer-worker) ─────────────────────────────────────────
npm-audit:
name: npm audit (puppeteer-worker)
runs-on: ubuntu-latest
defaults:
run:
working-directory: services/puppeteer-worker
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: "24"
cache: npm
cache-dependency-path: services/puppeteer-worker/package-lock.json
- name: Install dependencies (skip Chromium download)
env:
PUPPETEER_SKIP_DOWNLOAD: "true"
run: npm ci --ignore-scripts
- name: npm audit
# Pre-existing vulnerabilities in puppeteer-worker deps — tracked via
# GitHub Security tab. Remove continue-on-error once Dependabot PRs
# have cleared the existing CVE backlog.
continue-on-error: true
run: npm audit --audit-level=high
# ── Trivy: filesystem scan — merrymaker-go ───────────────────────────────
trivy-go:
name: Trivy FS (merrymaker-go)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Trivy filesystem scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
scan-ref: services/merrymaker-go
format: sarif
output: trivy-go.sarif
severity: CRITICAL,HIGH
exit-code: "0" # informational — SARIF results appear in Security tab; existing debt addressed via Dependabot
ignore-unfixed: true
- name: Upload SARIF to GitHub Security tab
if: always()
uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
with:
sarif_file: trivy-go.sarif
category: trivy-merrymaker-go
# ── Trivy: filesystem scan — puppeteer-worker ────────────────────────────
trivy-puppeteer:
name: Trivy FS (puppeteer-worker)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Trivy filesystem scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
scan-ref: services/puppeteer-worker
format: sarif
output: trivy-puppeteer.sarif
severity: CRITICAL,HIGH
exit-code: "0" # informational — SARIF results appear in Security tab; existing debt addressed via Dependabot
ignore-unfixed: true
- name: Upload SARIF to GitHub Security tab
if: always()
uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
with:
sarif_file: trivy-puppeteer.sarif
category: trivy-puppeteer-worker
# ── CodeQL — Go + JavaScript/TypeScript ──────────────────────────────────
codeql:
name: CodeQL (${{ matrix.language }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [go, javascript-typescript]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Initialize CodeQL
uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
with:
languages: ${{ matrix.language }}
queries: security-extended,security-and-quality
- name: Setup Go
if: matrix.language == 'go'
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: services/merrymaker-go/go.mod
check-latest: true
- name: Setup Bun (needed to build embed targets before CodeQL Go scan)
if: matrix.language == 'go'
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version: "1.3.13"
- name: Build frontend assets (Go embed requires compiled assets)
if: matrix.language == 'go'
working-directory: services/merrymaker-go/frontend
run: |
bun install --frozen-lockfile
bun run build
- name: Autobuild
uses: github/codeql-action/autobuild@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
with:
category: /language:${{ matrix.language }}