SBOM + License Scanner¶
Availability: all tiers (Community, Pro, Enterprise) · Tenant-scoped
See the Tier & Scope Matrix for the current catalog structure.
The SBOM + License Scanner (scanner-sbom) is an ephemeral codebase sub-scanner that generates a Software Bill of Materials from source code, matches packages against vulnerability databases, and checks license compliance. It is the 5th codebase sub-scanner alongside secrets, IaC, SAST, and dependencies.
Image: ghcr.io/virtual-sutra/scanner-sbom Spawner: CodebaseCoordinator (codebase sub-scanner - not dispatched directly by the orchestrator) Source agent: CODEBASE_ANALYZER
How it fits in the codebase scanning model¶
When SCANNER_SPAWNER_ENABLED=true and a repository has enable_sbom: true, the CodebaseCoordinator spawns scanner-sbom alongside the other 4 ephemeral scanners. All scanners share the same cloned repository - no redundant cloning.
CodebaseAnalyzerAgent
│
└─► CodebaseCoordinator
│ (clones repo once — initContainer in K8s, coordinator in Docker)
│
├── scanner-secrets (always)
├── scanner-iac (always)
├── scanner-sast (always)
├── scanner-deps (always)
└── scanner-sbom (when enable_sbom: true)
Kubernetes (G1 mode - default)¶
In Kubernetes the coordinator runs as an initContainer (COORDINATOR_MODE=init) inside a single Job Pod per repository. It clones the repo into an emptyDir volume, writes a sentinel file when done, then exits. The scanner containers start in the same Pod, wait for the sentinel (controlled by CLONE_READY_TIMEOUT_SECONDS), and scan from the shared emptyDir. No ReadWriteMany (RWX) PVC is required.
Docker Compose¶
In Docker Compose mode the coordinator and each scanner run as separate containers with a named Docker volume at CLONE_ROOT (default /tmp/vsutra-repos). The coordinator clones the repo into the volume first; scanners mount it read-only. This legacy per-container model is unchanged by G1.
Tools¶
| Tool | Purpose |
|---|---|
| Syft | CycloneDX SBOM generation from package manifests |
| Grype | Vulnerability matching against the SBOM |
| Custom license checker | SPDX license compliance against configurable blocklist |
Configuration¶
Enable SBOM scanning per repository in inspection.json. The sbom_license_blocklist can be set at the scope level (applies to all repos) or overridden per repository.
{
"scope": {
"sbom_license_blocklist": ["GPL-3.0", "AGPL-3.0"],
"repositories": [
{
"platform": "github",
"token_ref": "env://GITHUB_TOKEN",
"org_or_owner": "my-org",
"repos": ["my-app", "my-service"],
"enable_sbom": true,
"sbom_license_blocklist": ["GPL-3.0", "AGPL-3.0", "SSPL-1.0"]
}
]
}
}
Configuration fields¶
| Field | Level | Default | Description |
|---|---|---|---|
enable_sbom | RepositoryCredentials | false | Activate scanner-sbom for this repo group |
sbom_license_blocklist | RepositoryCredentials | [] | SPDX license IDs that produce findings; overrides scope-level list |
sbom_license_blocklist | InspectionScope | [] | Default blocklist applied to all repos that don't override it |
Supported package ecosystems¶
| Ecosystem | Detected from |
|---|---|
package:npm | package.json, package-lock.json, yarn.lock |
package:pip | requirements*.txt, Pipfile, setup.py, pyproject.toml |
package:go | go.mod, go.sum |
package:java | pom.xml, *.jar, *.war, *.ear, build.gradle |
package:ruby | Gemfile, Gemfile.lock |
package:rust | Cargo.toml, Cargo.lock |
package:dotnet | *.csproj, packages.config, *.nuspec |
package:php | composer.json, composer.lock |
Findings Schema¶
All findings have source_agent = CODEBASE_ANALYZER and tags["scanner"] = "sbom".
Vulnerability findings (Grype)¶
| Field | Value |
|---|---|
resource_type | package:{ecosystem} (e.g. package:npm, package:pip) |
severity | Derived from Grype CVSS score (critical/high/medium/low) |
tags.cve_id | CVE identifier (e.g. CVE-2024-12345) |
tags.package | Package name and version (e.g. lodash@4.17.15) |
tags.fixed_version | Version that resolves the CVE (when available) |
tags.scanner | "sbom" |
License violation findings¶
| Field | Value |
|---|---|
resource_type | package:{ecosystem} |
severity | medium |
tags.license | SPDX license identifier (e.g. GPL-3.0, AGPL-3.0) |
tags.package | Package name and version |
tags.scanner | "sbom" |
title | "Blocked license in {package}: {license}" |
Environment Variables¶
| Variable | Default | Description |
|---|---|---|
REDIS_URL | required | Redis connection URL |
CLONE_ROOT | /tmp/vsutra-repos | Path where the coordinator cloned the repo (read-only mount) |
LOG_LEVEL | INFO | Logging level |
SPDX license identifier reference¶
Common licenses to include in a blocklist:
| SPDX ID | License |
|---|---|
GPL-2.0 | GNU General Public License v2 |
GPL-3.0 | GNU General Public License v3 |
AGPL-3.0 | GNU Affero GPL v3 (strongest copyleft - common SaaS risk) |
LGPL-2.1 | GNU Lesser GPL v2.1 |
LGPL-3.0 | GNU Lesser GPL v3 |
SSPL-1.0 | Server Side Public License (MongoDB) |
BUSL-1.1 | Business Source License 1.1 (HashiCorp) |
CC-BY-SA-4.0 | Creative Commons Share-Alike 4.0 |
For a full list see spdx.org/licenses.