Skip to main content

User Guide

<!--
SPDX-License-Identifier: Apache-2.0
SPDX-FileCopyrightText: 2026 ndaal Gesellschaft für Sicherheit in der Informationstechnik mbH & Co KG, Cologne
SPDX-FileCopyrightText: Author: Pierre Gronau <Pierre.Gronau@ndaal.eu>
-->

# User Guide — ndaal SBOM Auditor

This guide walks through investigating an SBOM in the ndaal SBOM Auditor,
from ingest to a downloadable report. For options and routes see
[REFERENCE.md](../REFERENCE.md).

## What the auditor does

The auditor lets you investigate SBOM (Software Bill of Materials) files
locally. You upload an SBOM or import a folder of them, run an ensemble of
independent analyzers against each, review the normalised findings —
optionally enriched with live exploitation intelligence — and export the
result in eight formats. Everything runs on your machine and there is no
telemetry. The only outbound connections are ones you control: the
self-update you start, and, while vulnerability enrichment is on, the
per-CVE lookups it sends to the vulnlookup source you configure.
Enrichment is on by default; turn it off in **Settings** to keep the
auditor offline.

## Opening the interface

- Open `https://127.0.0.1:8680/` in your browser. The self-signed
  certificate triggers a one-time warning; accept it to continue.
- The navbar's moon / sun button toggles dark mode; the preference is
  remembered in your browser only.
- The language menu switches the interface between 49 languages. English,
  German and French are human-authored and pinned to the front; the others
  are machine-translated, pending native review, with automatic English
  fallback for any missing string, and Urdu renders right-to-left. The
  choice is pinned with a cookie. The generated reports (SARIF, CSAF, PDF)
  and the HTTP API are English-only.
- The Info menu (top right) links About, System info, Privacy, Security,
  License, Imprint, Changelog, README and the two guides.

## Step 1 — ingest an SBOM

You can add SBOMs two ways:

1. **Upload.** Open **Upload**, choose a single SBOM file and submit it.
   CycloneDX (JSON/XML), SPDX (JSON/tag-value) and syft-json are
   detected automatically. Very large files are rejected by the upload
   size cap, which applies per file and defaults to 10 GiB; an
   administrator can adjust the limit on the **Settings** page.
2. **Import a folder.** Configure the import directory on the
   **Settings** page, then open **Import** and scan it to ingest every
   SBOM it contains.

Each file is hashed and deduplicated: re-adding the same content returns
the existing entry rather than a duplicate. After ingest you land on the
SBOM's detail page, which shows its format, spec version and component
count.

## The Stored SBOMs dashboard

The home page (`/`) lists every stored SBOM in a table — name, format,
component count, source, ingest time, and the highest finding severity.
Click a row to open its detail page. When you have many SBOMs, four
controls help you find the one you want; they combine, so you can search,
filter and sort at once.

- **Search.** Type in the search box to find SBOMs by name, format, spec
  version, or by a component they contain — searching `log4j` or
  `openssl` lists every SBOM whose component tree includes it. The search
  is full-text and matches whole words.
- **Filter.** The Format dropdown narrows the list to one format
  (CycloneDX JSON/XML, SPDX JSON, SPDX 3.0, SPDX tag-value, Syft JSON or
  Unknown). The Severity dropdown shows only SBOMs whose highest finding
  severity is the one you pick. **Reset** clears both filters and keeps
  your sort.
- **Sort.** Click the Name, Format or Components column header to sort by
  it; click again to reverse. An arrow marks the active column.
- **Severity column.** The rightmost column shows each SBOM's single
  highest finding severity across its analyzer runs, as a coloured badge
  (Critical down to Negligible). A dash (—) means the SBOM has no
  findings yet — either it has not been analyzed, or it was analyzed
  clean.
- **Pages.** The list shows 25 SBOMs per page, with a "Showing X–Y of N"
  caption and Previous / Next controls. Your search, filters and sort are
  kept as you page.

## Step 2 — analyze

On the SBOM detail page, start the analysis. The auditor queues one run
per enabled analyzer and runs them in the background. The run list updates
itself until every run finishes; you do not need to reload.

Each run ends in one of four states — read them literally:

| Status | Meaning |
| --- | --- |
| `ok` | The tool ran and produced usable results. A tool that exits non-zero because it found vulnerabilities still counts as `ok`. |
| `skip` | The tool did not run — it is not installed, or the SBOM is incompatible with it. The reason is shown. |
| `fail` | The tool ran but produced no usable output. |
| `timeout` | The tool exceeded its time limit and was stopped. |

A `skip` or `fail` is never the same as "no vulnerabilities". If a tool
did not run, its coverage is simply missing — the auditor makes that
visible rather than hiding it.

If storage encryption is enabled and a stored SBOM cannot be decrypted —
a wrong key or tampered bytes — the read now fails loudly with an error
instead of scanning an empty document and reporting "no findings".
Treat such an error as a key mismatch or tampering to investigate, never
as a clean result.

