Skip to main content
Commands

vg sbom

Export CycloneDX or SPDX SBOMs, compare dependency deltas, and generate OpenVEX documents.

Overview

The vg sbom command family provides supply-chain evidence — Software Bill of Materials (SBOM) export, dependency deltas, and OpenVEX exploitability statements — for compliance, audit, and supply chain security workflows.

Three commands: sbom export generates SBOMs, sbom delta compares dependency changes, and sbom vex produces OpenVEX documents.


Usage

# Export SBOM from scan artifact
vg sbom export [options]

# Compare dependencies between two scans
vg sbom delta --from <file> --to <file> [options]

# Generate an OpenVEX document
vg sbom vex [options]

sbom export

Options

FlagDefaultDescription
--in <file>.vibgrate/scan_result.jsonInput scan artifact
--format <type>cyclonedxSBOM format: cyclonedx, spdx
--out <file>stdoutOutput file path

Supported Formats

FormatSpecificationFile Extension
🟢 CycloneDXcyclonedx.org.cdx.json
🔵 SPDXspdx.dev.spdx.json

Examples

# Export CycloneDX SBOM
vg sbom export --format cyclonedx --out sbom.cdx.json

# Export SPDX SBOM
vg sbom export --format spdx --out sbom.spdx.json

# Export from specific artifact
vg sbom export --in ./archive/scan-q1.json --out sbom-q1.cdx.json

Component identity

Match a component on its package URL (purl). That string is the primary identity in vg sbom export. vg scan --format json and .vibgrate/scan_result.json use the same coordinates and do not repeat the purl string.

OutputFields to key on
CycloneDXcomponents[].purl. bom-ref is that purl when the purl was written.
SPDXpackages[].externalRefs[] with referenceType purl. The value is referenceLocator.
Scan JSON, inventoryprojects[].type, projects[].dependencies[].package, projects[].dependencies[].resolvedVersion.
Scan JSON, advisory matchextended.vulnerabilities.packages[].ecosystem, .package, and .version.

projects[].type is the project kind (java, node, python). The vulnerability block uses the advisory ecosystem (maven, npm, pypi). vg sbom export turns those coordinates into the purl type (pkg:maven, pkg:npm, pkg:pypi).

These documents have no CPE field. The CLI does not write one, including when a name has several segments (a Maven group:artifact, an npm scope, a Go module path). A missing CPE is the normal record. Leave it missing. If a file from another cataloger carries a cpe property, keep the purl as the identity you match. A CPE does not replace a purl, rank above it, or stand in for a purl that was omitted.

When a name cannot be a package URL, the component stays in the SBOM and purl is omitted. CycloneDX sets vibgrate:purlStatus to unavailable. That row still has no CPE.

Local advisory matching uses the same coordinates. vg scan --vulns --offline --package-manifest package-versions.json reads vulns under the ecosystem and the package name in that file. Matches land on extended.vulnerabilities.packages[]. Join an advisory of your own on the purl, or on ecosystem + package name + version.

vg scan --vulns --offline --package-manifest package-versions.json --format json --out scan.json
vg sbom export --in scan.json --format cyclonedx --out sbom.cdx.json

For com.google.code.gson:gson at 2.11.0 in a Java project, read these fields. They are shown together so the join is visible. vg writes them in scan.json and sbom.cdx.json, not in one object. The advisory object is present when --vulns records a match for that package.

{
  "scanDependency": {
    "projectType": "java",
    "package": "com.google.code.gson:gson",
    "resolvedVersion": "2.11.0"
  },
  "scanAdvisory": {
    "ecosystem": "maven",
    "package": "com.google.code.gson:gson",
    "version": "2.11.0"
  },
  "cyclonedx": {
    "name": "com.google.code.gson:gson",
    "version": "2.11.0",
    "purl": "pkg:maven/com.google.code.gson/gson@2.11.0",
    "bom-ref": "pkg:maven/com.google.code.gson/gson@2.11.0"
  }
}

Key the join on pkg:maven/com.google.code.gson/gson@2.11.0, or on maven + com.google.code.gson:gson + 2.11.0. The group com.google.code.gson is the purl namespace. SPDX stores the same purl on externalRefs[].referenceLocator.


sbom delta

Options

FlagRequiredDescription
--from <file>✅First (older) scan artifact
--to <file>✅Second (newer) scan artifact
--out <file>—Output file path

Example

vg sbom delta \
  --from .vibgrate/baseline.json \
  --to .vibgrate/scan_result.json \
  --out dependency-changes.json

