Skip to content

feat(sbom): scope catalogers + add optional GitHub Actions scan#30

Merged
hoobio merged 5 commits into
mainfrom
feat/sbom-clean-scoping
May 23, 2026
Merged

feat(sbom): scope catalogers + add optional GitHub Actions scan#30
hoobio merged 5 commits into
mainfrom
feat/sbom-clean-scoping

Conversation

@hoobio

@hoobio hoobio commented May 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Image scan drops the github-actions catalogers so transitive uses: refs scraped from upstream packages' bundled .github/workflows/*.yml (e.g. node_modules/@fastify/*) stop leaking into the container BOM.
  • Invoke-SyftDirScan accepts a catalogers override; the bun/pnpm lockfile path pins to javascript-lock-cataloger so the scan reads just the lockfile and doesn't walk node_modules, .github, or dist.
  • New optional ScanGithubActionsPath / scan-github-actions-path / scanGithubActionsPath input: scans the consumer's own workflows directory with only the github-actions catalogers and merges the result. The image scan no longer covers this, so consumers wanting GitHub Actions in their BOM must set this input explicitly.
  • pnpm-lock.yaml is now detected alongside bun.lock and routes through the same lockfile-only syft path. A warning fires for bun.lock because syft v1.x can't parse it; affected consumers should migrate to pnpm for accurate node-package coverage.

Test plan

  • PSScriptAnalyzer clean on scripts/
  • YAML parse passes for the GitHub action.yml and ADO step template
  • Local syft scan of .github/workflows with the two github-actions catalogers returns just the actions referenced from our workflows (validated against hoobi-portfolio)
  • Local syft scan with javascript-lock-cataloger reads a synthetic pnpm-lock.yaml
  • hoobi-portfolio CI consumes this branch end-to-end and produces a clean SBOM

hoobio added 5 commits May 23, 2026 23:11
- Image scan: drop github-actions catalogers (removes transitive `uses:`
  refs scraped from upstream packages' bundled .github/workflows/*).
- Dir scan (Invoke-SyftDirScan): accept a Catalogers override; lockfile
  scans pin to javascript-lock-cataloger so they don't walk node_modules,
  .github, or dist.
- Node lang: detect pnpm-lock.yaml in addition to bun.lock and route to
  the same lockfile-only path. Warn when bun.lock is detected because
  syft v1.x can't parse it.
- New input ScanGithubActionsPath / scan-github-actions-path / scanGithubActionsPath:
  optional, opt-in scan of the consumer's own workflows folder restricted
  to the github-actions catalogers. Merged into the final BOM.
…s deploy tree

When Invoke-NodeScan's AppManifestPath has no recognised lockfile
(bun.lock / pnpm-lock.yaml / package-lock.json / yarn.lock) but does
have a node_modules directory, route to syft with
javascript-package-cataloger. That reads each node_modules/<pkg>/
package.json so the BOM reflects exactly what's installed.

Pairs naturally with `pnpm deploy --prod <target>`, which writes the
prod-only tree (no lockfile in the target) and is the right input for
an in-image SBOM that mirrors what ships to production.
cyclonedx-cli's merge output only reports the first input's component
count and the merged total, so per-input regressions (e.g. an empty
github-actions BOM) hide in plain sight. Log each input's count
ourselves before invoking the merge.
…ns cataloger

syft's `github-actions-usage-cataloger` and
`github-action-workflow-usage-cataloger` only match files whose path
contains `.github/workflows/`. When the script mounted the consumer's
workflows directory at `/work` directly, the in-container files looked
like `/work/ci.yml` and the catalogers silently produced a 0-component
BOM. Mount the source at `/work/.github/workflows` instead and scan
`dir:/work` so the heuristic fires.

Verified locally: a flat-dir scan returns 0 components; nesting under
.github/workflows/ returns the expected 22 against hoobi-portfolio's
CI workflows.
…uplicate component

When CycloneDX output is selected, syft auto-adds the `file` tag to the
default cataloger selection. The file-content/-digest/-metadata
catalogers then emit a `type: file` component for each
node_modules/<pkg>/package.json next to the proper
`pkg:npm/<pkg>@<ver>` library entry from the package cataloger.
Visible duplicate in the consumer's UI (zod@4.4.3 listed twice).

Pass `--select-catalogers -file` (additive negative on top of
`--override-default-catalogers`) on both the image scan and the
directory scan to drop the file tag entirely. Image scan also already
strips github-actions-usage-cataloger and github-action-workflow-usage-cataloger
to keep transitive workflow refs out.
@hoobio hoobio merged commit 7fa1923 into main May 23, 2026
3 checks passed
@hoobio hoobio deleted the feat/sbom-clean-scoping branch May 23, 2026 14:31
hoobio pushed a commit that referenced this pull request May 23, 2026
Auto-generated by
[release-please](https://github.com/googleapis/release-please).
---


##
[2.3.0](v2.2.1...v2.3.0)
(2026-05-23)


### Features

* **sbom:** scope catalogers + add optional GitHub Actions scan
([#30](#30))
([7fa1923](7fa1923))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: release-please-hoobi[bot] <279189756+release-please-hoobi[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant