Skip to content

Latest commit

 

History

History
253 lines (194 loc) · 9.25 KB

File metadata and controls

253 lines (194 loc) · 9.25 KB

Output Formats

Bomly writes one primary stdout output and any number of additional outputs in the same run.

Primary output: --format

Use --json as a shortcut for --format json when you want structured output quickly.

Format Default for When to use
text Local runs, --interactive Reading on a terminal
json Automation Pipelines, custom dashboards, anything consumed by code
markdown Reviews Job summaries, PR comments, and other Markdown surfaces
sarif Audit-only CI security panes, GitHub Security tab, IDE problem markers
spdx Scan only SPDX 2.3 JSON SBOMs
cyclonedx Scan only CycloneDX 1.7 JSON SBOMs

Flag:

bomly scan --format text     # default
bomly scan --json
bomly explain lodash --format markdown
bomly diff --base main --head HEAD --format markdown
bomly scan --audit --format sarif
bomly scan --format spdx

Constraints:

  • --format sarif requires --audit. SARIF is a findings format; without an auditor there are no findings.
  • --format spdx and --format cyclonedx are supported by scan only.
  • --interactive forces --format text. Combining it with --json or another non-text reporting format is rejected with exit 4.

text — human-readable

The default. Groups packages by ecosystem and edge depth, summarizes finding counts by severity, and links to the explain path for any flagged package. With --enrich, it adds a short remediation summary directly below the enrichment line and points to JSON for the details. The summary counts only concrete fix suggestions; manual review, unknown fix evidence, and packages with no available fix do not inflate the count. Color and box-drawing are auto-disabled when stdout is not a TTY.

bomly scan --enrich --audit
✓ 68 packages in 1 manifest   (1 direct, 67 transitive · runtime 68, dev 0)

✓ Enriched via Grype, deps.dev License Matcher

✓ 7 fix suggestions for 7 of 7 vulnerable packages.
  Run again with --format json to see remediation details.

Top-level dependencies
  NAME      VERSION   LICENSE   SCOPE     VULNS
  express   4.19.2    MIT       runtime   1L

Findings
  [HIGH]      GHSA-37ch-88jc-xwx2  path-to-regexp@0.1.7
  [HIGH]      GHSA-9wv6-86v2-598j  path-to-regexp@0.1.7
  [HIGH]      GHSA-qwcr-r2fm-qrc7  body-parser@1.20.2
  [HIGH]      GHSA-rhx6-c78j-4q9w  path-to-regexp@0.1.7

Markdown reports include the same remediation summary and the complete suggestion table.

json — structured

The shape every Bomly subcommand emits. Each command has its own schema:

Command Schema
bomly scan scan.md
bomly explain explain.md
bomly diff diff.md

bomly scan surfaces the three-collection model (see Architecture → Domain model): manifests[].dependencies are lean detection-stage nodes (identity, scopes, depends_on, package_ref); packages is the deduplicated matching-stage registry (licenses, vulnerabilities, scorecard, EOL, CPEs, digests) keyed by PURL; and findings is the reference-style audit output. Resolve a finding or a dependency to its enrichment by matching package_ref/package.purl into packages.

For remediation suggestions, affected_dependency_refs names occurrences of the vulnerable package. suggested_action_dependency_ref names the dependency or manifest anchor that the suggested action targets. These can differ for a transitive package.

Pipe into jq for common queries:

# Every package with a high-or-critical vulnerability
bomly scan --enrich --json | jq '
  .packages[]
  | select(.vulnerabilities[]? | .severity == "high" or .severity == "critical")
  | {name, version, ecosystem}
'

# All transitive paths to a specific dependency
bomly explain lodash --json | jq '.paths[] | .nodes | map(.name) | join(" -> ")'

# New findings introduced by a PR
bomly diff --base main --head HEAD --enrich --audit --json | jq '.findings.introduced[]'

The first query against a project pinning express@4.19.2 (first two of several matches shown):

{
  "name": "body-parser",
  "version": "1.20.2",
  "ecosystem": "npm"
}
{
  "name": "path-to-regexp",
  "version": "0.1.7",
  "ecosystem": "npm"
}

