Skip to content

release: v0.10.7 — Publishes the container image for the v0.10.6 fixes #40

release: v0.10.7 — Publishes the container image for the v0.10.6 fixes

release: v0.10.7 — Publishes the container image for the v0.10.6 fixes #40

Workflow file for this run

name: Code Scan
# Read-only security scanners that complement CodeQL. Each tool's findings
# are uploaded as SARIF into the GitHub Security tab (code scanning), so they
# sit alongside CodeQL and are reviewed together as a release gate. The SARIF
# scanners (zizmor / semgrep / osv-scanner) report into the Security tab
# rather than blocking a PR on a pre-existing finding; gitleaks is a hard gate
# (test fixtures + in-tree public keys allowlisted) and actionlint reports
# until its baseline is clean.
#
# All action uses are SHA-pinned (with a trailing version comment), matching
# the rest of the repo's workflows.
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
# Workflow-level is read-only; only the SARIF-uploading jobs elevate.
permissions:
contents: read
jobs:
# ── actionlint: GitHub Actions workflow correctness (gate) ──────────
actionlint:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Run actionlint
# Report-only on introduction so a pre-existing finding in another
# workflow doesn't block PRs; flip to a hard gate once the baseline
# is clean.
#
# The actionlint image is digest-pinned (not :latest) so a tag-
# republish or registry compromise cannot swap the linter bytes
# and emit a fake-clean result that masks a genuine workflow defect.
# Refresh the digest on the same cadence as the other action pins.
run: docker run --rm -v "${PWD}:/repo" -w /repo rhysd/actionlint@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667 -color || true # v1.7.12
# ── zizmor: GitHub Actions security audit (SARIF → Security tab) ────
zizmor:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
security-events: write # upload SARIF (code scanning)
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.x'
- name: Install zizmor
# Version-pinned (not floating latest) so a compromised newer release
# can't silently enter this security-events:write job; bump deliberately.
run: pipx install zizmor==1.26.1
- name: Run zizmor
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Scope to first-party workflows. Passing `.` also descends into
# vendored dependencies' own `.github/workflows/` (e.g. vendor/blamejs),
# whose pipelines never run in this repo, surfacing findings about
# third-party CI we don't control. Mirrors the semgrep job's vendor
# exclusion — both keep the scan to code that executes here.
run: zizmor --format sarif .github/workflows/ > zizmor.sarif || true
- name: Upload SARIF
if: ${{ always() && hashFiles('zizmor.sarif') != '' }}
continue-on-error: true
uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1
with:
sarif_file: zizmor.sarif
category: zizmor
# ── Semgrep: SAST + Actions/secret rules (SARIF → Security tab) ─────
semgrep:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
security-events: write # upload SARIF (code scanning)
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.x'
- name: Install Semgrep
# Version-pinned (not floating latest) so a compromised newer release
# can't silently enter this security-events:write job; bump deliberately.
run: pipx install semgrep==1.168.0
- name: Run Semgrep
run: |
semgrep scan \
--config p/default \
--config p/github-actions \
--config p/secrets \
--sarif --output semgrep.sarif \
--exclude vendor --exclude tests --exclude build || true
- name: Upload SARIF
if: ${{ always() && hashFiles('semgrep.sarif') != '' }}
continue-on-error: true
uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1
with:
sarif_file: semgrep.sarif
category: semgrep
# ── OSV-Scanner: known CVEs across the vendored surface (SARIF) ─────
# The vendored deps have no lockfile, so build the CycloneDX SBOM (the same
# one shipped on each release) and scan that — every leaf bundle (blamejs +
# noble-*) carries a purl/CPE for advisory mapping.
osv-scanner:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
security-events: write # upload SARIF (code scanning)
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '>=24.18.0'
- name: Build CycloneDX SBOM
run: node scripts/build-sbom.js --out build
- name: Install OSV-Scanner
id: osv_install
env:
# Pinned release + committed SHA-256 of osv-scanner_linux_amd64.
# Bump both together when moving to a newer osv-scanner; the SUMS
# file lives at the release's osv-scanner_SHA256SUMS asset.
OSV_VERSION: v2.4.0
OSV_SHA256: 15314940c10d26af9c6649f150b8a47c1262e8fc7e17b1d1029b0e479e8ed8a0
run: |
# This job holds security-events:write, so a scanner binary pulled
# from the mutable releases/latest path and run unverified could
# execute attacker bytes and suppress the very code-scanning findings
# this gate exists to surface. Pin to a specific release tag and
# verify the asset's SHA-256 before chmod+exec — matching the SHA-pin
# posture of every other executable input in this repo's CI.
#
# A network/download failure is an availability problem: warn + skip
# the scan (SARIF is report-only). A checksum MISMATCH is an integrity
# problem (tag-republish / asset swap): fail loudly rather than run or
# silently skip, so a swapped binary can never emit a fake-clean SARIF.
if ! curl -sSfL "https://github.com/google/osv-scanner/releases/download/${OSV_VERSION}/osv-scanner_linux_amd64" -o "${RUNNER_TEMP}/osv-scanner"; then
echo "::warning::osv-scanner download failed; skipping scan"
echo "ok=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if ! echo "${OSV_SHA256} ${RUNNER_TEMP}/osv-scanner" | sha256sum -c -; then
echo "::error::osv-scanner ${OSV_VERSION} checksum mismatch; refusing to execute"
exit 1
fi
chmod +x "${RUNNER_TEMP}/osv-scanner"
echo "ok=true" >> "$GITHUB_OUTPUT"
- name: Scan SBOM
if: ${{ steps.osv_install.outputs.ok == 'true' }}
run: |
SBOM=$(ls build/*.cdx.json | head -1)
echo "Scanning ${SBOM}"
"${RUNNER_TEMP}/osv-scanner" scan --format sarif --output osv.sarif --sbom "${SBOM}" || true
- name: Upload SARIF
if: ${{ always() && hashFiles('osv.sarif') != '' }}
continue-on-error: true
uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1
with:
sarif_file: osv.sarif
category: osv-scanner
# ── Gitleaks: committed-secret scan (gate; tests/ allowlisted) ─────
gitleaks:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
fetch-depth: 0 # full history so a secret added then removed is still caught
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_CONFIG: .gitleaks.toml