Skip to content

Generate notice, security & risk reports

Beyond SBOM generation, BomLens produces an open-source notice (NOTICE) and a security vulnerability report in one run. This page covers how to generate those outputs. For how to read and interpret them, see What the reports mean.

Quick start (5 minutes)

If this is your first time, this is all you need. With the Docker engine running, generate the SBOM, notice, and security report in one run — from the browser or the CLI.

Browser UI (no command line)

Launch the UI, then enter a project name and version, pick a scan target, run, and download the notice and security report.

./scripts/scan-sbom.sh --ui     # opens http://localhost:8080 (port taken? UI_PORT=9090 ./scripts/scan-sbom.sh --ui)
#   Windows: double-click scripts\sbom-ui.bat

CLI

From the project folder you want to scan:

cd /path/to/your-project
/path/to/bomlens/scripts/scan-sbom.sh --project MyApp --version 1.0.0 --all --generate-only

On Windows, use scripts\scan-sbom.bat (Git Bash) or run as-is under WSL2. Installation is in Getting started.

When it finishes, open MyApp_1.0.0_NOTICE.html and MyApp_1.0.0_security.html in the same folder to check the results right away. See below for the detailed options.


Prerequisites

  • Docker engine 20.10+ (free: WSL2 + docker-ce, or Rancher Desktop / Docker Desktop, which is paid for organizational use)
  • Pull the scanner image:
    docker pull ghcr.io/sktelecom/bomlens:latest   # the former name sbom-scanner is the same image
    
  • Run every example from the root of the project to scan.

Output flags are best used together with --generate-only (save locally). Omit it to also auto-upload to an external system (a Dependency-Track server or TRUSCA); pick the target with UPLOAD_TARGET.


Generate everything at once (--all)

--all is shorthand for --notice --security --spdx. It produces the SBOM, the notice, the security report, and an SPDX copy of the SBOM in a single scan.

In the web UI and the desktop app the notice and the security report are generation options on the New scan screen, and the SPDX copy is exported from the results screen once the scan is done.

./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --all --generate-only

Generated files:

MyApp_1.0.0_bom.json            # SBOM (CycloneDX 1.6)
MyApp_1.0.0_NOTICE.txt          # notice (text)
MyApp_1.0.0_NOTICE.html         # notice (HTML)
MyApp_1.0.0_security.json       # security report (raw Trivy)
MyApp_1.0.0_security.md         # security report (summary)
MyApp_1.0.0_security.html       # security report (visual)
MyApp_1.0.0_risk-report.md      # open-source risk report (summary)
MyApp_1.0.0_risk-report.html    # open-source risk report (visual)

The open-source risk report (_risk-report) is generated by default in every analysis mode (license + vulnerability tally, with response deadlines). To skip it, use --no-report. For handling each of the six input forms, see the Scenarios guide.

For the full list of artifact kinds, see the artifacts reference; to generate them from a browser, see the web UI.


Open-source notice (--notice)

Gathers the components[].licenses information from the SBOM and generates a notice that groups components by license.

./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --notice --generate-only
  • _NOTICE.txt — standard text, good to ship with the distribution.
  • _NOTICE.html — a browser-friendly format. All package metadata is HTML-escaped and safe.
  • Components with no license information are classified as NOASSERTION.

For license normalization and full-text bundling behavior, see What the reports mean.

Example (text):

License: Apache-2.0
Components (1):
  - requests@2.31


Security vulnerability report (--security)

Scans the generated SBOM with Trivy and reports known vulnerabilities (CVEs). (NVD + OSV + GHSA DB)

./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --security --generate-only
  • _security.json — raw Trivy JSON. For CI or machine processing.
  • _security.md — a per-severity tally table and CVE list. Good to attach to a PR or issue.
  • _security.html — a visual report with severity badges and tables.

The report does not fail the scan even when vulnerabilities exist (report-only). If you need a gate, post-process _security.json.

For severity, CVSS, EPSS, and KEV priority signals and follow-up interpretation, see What the reports mean.


Deep CVE matching (--deep-cve)

Trivy matches vulnerabilities by package identity (PURL), which covers the ecosystem advisory databases well. Some CVEs in older Java libraries, however, are recorded only in the NVD against a CPE identifier, so a PURL-based scan never reaches them. --deep-cve adds a second pass for Maven components: BomLens derives an NVD-matchable CPE for each component from its groupId, and grype matches those CPEs against a bundled NVD database.