JSON output includes Bomly-specific metadata that standard SBOM formats don't carry: reachability tier/status/confidence, audit reasons, and per-finding source.

bomly explain returns every deterministic root-to-target path, not only a shortest or representative path. Paths are ordered by their stable package-ID sequence, and cyclic paths are explicitly marked. This preserves alternate workspace and duplicate-version routes that can require different investigation.

bomly diff classifies an audit finding by its stable advisory/package identity, independent of a package version bump. A finding present on both sides is persisted; it is not reported as one resolved finding plus one introduced finding merely because the affected package version changed.

Dependency changes are split into separate kinds. A version change says that the package release changed. A detail change says that the same package occurrence changed in one of these ways:

  • its relationship changed between direct, transitive, and unknown;
  • its source changed, such as registry to Git or workspace;
  • its eligibility for registry matching changed.

A dependency can have both a version change and a detail change in the same diff. Structured output calls each detail-change record a transition. JSON keeps the before and after evidence under results.dependencies.transitions and under the matching manifest. Text, Markdown, the interactive view, and MCP show the same classification.

Human-readable output asks for extra review when a known source changes to Git or a URL, or when vulnerability checks covered the dependency before the change but no longer do. Other detail changes remain informational. These labels help reviewers find important changes; by themselves, they do not change the command's exit status.

sarif — CI security tools

SARIF 2.1.0. Findings only. One result per (rule × package) pair. Includes:

  • Finding ID as the rule ID (CVE / GHSA / OSV identifier).
  • Severity mapped to SARIF level (error for critical/high, warning for medium, note for low/unknown).
  • Locations populated with manifest file paths when known.
  • Bomly-specific reachability and policy metadata in the properties bag.
bomly scan --enrich --audit --fail-on high --format sarif > bomly.sarif
Sample result object (one finding, properties trimmed)
{
  "ruleId": "GHSA-m6fv-jmcg-4jfg",
  "level": "error",
  "message": {
    "text": "send vulnerable to template injection that can lead to XSS in pkg:npm/send@0.18.0"
  },
  "locations": [
    {
      "physicalLocation": {
        "artifactLocation": { "uri": "package-lock.json" },
        "region": { "startLine": 636 }
      }
    }
  ],
  "properties": {
    "package_ref": "pkg:npm/send@0.18.0",
    "fixed_in": "0.19.0",
    "fix_state": "fixed"
  }
}

Locations point at the lockfile line that pins the vulnerable version, so code-scanning annotations land somewhere actionable.

GitHub Code Scanning, Azure DevOps, and most IDE extensions ingest SARIF directly. See CI integration for upload recipes.

Additional output: -o

-o uses the same format names as --format, plus an optional file path. Use <format>=<path> to write to a file, or just <format> to write that additional output to stdout. When every -o names a file and --format is not set, a successful run writes the files silently — pass --format text (or any primary format) if you also want stdout output.

bomly scan --json \
  -o text=summary.txt \
  -o markdown=summary.md \
  -o sarif=bomly.sarif \
  -o spdx=sbom.spdx.json \
  -o cyclonedx=sbom.cdx.json

Supported targets:

-o value Format
text Human-readable terminal report
json Structured Bomly JSON report
markdown GitHub-flavored Markdown report
sarif SARIF 2.1.0 report; requires --audit
spdx SPDX 2.3 JSON
cyclonedx CycloneDX 1.7 JSON

spdx and cyclonedx are supported by scan. Report formats (text, json, markdown, sarif) are supported by report-producing commands. See SBOM formats for the SBOM comparison and writing rules.

Combining outputs

A single scan can produce:

  • A human report on stdout.
  • A JSON document written to a file.
  • A SARIF document for a CI panel.
  • One or more SBOM artifacts.

Example:

bomly scan --enrich --audit --fail-on high \
  --format text \
  -o json=bomly.json \
  -o sarif=bomly.sarif \
  -o spdx=sbom.spdx.json \
  -o cyclonedx=sbom.cdx.json

--format text keeps the terminal report on stdout. Without it (and with every -o naming a file), a successful run writes the files and prints nothing.

Detector and matcher work runs once. All outputs derive from the same in-memory graph.

See also