From 94354c40c5ac1cccf904f6076705df0f74484b4f Mon Sep 17 00:00:00 2001 From: Steven Zhang Date: Thu, 16 Apr 2026 16:38:13 -0500 Subject: [PATCH 1/6] fix(ci): enable corepack in dependency-scan so cdxgen produces a real SBOM The dependency-scan workflow has been silently broken since it was added (SEC-7263). cdxgen internally runs `yarn install` but corepack was never enabled, so it fell back to system yarn 1.x, failed silently, and produced a 0-component BOM. OPA then evaluated the empty BOM and vacuously passed. - Enable corepack and install deps before the shared generate-sbom action - Add a non-zero component guard so empty scans fail loudly - Document that this workflow checks license compliance, not CVEs Fixes: SDK-2170 Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependency-scan.yml | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.github/workflows/dependency-scan.yml b/.github/workflows/dependency-scan.yml index c5e544e2f7..a71a582398 100644 --- a/.github/workflows/dependency-scan.yml +++ b/.github/workflows/dependency-scan.yml @@ -1,3 +1,12 @@ +# Dependency Scan — License Compliance +# +# Generates a CycloneDX SBOM via cdxgen and evaluates it against an OPA/Rego +# license policy. This checks for disallowed licenses (e.g. GPL in a +# proprietary SDK) — it does NOT check for CVEs or security vulnerabilities. +# Vulnerability scanning is handled separately by dependency-review-action. +# +# See: SDK-2170, SEC-7263 + name: Dependency Scan on: @@ -12,6 +21,22 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + # The shared generate-sbom action runs cdxgen, which internally invokes + # `yarn install` to resolve the dependency tree. This repo uses Yarn 3.x + # via corepack (packageManager field in package.json), so corepack must + # be enabled before cdxgen runs. Without this, cdxgen falls back to + # system yarn (1.x), fails silently, and produces a 0-component BOM. + - name: Setup Node with corepack + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: 20.x + + - name: Enable corepack + run: corepack enable + + - name: Install dependencies + run: yarn install + - name: Generate SBOM uses: launchdarkly/gh-actions/actions/dependency-scan/generate-sbom@0a54234f88a428df4163234dbb23ddb7fee8b8ec # main with: @@ -28,3 +53,15 @@ jobs: uses: launchdarkly/gh-actions/actions/dependency-scan/evaluate-policy@0a54234f88a428df4163234dbb23ddb7fee8b8ec # main with: artifacts-pattern: bom-* + + # Guard against silent regression: if cdxgen fails to resolve + # dependencies (e.g. corepack not enabled), the BOM will contain + # 0 components and the policy evaluation vacuously passes. + - name: Verify SBOM contains components + run: | + COMPONENT_COUNT=$(jq '.components | length' bom.json) + echo "SBOM contains $COMPONENT_COUNT components" + if [ "$COMPONENT_COUNT" -eq 0 ]; then + echo "::error::SBOM contains 0 components — the scan produced nothing. Check that corepack is enabled and dependencies are installed." + exit 1 + fi From 5f1f98f613a7df28714031bdd7f7bf18ac50bf43 Mon Sep 17 00:00:00 2001 From: Steven Zhang Date: Thu, 16 Apr 2026 16:39:28 -0500 Subject: [PATCH 2/6] fix(ci): disable immutable installs for dependency-scan Yarn Berry auto-enables immutable installs in CI, but this repo gitignores yarn.lock, so the install fails. Match the pattern used in react.yml. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependency-scan.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/dependency-scan.yml b/.github/workflows/dependency-scan.yml index a71a582398..3372519dc9 100644 --- a/.github/workflows/dependency-scan.yml +++ b/.github/workflows/dependency-scan.yml @@ -36,6 +36,8 @@ jobs: - name: Install dependencies run: yarn install + env: + YARN_ENABLE_IMMUTABLE_INSTALLS: 'false' - name: Generate SBOM uses: launchdarkly/gh-actions/actions/dependency-scan/generate-sbom@0a54234f88a428df4163234dbb23ddb7fee8b8ec # main From 5da2de5dccfb1fdf5f1299249cc3a25db8472a6a Mon Sep 17 00:00:00 2001 From: Steven Zhang Date: Fri, 17 Apr 2026 17:53:24 -0500 Subject: [PATCH 3/6] fix(ci): test omit-optional flag to exclude LGPL optional deps from SBOM Point generate-sbom at the skz/ignore-optional branch of gh-actions which adds --omit optional to cdxgen. This should exclude @img/sharp-libvips-* (LGPL-3.0, optional deps of sharp via Next.js) from the SBOM. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependency-scan.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dependency-scan.yml b/.github/workflows/dependency-scan.yml index 3372519dc9..39b0b5808e 100644 --- a/.github/workflows/dependency-scan.yml +++ b/.github/workflows/dependency-scan.yml @@ -43,6 +43,7 @@ jobs: uses: launchdarkly/gh-actions/actions/dependency-scan/generate-sbom@0a54234f88a428df4163234dbb23ddb7fee8b8ec # main with: types: 'nodejs' + omit-optional: 'true' evaluate-policy: runs-on: ubuntu-latest From 4f35f14334a33f3503b1fea4f5872f47bd739891 Mon Sep 17 00:00:00 2001 From: Steven Zhang Date: Fri, 17 Apr 2026 18:12:01 -0500 Subject: [PATCH 4/6] fix(ci): skip platform-specific optional deps to avoid LGPL false positives Revert the omit-optional gh-actions branch (didn't filter transitive optionals). Instead, set YARN_SUPPORTED_ARCHITECTURES to empty arrays so yarn skips all platform-specific optional deps (like @img/sharp-libvips-*) during install. If they're not in node_modules, cdxgen won't pick them up. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependency-scan.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dependency-scan.yml b/.github/workflows/dependency-scan.yml index 39b0b5808e..05237ac684 100644 --- a/.github/workflows/dependency-scan.yml +++ b/.github/workflows/dependency-scan.yml @@ -34,16 +34,16 @@ jobs: - name: Enable corepack run: corepack enable - - name: Install dependencies + - name: Install dependencies (skip platform-specific optionals) run: yarn install env: YARN_ENABLE_IMMUTABLE_INSTALLS: 'false' + YARN_SUPPORTED_ARCHITECTURES: '{"os":[],"cpu":[],"libc":[]}' - name: Generate SBOM uses: launchdarkly/gh-actions/actions/dependency-scan/generate-sbom@0a54234f88a428df4163234dbb23ddb7fee8b8ec # main with: types: 'nodejs' - omit-optional: 'true' evaluate-policy: runs-on: ubuntu-latest From 56a4bbb70b9dc4f6a4c8611951d696ad06eb7a99 Mon Sep 17 00:00:00 2001 From: Steven Zhang Date: Fri, 17 Apr 2026 18:12:38 -0500 Subject: [PATCH 5/6] fix(ci): use yarn config set for supportedArchitectures YARN_SUPPORTED_ARCHITECTURES env var doesn't work as JSON in Yarn 3.4.1. Use yarn config set with --json flag to set each sub-key individually. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependency-scan.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dependency-scan.yml b/.github/workflows/dependency-scan.yml index 05237ac684..1a80c2bc06 100644 --- a/.github/workflows/dependency-scan.yml +++ b/.github/workflows/dependency-scan.yml @@ -35,10 +35,13 @@ jobs: run: corepack enable - name: Install dependencies (skip platform-specific optionals) - run: yarn install + run: | + yarn config set supportedArchitectures.os --json '[]' + yarn config set supportedArchitectures.cpu --json '[]' + yarn config set supportedArchitectures.libc --json '[]' + yarn install env: YARN_ENABLE_IMMUTABLE_INSTALLS: 'false' - YARN_SUPPORTED_ARCHITECTURES: '{"os":[],"cpu":[],"libc":[]}' - name: Generate SBOM uses: launchdarkly/gh-actions/actions/dependency-scan/generate-sbom@0a54234f88a428df4163234dbb23ddb7fee8b8ec # main From d73db9594c74a4b8da7502630fc8314971e3f012 Mon Sep 17 00:00:00 2001 From: Steven Zhang Date: Fri, 17 Apr 2026 21:37:04 -0500 Subject: [PATCH 6/6] fix(ci): scope dependency install to released packages only Use yarn workspaces focus to install only dependencies of released packages (from .release-please-manifest.json). This excludes example apps and contract tests that bring in LGPL transitive deps like @img/sharp-libvips (via Next.js) which don't ship in published SDKs. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/dependency-scan.yml | 40 ++++----------------------- scripts/released-packages.js | 16 +++++++++++ 2 files changed, 22 insertions(+), 34 deletions(-) create mode 100644 scripts/released-packages.js diff --git a/.github/workflows/dependency-scan.yml b/.github/workflows/dependency-scan.yml index 1a80c2bc06..287fb46767 100644 --- a/.github/workflows/dependency-scan.yml +++ b/.github/workflows/dependency-scan.yml @@ -1,12 +1,3 @@ -# Dependency Scan — License Compliance -# -# Generates a CycloneDX SBOM via cdxgen and evaluates it against an OPA/Rego -# license policy. This checks for disallowed licenses (e.g. GPL in a -# proprietary SDK) — it does NOT check for CVEs or security vulnerabilities. -# Vulnerability scanning is handled separately by dependency-review-action. -# -# See: SDK-2170, SEC-7263 - name: Dependency Scan on: @@ -21,32 +12,25 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - # The shared generate-sbom action runs cdxgen, which internally invokes - # `yarn install` to resolve the dependency tree. This repo uses Yarn 3.x - # via corepack (packageManager field in package.json), so corepack must - # be enabled before cdxgen runs. Without this, cdxgen falls back to - # system yarn (1.x), fails silently, and produces a 0-component BOM. - - name: Setup Node with corepack - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + - uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: 20.x - name: Enable corepack run: corepack enable - - name: Install dependencies (skip platform-specific optionals) - run: | - yarn config set supportedArchitectures.os --json '[]' - yarn config set supportedArchitectures.cpu --json '[]' - yarn config set supportedArchitectures.libc --json '[]' - yarn install + - name: Install released package dependencies + run: yarn workspaces focus $(node scripts/released-packages.js) env: YARN_ENABLE_IMMUTABLE_INSTALLS: 'false' + YARN_ENABLE_SCRIPTS: 'false' + ELECTRON_SKIP_BINARY_DOWNLOAD: '1' - name: Generate SBOM uses: launchdarkly/gh-actions/actions/dependency-scan/generate-sbom@0a54234f88a428df4163234dbb23ddb7fee8b8ec # main with: types: 'nodejs' + ensure-non-empty: 'true' evaluate-policy: runs-on: ubuntu-latest @@ -59,15 +43,3 @@ jobs: uses: launchdarkly/gh-actions/actions/dependency-scan/evaluate-policy@0a54234f88a428df4163234dbb23ddb7fee8b8ec # main with: artifacts-pattern: bom-* - - # Guard against silent regression: if cdxgen fails to resolve - # dependencies (e.g. corepack not enabled), the BOM will contain - # 0 components and the policy evaluation vacuously passes. - - name: Verify SBOM contains components - run: | - COMPONENT_COUNT=$(jq '.components | length' bom.json) - echo "SBOM contains $COMPONENT_COUNT components" - if [ "$COMPONENT_COUNT" -eq 0 ]; then - echo "::error::SBOM contains 0 components — the scan produced nothing. Check that corepack is enabled and dependencies are installed." - exit 1 - fi diff --git a/scripts/released-packages.js b/scripts/released-packages.js new file mode 100644 index 0000000000..664b10f788 --- /dev/null +++ b/scripts/released-packages.js @@ -0,0 +1,16 @@ +#!/usr/bin/env node + +/** + * Prints the workspace names of all released packages, one per line. + * Released packages are those listed in .release-please-manifest.json. + */ + +const path = require('path'); + +const repoRoot = path.resolve(__dirname, '..'); +const manifest = require(path.join(repoRoot, '.release-please-manifest.json')); + +for (const pkgPath of Object.keys(manifest)) { + const { name } = require(path.join(repoRoot, pkgPath, 'package.json')); + console.log(name); +}