./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --deep-cve --generate-only
  • --deep-cve implies --security. The extra findings merge into the same security report (_security.json/.md/.html), tagged with their nvd:cpe source.
  • The scan runs on the opt-in ghcr.io/sktelecom/bomlens-deep-cve:latest image, which bundles grype and its database; it is pulled automatically when the flag is set (override with SBOM_DEEP_CVE_IMAGE). The flag applies to the base-image modes (source, image, binary, rootfs, SBOM analysis); a firmware or AI-model scan prints a warning and runs without grype.
  • CPE matching is looser than PURL matching, because NVD version ranges can be recorded coarsely. By default the scan stays offline: such findings are kept and marked version-unverified in the report (a dagger with a footnote), so a reader knows which rows may be loose-version false positives. To tighten them, set SECURITY_NVD_VERIFY=true with an NVD_API_KEY: each finding is then checked against the live NVD version range and out-of-range false positives are dropped. The verification needs network access and adds minutes.
SECURITY_NVD_VERIFY=true NVD_API_KEY="your-key" \
  ./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --deep-cve --generate-only

Deep license detection (--deep-license)

The basic notice covers the licenses of dependencies (third-party). --deep-license uses scancode-toolkit to also detect license headers in the project's own source code (first-party).

./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --notice --deep-license --generate-only

In the web UI, deep license detection is one of the Generation options. Either way it relies on scancode, which is heavy and slow (minutes to tens of minutes for a large repo) and is not in the base image. To use it, run from an image that bundles scancode:

docker build --build-arg SBOM_DEEP_LICENSE=true -t bomlens:deep ./docker
# CLI:    SBOM_SCANNER_IMAGE=bomlens:deep ./scripts/scan-sbom.sh ... --deep-license
# Web UI: SBOM_SCANNER_IMAGE=bomlens:deep ./scripts/scan-sbom.sh --ui

Additional output: MyApp_1.0.0_scancode.json


Outbound-license conflicts (--license)

Declares the license you distribute under, so each dependency can be judged against it. A source scan cannot infer this — cdxgen leaves the root license empty for maven and gradle trees — so without the flag no verdict is produced.

./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --license Apache-2.0 --all --generate-only

The value is recorded on the SBOM's root component, and the risk report gains a conflict section. An existing root license — a supplier SBOM's own declaration — is never replaced. For how to read the verdicts see What the reports mean.


Deterministic output (--byte-stable)

Produces a byte-identical SBOM for the same input. It removes meaningless diffs in CI (timestamps, random IDs, ordering differences) and ensures reproducibility.

./scripts/scan-sbom.sh --project "MyApp" --version "1.0.0" --byte-stable --generate-only

What it does: fixes metadata.timestamp to 1970-01-01T00:00:00Z, removes the random serialNumber, sorts components by purl, and sorts keys.


SBOM signing (--sign)

Creates a detached signature on the SBOM with cosign to establish supply-chain trust. It is offline key-based signing (--tlog-upload=false), so no network or OIDC is needed.

# 1) Generate a key (first time only). For a passwordless key, use COSIGN_PASSWORD=""
docker run --rm -v "$PWD":/keys -w /keys -e COSIGN_PASSWORD="" \
  --entrypoint cosign ghcr.io/sktelecom/bomlens:latest generate-key-pair

# 2) Scan while signing (COSIGN_KEY=private key path, COSIGN_PASSWORD=key password)
COSIGN_KEY="$PWD/cosign.key" COSIGN_PASSWORD="" \
  ./scripts/scan-sbom.sh --project MyApp --version 1.0.0 --sign --generate-only

# 3) Verify
docker run --rm -v "$PWD":/w -w /w --entrypoint cosign \
  ghcr.io/sktelecom/bomlens:latest \
  verify-blob --key cosign.pub --signature MyApp_1.0.0_bom.json.sig \
  --insecure-ignore-tlog MyApp_1.0.0_bom.json

The private key is mounted read-only into the container. Additional output: MyApp_1.0.0_bom.json.sig


Troubleshooting

Symptom Cause / fix
trivy not installed ... skipping old image. Pull the latest image with docker pull.
--deep-license requested but scancode not in image build the image with --build-arg SBOM_DEEP_LICENSE=true.
Docker is not running in the UI start the Docker engine (Rancher Desktop/Docker Desktop, etc.) and run it again.
Many NOASSERTION in the notice the dependencies have no license metadata. Supplement with --deep-license or check manually.
Port conflict (--ui) specify a different port with UI_PORT.