322 lines
19 KiB
Markdown
322 lines
19 KiB
Markdown
# Complete TOML configuration reference (schema v1)
|
||
|
||
This reference documents all 26 top-level settings and four anchor fields. The product provides validation and a daemon
|
||
that schedules validation cycles. SLURM, RTR, ROV, HTTP/API services, offline
|
||
validation and additional payload JSON export are outside this configuration.
|
||
|
||
## 1. Loading a configuration
|
||
|
||
```bash
|
||
panda-rpki validate --config /srv/panda/validate.toml --check-config
|
||
panda-rpki validate --config /srv/panda/validate.toml --print-config
|
||
panda-rpki validate --config /srv/panda/validate.toml
|
||
```
|
||
|
||
Use `daemon` and a daemon configuration for continuous operation. Normal runs,
|
||
checks and printing all require one explicit file. Check and print are mutually
|
||
exclusive. There is no default-file discovery, include, profile merging, or
|
||
business-setting override. Old `--tal`, `--ta`, `--out`, `--log-format` options
|
||
and daemon `--` forwarding are rejected. `PANDA_RPKI_LOG_*` does not override
|
||
TOML. Standard dependency environments such as proxy settings are separate from
|
||
this application configuration contract.
|
||
|
||
Settings come from TOML, then built-in defaults. Unknown keys, duplicate TOML
|
||
keys, incorrect types and a mismatched mode return exit code 2. Quote strings,
|
||
leave integers unquoted, use `true`/`false` for booleans, and use `[]` for an empty
|
||
array. TOML has no null value: omit optional paths rather than writing `null`,
|
||
an empty path, or an empty string.
|
||
|
||
Write all top-level settings before the first `[[anchors]]` table. Fields after
|
||
that header belong to the current anchor until another table header appears.
|
||
For example, putting `log-format` after `tal` makes it an unknown anchor field.
|
||
|
||
```toml
|
||
config-version = 1
|
||
mode = "validate"
|
||
out = "output"
|
||
log-format = "text" # Top-level setting: keep this before [[anchors]].
|
||
|
||
[[anchors]]
|
||
id = "ripe"
|
||
tal = "input/ripe.tal"
|
||
```
|
||
|
||
## 2. Common top-level settings
|
||
|
||
These settings apply to both commands. Defaults below describe omitted fields.
|
||
The examples explicitly choose a 1,800-second timeout and strict completion;
|
||
those choices do not change the built-in defaults.
|
||
|
||
| Key | Type | Default / required | Meaning and constraints |
|
||
| --- | --- | --- | --- |
|
||
| `config-version` | Integer | Explicit `1` required | Configuration schema version, not the software version. Missing or unsupported versions are rejected. |
|
||
| `mode` | String | Required | `validate` or `daemon`; must match the command. |
|
||
| `anchors` | Array of tables | At least one required | Write `[[anchors]]` entries; see section 5. No automatic TAL-directory scan. |
|
||
| `ta-constraints-enabled` | Boolean | true | Apply explicit or adjacent TA constraints files. False skips all constraints loading and enforcement, including adjacent discovery; unused missing or malformed files are ignored. |
|
||
| `ta-refresh-policy` | String | `allow-valid-cache` | On automatic TA download failure, permit a revalidated, usable cached certificate. `require-fresh` prohibits fallback. Does not replace fixed TA files. |
|
||
| `max-ca-depth` | Nonnegative integer | 64 | Maximum CA validation-tree depth. Zero is accepted by configuration parsing, but is a depth limit, not unlimited traversal. Usually keep 64. |
|
||
| `http-timeout-secs` | Nonnegative integer, seconds | 300 | HTTP fetch timeout. Zero is normalized to one second, not unlimited. Does not set the whole-run or rsync timeout. |
|
||
| `http-root-cert` | Array of path strings | `[]` | Additional HTTP TLS root certificates in PEM format. Every file must be readable and parseable. Empty means no custom additions; system TLS trust remains. These are not RPKI TA certificates. |
|
||
| `parallel-max-repo-sync-workers-global` | Positive integer | 8 | Global repository-sync worker count. Zero is rejected. |
|
||
| `parallel-phase2-object-workers` | Positive integer | 8 | Phase-2 object-processing worker count. Zero is rejected. |
|
||
| `parallel-phase2-worker-queue-capacity` | Positive integer | 256 | Phase-2 worker queue capacity. Zero is rejected. |
|
||
| `parallel-repo-worker-queue-capacity` | Positive integer | Input default 256; effective 1024 | Repository worker queue capacity. Zero is rejected; values 1–1023 are raised to 1024. Print-config reports normalization. |
|
||
| `log-level` | String | `info` | `off`, `error`, `warn`, `info`, `debug`, or `trace`; case-sensitive. |
|
||
| `log-format` | String | `text` | Human-readable English diagnostics or `json` events, one object per line. Does not change summary or metadata formats. |
|
||
| `log-progress-interval-secs` | Nonnegative integer, seconds | 10 | Periodic progress interval. Zero disables periodic progress, not other stage messages. Levels off/error/warn do not start a progress thread. |
|
||
| `require-complete` | Boolean | false | A partial run exits 0 when false, 3 when true. Does not change validation rules, turn partial into success, or permit partial publication. |
|
||
| `run-timeout-secs` | Nonnegative integer, seconds | 0 | Whole-run budget; zero disables it. Validate includes runtime TA acquisition and output preparation. Daemon measures from child startup and enforces the budget in the controller. Check/print do not use this budget. |
|
||
|
||
Integers are also limited by TOML and the target platform's integer types.
|
||
Larger worker counts do not guarantee higher throughput; consider CPU, memory
|
||
and repository-service load.
|
||
|
||
## 3. Validate-only settings
|
||
|
||
These keys are rejected in daemon configurations, even when set to their usual
|
||
default values.
|
||
|
||
| Key | Type | Default / required | Meaning and constraints |
|
||
| --- | --- | --- | --- |
|
||
| `out` | Directory path | Required | Current-attempt output: CSV, summary, timing files and completion marker. A partial run can also produce artifacts. |
|
||
| `rrdp-state-dir` | Directory path | `<out>/.state` | Persistent protocol state containing repository-db. Reuse for incremental synchronization; runtime access is exclusive. |
|
||
| `rrdp-sync-mode` | String | `auto` | `auto` selects synchronization according to available state; `snapshot` requires empty state; `delta` requires an existing database. Individual repositories can still use protocol fallback. |
|
||
| `ccr-out` | File path | Omitted: no CCR | For example, `output/result.ccr`. Can be outside out. An existing target must be a file, not a directory. |
|
||
| `publish-dir` | Directory path | Omitted: disabled | Immutable successful result copies and latest pointer. Must not equal, contain, or be contained by out or protocol state. Uses additional disk space; Successful copies in publish/runs are not automatically pruned. |
|
||
|
||
## 4. Daemon-only settings
|
||
|
||
These keys are rejected in validate configurations.
|
||
|
||
| Key | Type | Default / required | Meaning and constraints |
|
||
| --- | --- | --- | --- |
|
||
| `state-root` | Directory path | Required | Controller root; daemon manages state, runs, locks, status files and latest beneath it. |
|
||
| `interval-secs` | Nonnegative integer, seconds | 60 | Delay after one cycle finishes before the next starts, not a fixed start-to-start period. Zero runs cycles consecutively. |
|
||
| `max-runs` | Positive integer | Omitted: unlimited | Maximum cycles in the current process, not the maximum historical sequence number. Zero is rejected. |
|
||
| `retain-runs` | Positive integer | 10 | Retain the newest N completed runs plus an older run referenced by latest. Not a hard limit on every directory. Zero is rejected. |
|
||
| `shutdown-grace-secs` | Nonnegative integer, seconds | 30 | Time allowed for the active child to finish after a stop request. Then TERM, followed by KILL after another two seconds. Zero skips waiting for natural completion. Separate from run timeout. |
|
||
|
||
Each cycle generates `runs/run_XXXXXX/validator-config.toml` with absolute paths.
|
||
The controller supplies output, CCR and synchronization settings. The child
|
||
configuration has run-timeout-secs=0 because the parent enforces the budget.
|
||
Editing generated child configurations is not a persistent configuration change.
|
||
|
||
The controller requests snapshot for empty state, delta after success and auto
|
||
after partial/failed. Ordinary partial/failed cycles do not prevent subsequent
|
||
cycles. On finite completion or stop, the aggregate exit is 2 if any cycle failed;
|
||
otherwise 3 if strict completion is enabled and any cycle was partial; otherwise
|
||
0. An exited container with code 3 does not imply Docker failed to stop it.
|
||
|
||
## 5. Anchor fields
|
||
|
||
| Key | Type | Default / required | Meaning and constraints |
|
||
| --- | --- | --- | --- |
|
||
| `id` | String | TAL filename stem | Identifier in results, logs and constraints. An explicitly empty string also falls back to the filename stem. Resolved IDs must be nonempty and unique; explicit names are preferred. |
|
||
| `tal` | File path | Required | TAL obtained from an independently trusted source; must exist and parse during preflight. Contains certificate URIs and the trusted public key. |
|
||
| `ta` | File path | Omitted: automatic mode | If present, selects a fixed DER TA certificate. Preflight checks binding, certificate profile/signature and validity. Network downloads do not silently replace it. |
|
||
| `constraints` | File path | Discover same-stem `.constraints` | For ripe.tal, try ripe.constraints. Absence of that file means no additional constraints. When ta-constraints-enabled is true, an explicit path must exist and parse. Omitting this setting does not disable discovery; an empty string is not a disable switch. Set top-level `ta-constraints-enabled = false` to disable all constraints. |
|
||
|
||
Automatic refresh updates the **TA certificate, never the TAL file**. Each
|
||
validate run or daemon cycle tries the TAL's HTTPS/rsync URIs in order. There is
|
||
no separate background refresh timer, and no invented HTTPS alternative for an
|
||
rsync-only TAL. Candidates must pass certificate and TAL-binding validation.
|
||
|
||
The cache is `<rrdp-state-dir>.ta-cache`, keyed by the TAL public-key SHA-256.
|
||
Download failure permits fallback only under allow-valid-cache with a usable,
|
||
revalidated cached certificate; that makes the result at least partial.
|
||
Require-fresh prohibits fallback. Existing fixed `.cer` files do not seed this
|
||
cache automatically; switching to automatic mode initially needs reachable URIs.
|
||
One failed TA with others completing yields partial; all TAs failing yields
|
||
failed. A fixed-certificate error found during preflight exits 2 immediately.
|
||
|
||
## 6. Paths, mounts, reload and concurrency
|
||
|
||
- `--config FILE` is relative to the process working directory. Paths inside
|
||
TOML are relative to the resolved configuration file location; existing
|
||
symlink ancestors are resolved. Absolute paths are accepted. There is no `~`,
|
||
`$HOME` or `${VAR}` expansion inside TOML strings.
|
||
- Moving a configuration can change every relative path. Keep temporary profile
|
||
copies in the same directory; concurrent instances additionally need separate
|
||
output, state and publication roots.
|
||
- Docker TOML uses container paths; Compose CONFIG_FILE/INPUT_DIR/STATE_DIR
|
||
variables use host paths. Those variables select mounts/image/UID, not
|
||
application settings.
|
||
- The TA cache is a sibling of protocol state. With a writable /state mount,
|
||
use `rrdp-state-dir="/state/repository"` so repository and repository.ta-cache
|
||
are both writable and persistent. Using /state directly places the cache at
|
||
/state.ta-cache, which needs a separate mount. Plan stopped migration for
|
||
existing databases; changing a path does not migrate the old database.
|
||
- Daemon's /data/state and /data/state.ta-cache already share the /data mount.
|
||
- TOML is loaded once at process startup. Daemon rereads the configured TAL/TA/
|
||
constraints files each cycle. TOML changes require a process restart. If an
|
||
editor or sed -i replaces a single-file bind mount's host inode, recreate the
|
||
container so the new file is mounted.
|
||
- Runtime locks protect output, state and publication roots. Preflight does not
|
||
acquire runtime locks. Passing it does not prove future write permissions,
|
||
network access, free space or exclusive access.
|
||
|
||
See [Docker operations](docker.md#graceful-stop-edit-and-reload) for complete
|
||
stop, check and recreate commands.
|
||
|
||
## 7. Results and consistent reads
|
||
|
||
| Status | Conditions in brief | Default exit | Strict exit | Update latest |
|
||
| --- | --- | --- | --- | --- |
|
||
| success | All configured TAs complete, no terminal repository failures or cache degradation, required artifacts complete | 0 | 0 | Yes |
|
||
| partial | Some TA/repository terminal failure or valid TA-cache fallback, with usable completed results | 0 | 3 | No |
|
||
| failed | Configuration/lock/fatal failure, all TAs fail, timeout, interruption, output or publication failure | 2 | 2 | No |
|
||
|
||
Rejecting invalid objects according to the standards does not itself imply
|
||
partial. A recoverable RRDP failure followed by valid fallback need not imply
|
||
partial either. Read resultStatus and the typed repositoryFailedCount rather
|
||
than inferring status from warning counts.
|
||
|
||
Out contains the current attempt. Atomic replacement of individual files is
|
||
not an atomic multi-file snapshot. The result-complete.json marker is written
|
||
last; a partial attempt can have a marker and still be partial. Only success is
|
||
copied to publish/runs/<id> and switches latest. Resolve latest once, then read
|
||
all files from that immutable directory. Daemon uses its existing run directory
|
||
without a second publication copy. Latest is absent before the first success;
|
||
upgrading an existing state root does not create latest from historical runs;
|
||
the pointer is established by the first subsequent complete success.
|
||
|
||
Text logging affects diagnostics only: summary, completion markers and printed
|
||
configuration remain JSON. Daemon lifecycle diagnostics are in container logs;
|
||
child validation diagnostics are in that run's validator.log. Historical logs
|
||
are not converted.
|
||
|
||
## 8. Complete examples and selection
|
||
|
||
The [native configuration directory](../examples/config/README.md) contains
|
||
copyable files:
|
||
|
||
| File | Scenario | Explicit choices |
|
||
| --- | --- | --- |
|
||
| validate-minimal.toml | Minimal single automatic TA | Required fields only; built-in defaults otherwise |
|
||
| validate-full.toml | All common/validate settings and successful publication | Text logs, strict completion, 1,800-second budget |
|
||
| validate-fixed.toml | Fixed certificate | Both tal and ta; certificate must match and be valid |
|
||
| daemon-all5.toml | Continuous five-TA automatic refresh | All common/daemon settings; max-runs omitted |
|
||
| daemon-three.toml | Three five-TA cycles | max-runs=3, interval=0, independent state root |
|
||
|
||
For containers, use the [four Docker configurations](../docker/examples/README.md).
|
||
Mounting a native relative-path example under /config does not automatically
|
||
make its paths correct.
|
||
|
||
### 8.1 Minimal complete validate configuration
|
||
|
||
Save as /srv/panda/validate.toml and prepare /srv/panda/input/ripe.tal:
|
||
|
||
```toml
|
||
config-version = 1
|
||
mode = "validate"
|
||
out = "output"
|
||
|
||
[[anchors]]
|
||
id = "ripe"
|
||
tal = "input/ripe.tal"
|
||
```
|
||
|
||
Run `panda-rpki validate --config /srv/panda/validate.toml`. Default state is
|
||
/srv/panda/output/.state; the TA cache is /srv/panda/output/.state.ta-cache.
|
||
Defaults are text/info, no CCR, no publication root and no whole-run timeout.
|
||
Partial also exits 0 by default. Add require-complete=true at the top level for
|
||
strict completion.
|
||
|
||
### 8.2 Fixed, automatic and mixed anchors: replacement fragment
|
||
|
||
```toml
|
||
[[anchors]]
|
||
id = "ripe"
|
||
tal = "input/ripe.tal"
|
||
ta = "input/ripe.cer" # Fixed; remove this key to switch to automatic.
|
||
|
||
[[anchors]]
|
||
id = "apnic"
|
||
tal = "input/apnic.tal" # Automatic.
|
||
```
|
||
|
||
This replaces the anchors section of a complete configuration; it is not a
|
||
standalone file. Mixed mode needs no extra mode switch. Changing
|
||
TA refresh policy does not make an anchor with an explicit ta automatic.
|
||
|
||
### 8.3 Logging, TLS and worker tuning: top-level fragment
|
||
|
||
```toml
|
||
log-format = "json"
|
||
log-level = "debug"
|
||
log-progress-interval-secs = 0
|
||
http-timeout-secs = 600
|
||
http-root-cert = ["tls/internal-root.pem"]
|
||
parallel-phase2-object-workers = 4
|
||
parallel-max-repo-sync-workers-global = 4
|
||
parallel-phase2-worker-queue-capacity = 256
|
||
parallel-repo-worker-queue-capacity = 1024
|
||
```
|
||
|
||
Replace existing top-level settings; do not add duplicate keys. Prepare the
|
||
custom TLS PEM file first, or keep [] when no extra roots are needed. This does
|
||
not change the TAL public key, relax TA validation or disable system TLS checks.
|
||
|
||
## 9. Preflight and troubleshooting
|
||
|
||
Check first, print effective configuration, then run normally. Check does not
|
||
use the network, take runtime locks or create run directories. It reads TOML,
|
||
TALs, fixed TAs, constraints and extra HTTP roots. Print performs the same checks
|
||
and emits effective settings, sources and normalizations.
|
||
|
||
For example, setting http-timeout-secs to 0 and the repository queue to 256
|
||
produces this excerpt, not the full print output:
|
||
|
||
```json
|
||
{
|
||
"effective": {
|
||
"http-timeout-secs": 1,
|
||
"parallel-repo-worker-queue-capacity": 1024
|
||
},
|
||
"normalizations": [
|
||
{"field":"http-timeout-secs","input":0,"effective":1},
|
||
{"field":"parallel-repo-worker-queue-capacity","input":256,"effective":1024}
|
||
]
|
||
}
|
||
```
|
||
|
||
| Symptom | Explanation and action |
|
||
| --- | --- |
|
||
| Missing configuration/version error | Explicitly write config-version=1 and pass --config. |
|
||
| Mode mismatch | Match the command and mode. |
|
||
| Unknown anchor field log-format | Move it before the first [[anchors]] table. |
|
||
| Out is not allowed in daemon | Remove validate-only keys; the controller owns output. |
|
||
| Zero workers/queues/max-runs/retention | Use positive values; omit max-runs for unlimited cycles. |
|
||
| File not found | Resolve paths against the config directory; check container mounts. |
|
||
| No automatic TA cache | First use needs a successful download; fixed cer files do not seed the cache. |
|
||
| Preflight passes, runtime fails | Check does not test network reachability, runtime locks or actual writes. |
|
||
| Logs still JSON | Check top-level settings, recreate the container and inspect new logs. Metadata remains JSON intentionally. |
|
||
| Exited with code 3 | Stopped with partial aggregate results; inspect summaries/lifecycle logs rather than repeatedly stopping. |
|
||
| Latest absent | No complete success yet; partial does not publish even when it exits 0. |
|
||
|
||
## TA resource constraints
|
||
|
||
The repository includes five OpenBSD TALs and matching constraints in
|
||
[`tals/`](../tals/README.md), with pinned provenance and checksums. Both all5
|
||
examples explicitly enable them. To customize one anchor, edit its constraints
|
||
file or its `constraints = "/input/custom.constraints"` path. Paths must be
|
||
visible inside the container; relative paths resolve against the TOML directory.
|
||
|
||
To disable every anchor's constraints, set this **before** `[[anchors]]`:
|
||
|
||
```toml
|
||
ta-constraints-enabled = false
|
||
```
|
||
|
||
This takes precedence over explicit paths and same-stem discovery. Re-enable
|
||
with `true`; enabled explicit paths must be readable and syntactically valid.
|
||
Absent adjacent files are allowed for custom TALs without explicit paths.
|
||
Check/print and actual validation use the same selection rules. The summary
|
||
records `taConstraintsEnabled` and `taConstraintsApplied` (anchor IDs and paths).
|
||
A loaded empty file imposes no additional restrictions; enabled alone does not
|
||
imply a file was found.
|
||
|
||
Each run loads a fresh immutable policy snapshot. Reusing RRDP state does not
|
||
reuse validation results from the previous policy. Stop and recreate the daemon
|
||
to adopt TOML changes; follow the Docker reload procedure after editing files.
|