<!--
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>
-->
# Administrator Guide — ndaal SBOM Auditor
This guide covers deploying, configuring and operating the ndaal SBOM
Auditor. For the exhaustive option and route tables see
[REFERENCE.md](../REFERENCE.md); for the architecture see
[structure.md](structure.md) and
[arc42/en/](arc42/en/01-introduction-and-goals.md).
## Overview
The auditor is a single self-contained binary. The web UI, fonts and the
SQLite engine are embedded, so a deployment is the binary plus a writable
data directory. It serves HTTPS only (TLS 1.3) and binds loopback by
default.
## Prerequisites
- A host that can run the binary (built for its target).
- Optionally, the analyzer tools on `PATH`: `syft`, `grype`, `trivy`,
`osv-scanner`, `bomber`. Each is optional; an absent tool is skipped,
not fatal.
- No database server, runtime or network service is required.
## Installing the analyzer tools
The tools are detected on `PATH` at analysis time and their versions are
shown on the `/tools` page. Install whichever you want to use, for
example:
```bash
# Anchore syft + grype
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s
# Aqua trivy, Google osv-scanner, devops-kung-fu bomber
# install per each project's documentation
```
To point the auditor at a specific binary, set the per-tool override:
`SBA_TOOL_SYFT_BIN`, `SBA_TOOL_GRYPE_BIN`, `SBA_TOOL_TRIVY_BIN`,
`SBA_TOOL_OSV_SCANNER_BIN` or `SBA_TOOL_BOMBER_BIN`.
## Starting the server
```bash
sbom-auditor --port 8680
```
The server binds `https://127.0.0.1:8680` (TLS 1.3 only). A self-signed
certificate for localhost is regenerated on every start-up, so browsers
warn once. Port 8681 is reserved for a future QUIC / HTTP/3 listener.
## Configuration
Every option has an `SBA_*` environment equivalent; the flag wins over
the environment. The full table is in [REFERENCE.md](../REFERENCE.md);
the most common options:
| Flag | Environment | Default | Purpose |
| --- | --- | --- | --- |
| `--port <PORT>` | `SBA_PORT` | `8680` | Listen port. |
| `--bind <ADDR>` | `SBA_BIND` | `127.0.0.1` | Bind address. |
| `--data-dir <DIR>` | `SBA_DATA_DIR` | `./data` | SQLite store and stored SBOMs. |
| `--db <FILE>` | `SBA_DB` | `<data-dir>/auditor.db` | Database path override. |
| `--encryption-key-file <FILE>` | `SBA_ENCRYPTION_KEY_FILE` | none | Enable storage encryption. |
| `--tls-cert <FILE>` | `SBA_TLS_CERT` | self-signed | PEM certificate chain. |
| `--tls-key <FILE>` | `SBA_TLS_KEY` | self-signed | PEM private key. |
| `--allowed-host <H>` | `SBA_ALLOWED_HOSTS` | none | Extra `Host` authorities. |
| `--allow-non-loopback` | `SBA_ALLOW_NON_LOOPBACK` | off | Permit a non-loopback bind. |
| `--log-dir <DIR>` | `SBA_LOG_DIR` | `./ndaal/log` | Log-file directory. |
| `--log-format <FMT>` | `SBA_LOG_FORMAT` | `text` | `text` or `json`. |
| `--no-self-update` | `SBA_NO_SELF_UPDATE` | off | Refuse `--self-update`. |
Runtime settings that are not start-up options — the import and export
directories, analyzer timeout and concurrency, the analyzer and sidecar
toggles and the upload size limit — are edited on the `/settings` page and
persisted in the database. Their keys and defaults are in
[REFERENCE.md](../REFERENCE.md).
## Security posture
- HTTPS only — there is no plaintext-HTTP fallback.
- Loopback bind by default; a non-loopback bind requires the explicit
`--allow-non-loopback` opt-in because the auditor ships no
authentication.
- Every response carries the ndaal security-header baseline (HSTS,
`X-Frame-Options: DENY`, a hash-pinned Content-Security-Policy, nosniff,
referrer minimisation, Permissions-Policy and cross-origin isolation),
every state-changing POST is same-origin checked, and an
anti-DNS-rebinding `Host` allowlist is enforced.
- All data, import and export I/O is confined by cap-std.
## Exposing the auditor on a network
The auditor has no authentication, so do not expose it directly. To reach
it from another host:
1. Run a TLS-terminating, authenticating reverse proxy (for example nginx
or Caddy with basic auth or SSO) in front of it.
2. Add the external hostname to the `Host` allowlist:
`--allowed-host auditor.example:443` (or `SBA_ALLOWED_HOSTS`).
3. Only then pass `--allow-non-loopback` (or bind the proxy to loopback
and keep the auditor on loopback too).
## Operator certificates
For a real (non-localhost) deployment, present a CA-issued certificate
instead of the ephemeral self-signed one:
```bash
sbom-auditor --tls-cert /etc/ssl/auditor.pem --tls-key /etc/ssl/auditor.key
```
The key may be PKCS#8, PKCS#1 (RSA) or SEC1 (EC). Both flags must be
given together.
## Storage encryption
Optional XChaCha20-Poly1305 encryption seals stored SBOM bytes and raw
analyzer output while they sit on disk. Supply a key file containing
exactly 32 raw bytes or 64 hex characters:
```bash
sbom-auditor --encryption-key-file /etc/sbom-auditor/at-store.key
```
Key management is the operator's responsibility:
- A missing or malformed key file is a hard error — encryption is never
silently skipped.
- Back up the key separately from the database; a lost key makes sealed
data unreadable.
- A store opened with a key still reads pre-existing plaintext rows, so
enabling encryption later is safe.
## Health probes
- `GET /healthz` — liveness; `200 ok` while the process serves.
- `GET /readyz` — readiness; `200 ready` once the app is serving.
Wire these into your process supervisor or load balancer.
## Logging
Logs are written to the console and to `<log-dir>/sbom-auditor.log`. Use
`--log-format json` for structured, newline-delimited logs suitable for a
log aggregator. An in-database audit log additionally records operator
actions such as settings changes.
## Backup and recovery
- The data directory holds everything stateful: the SQLite database
(`auditor.db` plus its WAL files) and the stored SBOM bytes. Stop the
server or use SQLite-consistent backup, then copy the data directory.
- If storage encryption is enabled, back up the key file separately and
securely.
- Recovery is copying the data directory (and key file) back and starting
the binary; the schema migration ladder brings an older database
forward automatically.
## Updating
- `--check-update` contacts gitlab.com read-only and reports whether a
newer release exists.
- `--self-update` downloads the latest release for the target, verifies it
against the published checksums, atomically replaces the running binary
and exits; it never downgrades and never installs on a mismatch.
- For package-managed or locked-down installs, set `--no-self-update`
(or `SBA_NO_SELF_UPDATE=1`) so `--self-update` refuses;
`--check-update` stays available.
## Running as a service
The binary is a well-behaved long-running process (graceful shutdown,
bounded connections and timeouts). Run it under systemd as a sandboxed
daemon: a dedicated unprivileged user, a private writable
`StateDirectory` for `--data-dir`, and the analyzer tools on the unit's
`PATH`. Keep the bind on loopback and place a reverse proxy in front for
remote access.
## Platform support
Built and tested on Debian 13.x and macOS. Any platform with a
compatible Rust target and the optional analyzer tools available on
`PATH` is supported; the auditor itself has no other runtime dependency.
## Troubleshooting
| Symptom | Likely cause | Action |
| --- | --- | --- |
| Browser warns about the certificate | Self-signed dev certificate | Expected once; accept it, or supply `--tls-cert` / `--tls-key`. |
| A tool always shows as skipped | Binary not on `PATH` | Install it or set `SBA_TOOL_<NAME>_BIN`; check `/tools`. |
| bomber skips on a newer SBOM | CycloneDX newer than 1.6 and syft absent | Install syft so the input can be converted. |
| Refused to bind | Non-loopback address without opt-in | Add `--allow-non-loopback` behind a proxy, or bind loopback. |
| Start-up aborts on the key file | Missing or malformed encryption key | Provide a 32-byte / 64-hex key file. |