Skip to content

chore(deps): bump the js-workspace group across 1 directory with 24 updates #326

chore(deps): bump the js-workspace group across 1 directory with 24 updates

chore(deps): bump the js-workspace group across 1 directory with 24 updates #326

Workflow file for this run

name: security
on:
workflow_dispatch:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# 03:00 UTC every Monday so security issues surface before a workweek.
- cron: "0 3 * * 1"
# Public-repo security gate.
#
# Hard, blocking jobs (npm/pnpm audit, pip-audit) fail the workflow on
# high/critical advisories. gosec / trivy stay report-only (artifacts +
# job summary) and, when the repo is public, also upload SARIF to GitHub
# code scanning. CodeQL is public-only and report-oriented — it is not
# part of the required "Security Success" aggregator so a first-time
# CodeQL config issue cannot wedge every PR.
#
# Branch protection should require the single "Security Success" check.
permissions:
contents: read
security-events: write
actions: read
concurrency:
group: security-${{ github.ref }}
cancel-in-progress: true
jobs:
gosec:
name: gosec (Go runtime + CLI)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Run gosec
uses: securego/gosec@master
with:
# Standard rule set; the high-noise rules (G104 for unchecked
# errors) are excluded so the report is meaningful. -no-fail keeps
# this report-only — the SARIF artifact below carries the findings.
args: "-fmt sarif -out gosec.sarif -no-fail -exclude G104 ./services/..."
- name: Summarize high-severity findings
if: always()
run: |
if [ -f gosec.sarif ]; then
high=$(python3 -c "import json;d=json.load(open('gosec.sarif'));r=d['runs'][0];print(sum(1 for x in r['results'] if (x.get('level')=='error')))" 2>/dev/null || echo '?')
echo "### gosec — $high error-level finding(s)" >> "$GITHUB_STEP_SUMMARY"
echo "Full SARIF is attached as the \`gosec-sarif\` artifact." >> "$GITHUB_STEP_SUMMARY"
fi
- name: Upload SARIF artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: gosec-sarif
path: gosec.sarif
if-no-files-found: ignore
- name: Upload SARIF to code scanning
if: always() && github.event.repository.private != true
continue-on-error: true
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: gosec.sarif
category: gosec
pnpm-audit:
name: pnpm audit (workspace)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Audit production dependencies
# --audit-level=high gates on high/critical only; moderate +
# below flow through Dependabot rather than blocking the build.
# --prod matches what we ship (dashboard, customer-app, sdk-ts).
run: pnpm audit --audit-level=high --prod
npm-audit-docs:
name: npm audit (docs-site)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: docs-site/package-lock.json
- name: Install
working-directory: docs-site
run: npm ci --omit=dev
- name: Audit
working-directory: docs-site
run: npm audit --audit-level=high --omit=dev
pip-audit:
name: pip-audit (sdk-py)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install pip-audit
run: pip install pip-audit
- name: Audit
working-directory: packages/sdk-py
# --vulnerability-service=osv preferred — has wider coverage
# than PyPI's index alone.
run: pip-audit --vulnerability-service=osv
trivy:
name: trivy fs scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Trivy (table to log + summary)
uses: aquasecurity/trivy-action@master
with:
scan-type: fs
scan-ref: .
severity: "HIGH,CRITICAL"
scanners: vuln
format: table
ignore-unfixed: true
output: trivy.txt
- name: Trivy (SARIF artifact)
uses: aquasecurity/trivy-action@master
with:
scan-type: fs
scan-ref: .
severity: "HIGH,CRITICAL"
scanners: vuln
format: sarif
ignore-unfixed: true
output: trivy.sarif
- name: Job summary
if: always()
run: |
{
echo "### trivy fs scan (HIGH/CRITICAL, fixed-only)"
echo '```'
cat trivy.txt 2>/dev/null || echo "(no report produced)"
echo '```'
echo "Full SARIF is attached as the \`trivy-sarif\` artifact."
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload SARIF artifact
if: always()
uses: actions/upload-artifact@v7
with:
name: trivy-sarif
path: trivy.sarif
if-no-files-found: ignore
- name: Upload SARIF to code scanning
if: always() && github.event.repository.private != true
continue-on-error: true
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: trivy.sarif
category: trivy
codeql:
name: CodeQL
# Code scanning is free on public repos. Skip on private checkouts
# without GitHub Advanced Security so the upload API cannot 403.
if: ${{ github.event.repository.private != true }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: ["go", "javascript", "python"]
steps:
- uses: actions/checkout@v7
- uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
- uses: github/codeql-action/autobuild@v4
- uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"
security-success:
name: Security Success
needs:
[gosec, pnpm-audit, npm-audit-docs, pip-audit, trivy]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check required security jobs
run: |
# Aggregator so branch protection can require one check.
# CodeQL is intentionally omitted — it is report-only.
results='${{ toJSON(needs) }}'
echo "Job results: $results"
echo "$results" | jq -e 'all(.[]; .result == "success" or .result == "skipped")'