csaf-crud 1.3.7

CSAF 2.0 / 2.1 advisory CRUD server with HATEOAS JSON API and HTML UI (TLS 1.3, HTTP/1.1 + HTTP/2 + HTTP/3)
<!-- SPDX-License-Identifier: Apache-2.0 -->
<!-- SPDX-FileCopyrightText: 2026 ndaal GmbH & Co KG, Cologne -->

# User Guide

How to manage CSAF security advisories with ndaal CSAF-CRUD, through
both the web interface and the JSON API. For configuration and
operations see the [Administrator Guide](Administrator_Guide.md); for
the complete command/endpoint catalogue see
[REFERENCE.md](../REFERENCE.md).

## What this application does

ndaal CSAF-CRUD lets you create, edit, validate, export, and import
CSAF 2.0 / 2.1 security advisories (security advisories, VEX
documents, and informational advisories). It records dual CVSS v3.1
and v4.0 scores and supports TLP 2.0, German Verschlusssache, and
NATO classification labels.

## Getting started

Open the web UI in a browser:

```text
https://127.0.0.1:8180/
```

The development server uses a self-signed certificate, so your
browser shows a one-time warning — accept the exception to continue.

The dashboard at `/` shows document counts by category, a configured
summary, and the most recent audit-log activity.

> Note: this release has no login. Every page and API route is open
> to anyone who can reach the server. See the
> [Administrator Guide]Administrator_Guide.md#authentication-and-access-control.

## Web interface

### Listing advisories

`/csaf` shows a paginated table (Tracking ID, Title, Category,
Status, CVSS v3, CVSS v4, Release Date). Use the Previous/Next
controls to page through results.

### Creating an advisory

1. Go to `/csaf` and choose **New**, or open `/csaf/new`.
2. Fill in the form. Required fields are marked; the main groups are:
   - **Document:** tracking ID, title, category
     (`csaf_security_advisory`, `csaf_vex`,
     `csaf_informational_advisory`), status (`draft`, `interim`,
     `final`), version, initial and current release dates.
   - **Classification:** TLP label (required) plus optional
     Verschlusssache and NATO labels when enabled in settings.
   - **Publisher:** name, namespace, category, contact details.
   - **Product:** vendor, product name, product ID, product status.
   - **Vulnerability:** CVE, title, description, CWE — required for a
     security advisory, optional for VEX and informational.
   - **Scores:** CVSS v3.1 and v4.0 base score, severity, and vector.
3. Submit. The document is validated, stored, and (if export is
   configured) written to disk with hash sidecars.
4. On a validation failure the form is redisplayed with your input
   preserved and an error banner listing each problem field. Fix and
   resubmit.

### Viewing, editing, deleting

- `/csaf/{id}` shows the metadata, the vulnerability table, and the
  raw JSON, with buttons to edit, download JSON, or delete.
- `/csaf/{id}/edit` reloads the form pre-filled from the stored
  document, including the classification labels.
- Delete asks for confirmation, then removes the document and records
  an audit entry.

### Downloading JSON

`/csaf/{id}/json` returns the raw CSAF JSON document for the advisory.

### Settings

`/settings` controls runtime behaviour: CSAF export mode (2.0 / 2.1),
theme, the import/export/dump/log directories, the naming convention,
publisher defaults, the default TLP / Verschlusssache / NATO labels,
where classification labels are written, and the five hash-sidecar
toggles. **Reset to defaults** restores everything; the theme toggle
switches light/dark.

### Import and export (admin pages)

- `/admin/import` scans the import directory and stores every valid
  `*.json` advisory (`provider-metadata.json` is skipped). The result
  page reports imported, skipped, and per-file errors. Import is
  lenient — a document with OASIS conformance warnings is still
  admitted, with the warnings logged.
- `/admin/export` writes every stored document to the export
  directory with the enabled sidecars. Export is strict — see
  validation below.
- The export page also offers **Dump Database** (a consistent
  snapshot) and **Export Audit Log** (Markdown, CSV, JSON, SARIF).

### Info pages

`/info/about`, `/info/license`, `/info/system`, `/info/privacy`, and
`/info/security` describe the application, its licence, host and
runtime details, data handling, and the security posture.

## The advisory lifecycle and validation

Validation runs on create, update, import, and export. Findings have
two severities:

- **Error (hard):** blocks the operation. In the web UI the form
  redisplays with the errors; via the API you get `422` with an
  `errors` array.
- **Warning (soft):** reported but non-blocking.

Export adds a second, stricter gate: when the `oasis-validator`
feature is enabled (default), the official OASIS CSAF 2.1 suite must
also pass, or the export of that document is refused. A common cause
is setting `csaf_mode` to `2.0` while a document is structurally 2.1
(it carries `metrics` / `cvss_v4`): relabelling it `2.0` makes it
non-conformant and export refuses it. Keep `csaf_mode` aligned with
your documents.

You can re-validate any stored document on demand with
`GET /api/v1/csaf/{id}/validate`, which returns `valid`,
`error_count`, `warning_count`, and the `findings`.

## Classification labels

Three label families are supported:

- **TLP 2.0:** `CLEAR`, `GREEN`, `AMBER`, `AMBER+STRICT`, `RED`.
- **Verschlusssache (German):** `VS-NfD`, `VS-Vertr.`, `Geh.`,
  `Str. Geh.`.
- **NATO:** `NR`, `NC`, `NS`, `CTS`.

Where the labels are written into the exported CSAF is controlled by
`classification_storage_mode`: into `document.distribution.text`,
into `document.notes[]`, or `both`. On edit, the labels are read back
from the stored document so they round-trip. See
[classification.md](classification.md) for the full feature detail.

## JSON API

The HATEOAS JSON API lives under `/api/v1`. Responses are JSON with a
`_links` object; errors are RFC 9457 `application/problem+json`. The
full contract is [specs/openapi.yaml](../specs/openapi.yaml).

List advisories:

```bash
curl -k "https://127.0.0.1:8180/api/v1/csaf?page=1&per_page=20"
```

Retrieve one:

```bash
curl -k https://127.0.0.1:8180/api/v1/csaf/ndaal-sa-2026-003
```

Create one:

```bash
curl -k -X POST https://127.0.0.1:8180/api/v1/csaf \
  -H "Content-Type: application/json" \
  --data @advisory.json
# 201 Created, Location: /api/v1/csaf/<tracking-id>
```

Validate one:

```bash
curl -k https://127.0.0.1:8180/api/v1/csaf/ndaal-sa-2026-003/validate
```

Other endpoints: `PUT`/`DELETE` on `/api/v1/csaf/{id}`,
`/api/v1/audit-log`, `/api/v1/settings`, `/api/v1/system/info`, and
`/api/v1/system/health`. See
[REFERENCE.md](../REFERENCE.md#http-api).

`-k` (insecure) is needed only while the development self-signed
certificate is in use.

## Command-line interface

`ndaal-csaf-cli` performs the same import/export/validate operations
headlessly:

```bash
ndaal-csaf-cli stats
ndaal-csaf-cli validate path/to/advisory.json
ndaal-csaf-cli import  --directory ./data_import
ndaal-csaf-cli export  --directory ./data_export
```

Pass `--config <PATH>` to use a non-default configuration file. See
[REFERENCE.md](../REFERENCE.md#cli-commands) for flags and exit codes.