Three posts of why. This one is how. By the end you have SBOMs and an AI-BOM generated on every push, a build that blocks when a critical CVE shows up, and a formatted summary posted right on the pull request.
Start local, then automate
Before the Action, run it once by hand so you know what the output looks like.
npx sbomix owner/repo
It clones the repo, reads your lockfiles and manifests, and writes three files in a couple of seconds:
bom.cyclonedx.json— CycloneDX 1.6, the format enterprise security teams and regulators ask forbom.spdx.json— SPDX 2.3, NTIA minimum elements, accepted by GitHub's dependency graphaibom.json— written only when AI frameworks turn up
No flags to get all three. Vulnerability enrichment runs inline against OSV while it scans, so the CVE data lands in the same pass.
The one-Action setup
Drop the SBOMix Action into any workflow. Here is the shape of it.
name: SBOM
on: [push, pull_request]
jobs:
sbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: RunTimeAdmin/sbomix@v1
with:
fail-on-critical: true
api-url: ${{ vars.SBOMIX_API_URL }}
api-key: ${{ secrets.SBOMIX_API_KEY }}
That does four things on every push:
- Scans the repo and writes the SBOM and AI-BOM artifacts
- Blocks the build if a critical CVE is found, because
fail-on-critical: trueis set - Posts a formatted SBOM summary as a comment on the pull request
- Pushes results to the hosted dashboard, because
api-keyis set from your repo secrets
Drop the api-url/api-key lines and it still scans and gates. It just keeps everything local instead of pushing to a dashboard. Your call.
The gate is the point
A vulnerability report nobody reads is decoration. The reason to put this in CI is the gate, not the file.
fail-on-critical: true means a critical CVE turns the build red before the code reaches a human reviewer. That is the shift-left everyone talks about, made concrete. The CVE was always going to surface in a security review eventually. The Action surfaces it at the pull request, when the fix is a one-line dependency bump instead of a release-blocking incident.
Set the floor where your team can live with it. Critical only, to start.
On speed, with the real numbers
A CI step that adds a minute to every push gets ripped out within a week. So speed is not a vanity metric here. It decides whether the thing survives.
SBOMix reads lockfiles instead of re-resolving the whole dependency tree, so scan time scales with dependency count, not codebase size. Two repos, run against Syft and Trivy via Docker:
| Repository | SBOMix | Syft | Trivy |
|---|---|---|---|
| nestjs/nest (npm, 2,366 components) | 463ms | 27.7s | 86.6s |
| BurntSushi/ripgrep (Rust, 82 components) | 268ms | 11.8s | 15.4s |
Syft and Trivy add a few seconds of Docker startup here; native installs narrow the gap, but reading a resolved lock file directly is still an order of magnitude faster than walking the filesystem. Run npm run bench on your own repo before you trust our table. That is the whole reason the CLI is free.
What this means for you
Ten minutes of setup buys you SBOMs and an AI-BOM on every push, a CVE gate at the pull request, and a dashboard that remembers. No documentation sprint. No manual inventory. The evidence builds itself while you ship.
Set SBOMIX_API_KEY in your repository secrets, add the Action, and watch the first PR comment land. Grab your key from the dashboard.
Last post: why the core is open source, when the free CLI is enough, and what the paid tiers actually add. The trust question, answered straight.