From 67dcacf016c6023458932f6e8c9e0f28c75c5b3f Mon Sep 17 00:00:00 2001 From: dkijania Date: Sun, 28 Jun 2026 17:05:47 +0200 Subject: [PATCH 1/2] =?UTF-8?q?ci:=20add=20supply-chain=20security=20?= =?UTF-8?q?=E2=80=94=20Dependabot,=20npm=20audit=20gate,=20SBOM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There were no supply-chain controls: no Dependabot, no audit gate, no SBOM. - `.github/dependabot.yml`: weekly updates for npm (production/development grouped), GitHub Actions, and Docker (keeps the pinned base-image digest fresh). - `.github/workflows/security.yaml`: - npm audit — hard gate on **critical** advisories in production deps (what actually ships), plus a full informational audit. Production deps currently have 0 critical, so the gate passes; the 4 highs are OpenTelemetry/fast-uri transitives that Dependabot / the Yoga 5 upgrade (#176) will clear. - CycloneDX SBOM generation, uploaded as an artifact. Dependency/image vulnerability scanning (Trivy/Grype) is deferred so the scanner action can be verified separately rather than shipped red — Dependabot (npm + docker) already surfaces vulnerable deps and base images in the meantime. Refs #175. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01QSuak9smCHbp4N17xjjLF6 --- .github/dependabot.yml | 26 +++++++++++++++++ .github/workflows/security.yaml | 49 +++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/security.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..1737ad64 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,26 @@ +version: 2 +updates: + # Application dependencies. Production and development updates are grouped + # separately so security-relevant runtime bumps are easy to review on their own. + - package-ecosystem: npm + directory: '/' + schedule: + interval: weekly + open-pull-requests-limit: 10 + groups: + production-dependencies: + dependency-type: production + development-dependencies: + dependency-type: development + + # Keep CI action versions current and patched. + - package-ecosystem: github-actions + directory: '/' + schedule: + interval: weekly + + # Keep the pinned base-image digest in the Dockerfile fresh. + - package-ecosystem: docker + directory: '/' + schedule: + interval: weekly diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml new file mode 100644 index 00000000..d51a4851 --- /dev/null +++ b/.github/workflows/security.yaml @@ -0,0 +1,49 @@ +name: Security + +on: + pull_request: + push: + branches: + - main + schedule: + # Weekly, so advisories on unchanged code are still surfaced. + - cron: '0 6 * * 1' + +permissions: + contents: read + +jobs: + npm-audit: + name: npm audit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + - run: npm ci + # Hard gate: fail on critical advisories in what actually ships (prod deps). + - name: Audit production dependencies (gate on critical) + run: npm audit --omit=dev --audit-level=critical + # Informational: surface the full picture (incl. dev tooling) without blocking. + - name: Full audit (informational) + run: npm audit || true + + sbom: + name: SBOM + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Generate CycloneDX SBOM + continue-on-error: true + uses: anchore/sbom-action@v0 + with: + path: . + format: cyclonedx-json + output-file: sbom.cyclonedx.json + - name: Upload SBOM artifact + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: sbom + path: sbom.cyclonedx.json From 66dd6482cd8930fccd7bba1dd4efc596eef86d17 Mon Sep 17 00:00:00 2001 From: dkijania Date: Wed, 19 Aug 2026 13:36:14 +0200 Subject: [PATCH 2/2] ci: tighten supply-chain checks --- .github/dependabot.yml | 8 +++++++- .github/workflows/security.yaml | 11 +++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1737ad64..e36111fe 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,7 +6,7 @@ updates: directory: '/' schedule: interval: weekly - open-pull-requests-limit: 10 + open-pull-requests-limit: 5 groups: production-dependencies: dependency-type: production @@ -18,9 +18,15 @@ updates: directory: '/' schedule: interval: weekly + open-pull-requests-limit: 3 + groups: + github-actions: + patterns: + - '*' # Keep the pinned base-image digest in the Dockerfile fresh. - package-ecosystem: docker directory: '/' schedule: interval: weekly + open-pull-requests-limit: 2 diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml index d51a4851..c1109ec8 100644 --- a/.github/workflows/security.yaml +++ b/.github/workflows/security.yaml @@ -12,6 +12,10 @@ on: permissions: contents: read +concurrency: + group: security-${{ github.ref }} + cancel-in-progress: true + jobs: npm-audit: name: npm audit @@ -21,7 +25,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: '20' - - run: npm ci + - run: npm ci --ignore-scripts # Hard gate: fail on critical advisories in what actually ships (prod deps). - name: Audit production dependencies (gate on critical) run: npm audit --omit=dev --audit-level=critical @@ -35,15 +39,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Generate CycloneDX SBOM - continue-on-error: true - uses: anchore/sbom-action@v0 + uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 with: path: . format: cyclonedx-json output-file: sbom.cyclonedx.json - name: Upload SBOM artifact - continue-on-error: true uses: actions/upload-artifact@v4 with: name: sbom path: sbom.cyclonedx.json + if-no-files-found: error