Which analyzers run, their per-run timeout and how many run at once are
controlled on the **Settings** page. You can check each tool's presence
and version on the **Tools** page.

## Step 3 — review findings

For each `ok` run, the tool's output is normalised into findings and
shown per tool, each with a severity badge. Where a tool reports a GHSA or
OSV identifier, the auditor resolves and shows the CVE alias so the same
vulnerability lines up across tools.

When vulnerability enrichment is on (see [Settings](#settings)), each
finding is also annotated by CVE with three exploitation signals from the
vulnlookup service, shown in four extra columns:

| Column | What it tells you |
| --- | --- |
| KEV | `Known exploited` when the CVE is on the CISA Known Exploited Vulnerabilities catalogue — the strongest sign it is attacked in the wild. A dash means the finding was enriched but is not listed; `Not enriched` means no enrichment was available. |
| Nuclei | Whether a public Nuclei exploit template matches the CVE, and that template's severity. |
| EPSS | The EPSS exploitation probability and its percentile — how likely the CVE is to be exploited relative to all scored CVEs. |
| Source | The vulnlookup source the annotation came from, shown as a link when it is a valid HTTPS address. |

The findings are ordered most-urgent-first: known-exploited (KEV) findings
first, then by descending EPSS percentile. Findings that carry no
enrichment keep the order the analyzer produced. The same annotations flow
into every export.

Two cautions when reading the KEV column:

- Check the finding's package. A KEV badge on a finding with no package —
  `affects fedora @ 40`, for example — was matched against the operating-system
  release rather than an installed package, and usually does not apply.
- CVE-2020-0601 (a Windows CryptoAPI flaw on the KEV catalogue) can be reported
  against the Go standard library. Go fixed it in 1.13.6 and it only ever
  affected Windows, so on a later Go release it does not apply.

The enrichment is looked up once every analyzer has finished, so the columns
fill in shortly after the run completes. If every finding stays
`Not enriched`, ask your administrator to check that the auditor's host can
reach the vulnlookup service.

## Step 4 — export

Open **Export** for the SBOM and choose from the eight formats:

| Format | Use |
| --- | --- |
| SARIF 2.1 / 2.2 | Machine-readable findings for other tooling. |
| CSAF 2.1 / 2.2 | Machine-readable security advisories. |
| Markdown | A readable report, including a section listing skipped analyzers. |
| ODT / DOCX | Office documents. |
| PDF | A portable report (fonts embedded, umlaut-safe). |

Every format is ticked by default, so an export left unchanged produces
the full set; clear the formats you do not need.

Two buttons act on your selection:

- **Export** renders the selected formats and writes each file into the
  export directory together with its checksum sidecars. The files are
  then listed on the export page for later download.
- **Start download** renders the same selection in memory and streams it
  straight to your browser, writing nothing on the server. One selected
  format arrives as that single document; several formats (or a CSAF
  selection that fans out to multiple files) arrive as one ZIP bundle.

Every export lists any skipped or failed analyzers with their reasons, so
a report never overstates how complete the analysis was.

## The Tools page

The **Tools** page probes each analyzer live and shows its presence,
version, role and any documented caveat (for example, that bomber only
consumes CycloneDX up to 1.6). Use it to confirm your environment before
you rely on an analysis.

Below the analyzer table, the page shows which programming languages and
package managers each analyzer supports particularly well, which tool suits
which job, and the tool versions that overview was written against. It
describes what each tool can read, not what the installed binaries do: for
that, the analyzer table above is the authority.

## Settings

The **Settings** page controls the import and export directories, the
per-run analyzer timeout, the analyzer concurrency, which analyzers and
which checksum sidecars are enabled, the maximum upload size, and
vulnerability enrichment. Changes are saved to the local database and
recorded in the audit log.

Under **Vulnerability enrichment** you switch the exploitation lookups on
or off and list up to three vulnlookup sources. Each source has a URL and a
TCP port (blank means the standard HTTPS port, 443); the QUIC port beside
it is reserved for a future HTTP/3 transport and is unused today. Sources 1
and 2 default to the public `https://vulnlookup.ndaal.eu/`; source 3 defaults
to a loopback `https://127.0.0.1/` on this host's own 8680 / 8681 ports, for a
vulnlookup running alongside the auditor. The
sources are queried in order and the first to answer wins, so put your
preferred source first. Results are cached and refreshed once a day; when
every source is unreachable the enrichment columns stay blank rather than
blocking the review.

## Privacy

Everything runs locally. The auditor collects no telemetry. Its only
outbound connections are ones you control:

- **Vulnerability enrichment** — while it is enabled (the default), the
  auditor sends a per-CVE lookup for each analyzed finding to the
  vulnlookup source you configure on **Settings**. Each request carries
  only the CVE identifier. Turn enrichment off to stop every such lookup
  and keep the auditor fully offline.
- **Self-update** — the `--self-update` you start.

No other network access happens on the auditor's own initiative.