Delta Output

{
  "summary": {
    "added": 5,
    "removed": 2,
    "changed": 12,
    "driftDelta": -8
  },
  "changes": [
    {
      "package": "lodash",
      "type": "upgraded",
      "from": "4.17.19",
      "to": "4.17.21"
    },
    {
      "package": "moment",
      "type": "removed",
      "note": "Replaced with date-fns"
    }
  ]
}

sbom vex

Generate a spec-compliant OpenVEX document stating the exploitability of components, ready to attach as a signed attestation. The generator is input-agnostic — it assembles a complete document from the statements you supply, so it works regardless of which scanner flagged the components. A zero-statement document is valid and honest: it asserts no known affected components.

Options

FlagDefaultDescription
--from <file>—Read statements from a JSON file (array, or an object with a statements array)
--statement <json>—Add a statement as inline JSON (repeatable)
--product <ref>—Default product for statements without their own (e.g. an image digest)
--author <name>VibgrateDocument author
--timestamp <iso> / --id <uri>—Pin for reproducible output
--out <file>stdoutOutput file path

Example

# Generate VEX and attest it to a signed image
vg sbom vex --product "$IMAGE_REF" \
  --statement '{"vulnerability":"CVE-2024-1","status":"not_affected","justification":"vulnerable_code_not_present"}' \
  --out openvex.json
cosign attest --yes --type openvex --predicate openvex.json "$IMAGE_REF"

Use Cases

Use CaseCommandOutput
📋 Compliancesbom export --format cyclonedxProcurement/regulatory submissions
🔍 Auditsbom delta --from baseline --to currentTrack changes between releases
🛡️ Supply Chainsbom export --format spdxFeed to Dependency-Track, Grype
📝 Change Managementsbom deltaReview before merging upgrade PRs
✅ Exploitabilitysbom vex --product <ref>OpenVEX attestation alongside the SBOM

Integrations

Dependency-Track

# Export and upload to Dependency-Track
vg sbom export --format cyclonedx --out sbom.cdx.json
curl -X POST "https://dtrack.example.com/api/v1/bom" \
  -H "X-Api-Key: $DTRACK_API_KEY" \
  -F "bom=@sbom.cdx.json"

Grype Vulnerability Scanning

# Export and scan with Grype
vg sbom export --format spdx --out sbom.spdx.json
grype sbom:sbom.spdx.json

Related Commands

Example use cases

Expand any use case to watch a live replay of the real @vibgrate/cli running against one of our test repositories. Nothing executes in your browser — these are recordings of actual runs, with the scan time shown as of now.

vg sbom export --format cyclonedx --out sbom.cdx.json

Related Documentation

Related Help Articles

Vibgrate CLI

See a real scan run

A replay of the actual CLI running against our test repositories — live progress, real findings, a genuine DriftScore. Nothing executes in your browser.

Replay
demo@vibgrate — bash
❯ npx @vibgrate/cli scan
 
╭──────────────────────────────────────────╮
│ Vibgrate Drift Report │
╰──────────────────────────────────────────╯
 
── node-turborepo (node) .
Runtime: >=18.0.0 (6 majors behind)
Frameworks:
Turbo: 1.13.4 → 2.11.7 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
1 current 1 1-behind 3 2+ behind 1 unknown
 
── @repo/admin (node) apps/admin
Frameworks:
TanStack Query: 5.104.1 → 5.104.1 (current)
React: 18.3.1 → 19.3.0 (1 behind)
React DOM: 18.3.1 → 19.3.0 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vite: 5.4.21 → 8.3.3 (3 behind)
Dependencies:
3 current 9 1-behind 3 2+ behind 4 unknown
 
── @repo/api (node) apps/api
Frameworks:
Express: 4.22.3 → 5.2.1 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vitest: 1.6.1 → 5.0.3 (4 behind)
Dependencies:
7 current 4 1-behind 4 2+ behind 4 unknown
 
── @repo/web (node) apps/web
Frameworks:
Next.js: 14.2.35 → 16.4.0 (2 behind)
React: 18.3.1 → 19.3.0 (1 behind)
React DOM: 18.3.1 → 19.3.0 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
2 current 6 1-behind 3 2+ behind 5 unknown
 
── @repo/config (node) packages/config
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
2 current 2 1-behind 5 2+ behind 0 unknown
 
