Zum Hauptinhalt springen

Administrator 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>
-->

# 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. |