── @repo/database (node) packages/database
Frameworks:
Prisma: 5.22.0 → 7.10.0 (2 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
1 current 0 1-behind 3 2+ behind 1 unknown
 
── @repo/types (node) packages/types
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
0 current 0 1-behind 1 2+ behind 1 unknown
 
── @repo/ui (node) packages/ui
Frameworks:
React: 18.3.1 → 19.3.0 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
React: 18.3.1 → 19.3.0 (1 behind)
Dependencies:
1 current 4 1-behind 1 2+ behind 1 unknown
 
── @repo/utils (node) packages/utils
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vitest: 1.6.1 → 5.0.3 (4 behind)
Dependencies:
0 current 1 1-behind 2 2+ behind 1 unknown
 
Tech Stack
Frontend: React, React DOM
Meta-frameworks: Next.js
Bundlers: tsx, Turbo, Vite
CSS / UI: Autoprefixer, PostCSS, Tailwind CSS
Backend: Express
ORM / Database: Prisma, Prisma Client
Testing: Vitest
Lint & Format: ESLint, ESLint Prettier, ESLint React, Prettier, typescript-eslint
 
Services & Integrations
Auth: JWT 9.0.3
Databases: Prisma 5.22.0
 
TypeScript
v5.3.3 · strict ✔ · MIXED · target: ES2022
 
Build & Deploy
Package Managers: pnpm
Monorepo: npm-workspaces, pnpm-workspaces, turbo
 
Product Purpose Signals
Frameworks: react, nextjs
Evidence: 177
Top Signals:
- [heading] Dashboard (apps/admin/src/pages/Dashboard.tsx)
- [title] Revenue Overview (apps/admin/src/pages/Dashboard.tsx)
- [copy] workspace:* (packages/ui/package.json)
- [copy] ./dist (packages/ui/tsconfig.json)
- [copy] ./src/index.ts (packages/ui/package.json)
- [copy] @repo/config/tsconfig-base.json (packages/ui/tsconfig.json)
- [copy] @repo/ui (packages/ui/package.json)
- [copy] #3b82f6 (apps/admin/src/pages/Dashboard.tsx)
Unknowns:
- No pricing or billing evidence found.
- No integrations/connectors evidence found.
- No route structure evidence found.
 
Security Posture
Lockfile ✖ · .env ✔ · node_modules ✔
 
Platform
Native modules: turbo
 
Code Quality
Files: 36 · Functions: 183 · Avg complexity: 2.62 · Avg length: 21.13 lines
Max nesting: 2 · Circular deps: 0 · Dead code: 0%
God files: apps/admin/src/pages/Products (448 lines)
 
Database Schema
postgresql · 8 models · 1 enum
Models: Address, CartItem, Category, Order, OrderItem (+3 more)
 
Findings (16 errors, 11 warnings)
✖ Node.js runtime ">=18.0.0" reached end-of-life on 2025-04-30 (latest: 24.0.0).
vibgrate/runtime-eol in .
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in .
✖ 60% of dependencies are 2+ major versions behind in node-turborepo.
vibgrate/dependency-rot in .
✖ @types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.6.4).
vibgrate/dependency-major-lag in .
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/admin
✖ Vite is 3 major versions behind (current: 5.4.21, latest: 8.3.3).
vibgrate/framework-major-lag in apps/admin
✖ vite is 3 major versions behind (spec: ^5.0.12, latest: 8.3.3).
vibgrate/dependency-major-lag in apps/admin
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/api
✖ Vitest is 4 major versions behind (current: 1.6.1, latest: 5.0.3).
vibgrate/framework-major-lag in apps/api
✖ @types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.6.4).
vibgrate/dependency-major-lag in apps/api
✖ vitest is 4 major versions behind (spec: ^1.2.1, latest: 5.0.3).
vibgrate/dependency-major-lag in apps/api
⚠ Next.js is 2 major versions behind (current: 14.2.35, latest: 16.4.0).
vibgrate/framework-major-lag in apps/web
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/web
✖ @types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.6.4).
vibgrate/dependency-major-lag in apps/web
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/config
✖ 56% of dependencies are 2+ major versions behind in @repo/config.
vibgrate/dependency-rot in packages/config
✖ eslint-plugin-react-hooks is 3 major versions behind (spec: ^4.6.0, latest: 7.1.1).
vibgrate/dependency-major-lag in packages/config
⚠ Prisma is 2 major versions behind (current: 5.22.0, latest: 7.10.0).
vibgrate/framework-major-lag in packages/database
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/database
✖ 75% of dependencies are 2+ major versions behind in @repo/database.
vibgrate/dependency-rot in packages/database
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/types
✖ 100% of dependencies are 2+ major versions behind in @repo/types.
vibgrate/dependency-rot in packages/types
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/ui
⚠ TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/utils
✖ Vitest is 4 major versions behind (current: 1.6.1, latest: 5.0.3).
vibgrate/framework-major-lag in packages/utils
✖ 67% of dependencies are 2+ major versions behind in @repo/utils.
vibgrate/dependency-rot in packages/utils
✖ vitest is 4 major versions behind (spec: ^1.2.1, latest: 5.0.3).
vibgrate/dependency-major-lag in packages/utils
 
╭──────────────────────────────────────────╮
│ Top Priority Actions │
╰──────────────────────────────────────────╯
 
1. Upgrade EOL runtime in node-turborepo
End-of-life runtimes no longer receive security patches and block ecosystem upgrades.
./.
>=18.0.0 → 24.0.0 (6 majors behind)
Impact: −10 drift points (runtime & EOL)
 
2. Fix security posture: no lockfile found
Without a lockfile, installs are non-deterministic. Run the install command to generate one and commit it.
./
Missing: package-lock.json, pnpm-lock.yaml, or yarn.lock
 
3. Upgrade Vitest 1.6.1 → 5.0.3 in @repo/api (+2 more)
4 major versions behind. Major framework drift increases breaking change risk and blocks access to security fixes and performance improvements.
./apps/api
Vitest: 1.6.1 → 5.0.3 (4 majors behind)
./packages/utils
Vitest: 1.6.1 → 5.0.3 (4 majors behind)
./apps/admin
Vite: 5.4.21 → 8.3.3 (3 majors behind)
Impact: −5–15 drift points
 
4. Reduce dependency rot in @repo/types (100% severely outdated)
1 of 1 dependencies are 2+ majors behind. Run `npm outdated` and prioritise packages with known CVEs or breaking API changes.
./packages/types
typescript: 5.9.3 → 7.0.2 (2 majors behind)
Impact: −5–10 drift points
 
5. Reduce dependency rot in @repo/database (75% severely outdated)
3 of 4 dependencies are 2+ majors behind. Run `npm outdated` and prioritise packages with known CVEs or breaking API changes.
./packages/database
@prisma/client: 5.22.0 → 7.10.0 (2 majors behind)
prisma: 5.22.0 → 7.10.0 (2 majors behind)
typescript: 5.9.3 → 7.0.2 (2 majors behind)
Impact: −5–10 drift points
 
╭──────────────────────────────────────────╮
│ Architecture Layers │
╰──────────────────────────────────────────╯
 
Archetype: nextjs (80% confidence)
Files classified: 24 (11 unclassified)
Folders classified: 8
apps/admin/src presentation 100% 4 files
apps/admin/src/pages presentation 100% 2 files
apps/api/src/middleware middleware 100% 2 files
apps/api/src/routes routing 100% 2 files
apps/web/src/app presentation 100% 4 files
apps/web/src/app/products presentation 100% 2 files
apps/web/src/app/products/[id] presentation 100% 1 file
packages/ui/src presentation 100% 6 files
Unclassified source (sample): 11
 
presentation 15 files drift ████████████████████ 100 risk high
routing 4 files drift ████████████████████ 100 risk high
middleware 2 files drift ███████▍░░░░░░░░░░░░ 37 risk moderate
config 2 files drift ░░░░░░░░░░░░░░░░░░░░ 0 risk none
shared 1 file drift ████████████████████ 100 risk high
 
╭──────────────────────────────────────────╮
│ DriftScore Summary │
╰──────────────────────────────────────────╯
 
DriftScore: 70/100
Risk Level: HIGH
Projects: 9
Classified: 8 nano · 1 micro · 0 small · 0 standard
Billable: 0.42 · 9 detected → 0.42 billable projects (micro-project pricing)
0.1 micro · 0.32 nano
These fractions add up across repositories, then round down to whole billable projects.
 
Score Breakdown
Runtime: ████████████████████ 100
Frameworks: ███████████▊░░░░░░░░ 59
Dependencies: ██████▌░░░░░░░░░░░░░ 33
EOL Risk: ████████████████████ 100
 
Scanned at 2026-10-07T12:34:03.236Z · 6.6s · 286 files scanned · 56 workspace files · 27 dirs
❯
Press Run to start.