dorfteich/docs/architecture/adr/0027-vs-nfd-hardening-profile-mode.md
Claude Fable 5 da5fd7c770
All checks were successful
CI / Lint, typecheck, test (pull_request) Successful in 6m12s
CI / Build container images (pull_request) Successful in 4m2s
CI / Auth e2e pack (pull_request) Successful in 8m29s
CI / Import/export fidelity gate (pull_request) Successful in 54s
CD / Build and push images (push) Successful in 31s
CD / Deploy to Test (push) Successful in 14s
CD / Smoke tests against Test (push) Successful in 1m29s
CD / Promote to Int (push) Successful in 14s
CI / Build container images (push) Has been skipped
CI / Lint, typecheck, test (push) Successful in 6m30s
CI / Auth e2e pack (push) Successful in 8m6s
CI / Import/export fidelity gate (push) Successful in 57s
#243: VS_NFD_MODE and the machine-readable hardening-profile catalog
The deployment declares through VS_NFD_MODE (off | marked | hidden |
enforced, default off) how the application treats configuration that
violates the VS-NfD reference profile — deploy-level like
BACKUP_ALLOWED_TARGETS, so a compromised Site Admin cannot widen it.
The catalog in shared (vs-nfd-profile.ts) is the single source of
truth: every profile-relevant setting with a decidable compliant value,
judgement calls in an explicit advisory list, and a fence test parsing
the hardening guide's reference tables so neither can drift (pattern
#201). The api evaluates the catalog against the typed settings
registry and validated env and exposes mode + verdict on
GET /admin/system/vs-nfd-profile; the admin settings view shows the
card whenever the mode is not off. Display only — the treatments land
with #244–#246 (ADR 0027, proposed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
2026-07-31 18:24:04 +02:00

3.3 KiB

ADR 0027: VS-NfD hardening-profile mode and configuration catalog

  • Status: proposed
  • Date: 2026-07-31

Context

The hardening guide (issue #227, docs/vs-nfd/50-haertungsleitfaden.md) names a reference configuration for VS-NfD operation, but it is prose: the application cannot answer whether the running configuration matches it, and an operator flipping a switch in the admin UI gets no hint that the choice leaves the profile. Requested by the operator (2026-07-30) as a follow-up to the M24/M25 switches: the application itself should know which options violate the profile — while deployments outside any VS context stay entirely unaffected.

Decision

  1. A deploy-level mode, not a runtime setting. VS_NFD_MODE (off | marked | hidden | enforced) is an environment variable, validated in the shared env schema and passed through compose — for the same reason as BACKUP_ALLOWED_TARGETS (#192, ADR 0026): a compromised Site-Admin account must not be able to widen it. The modes escalate: marked shows violations at the point of decision (#244), hidden removes violating options and marks the hiding (#245), enforced additionally rejects violating writes server-side (#246) — hiding alone is UI cosmetics a scripted client bypasses.
  2. off is the default. Outside a VS context the profile is not a topic: no marking, no card, no behavioural difference. Existing deployments upgrade without noticing the feature exists.
  3. The machine-readable catalog is the single source of truth (packages/shared/src/vs-nfd-profile.ts): every profile-relevant setting with a decidable compliant value (a tiny predicate model — equals, upper bound, non-empty) and its hardening-guide section. Judgement-call entries ("only what the service needs") live in an explicit advisory list. A fence test (pattern of the audit-catalogue fence #201) parses the guide's reference tables and fails when a switch is neither in the catalog nor in the advisory list — the guide keeps its binding maintenance rule, the catalog can never silently lag.
  4. Pond-level opt-ins are deliberately absent (apiEnabled, mcpEnabled): their instance master switches govern; a pond opt-in under a compliant master switch cannot violate the profile on its own. The evaluation and enforcement paths are scope-generic, so pond entries can be added if that judgement changes.
  5. Exposure first (#243): the api evaluates the catalog against the typed settings registry and the validated env and reports mode + verdict on GET /admin/system/vs-nfd-profile; the admin settings view shows the card whenever the mode is not off. The three treatments build on exactly this evaluation.

Consequences

  • The guide gains a second consumer: every new switch line must be triaged (catalog or advisory) or CI fails — a deliberate speed bump, same trade-off as the audit-catalogue fence.
  • Deploy-level means changing the mode requires a deployment change and an api restart; that is the point (role separation, operations handbook §6).
  • The verdict describes decidable entries only; advisory entries remain an assessor's reading of the guide. The card says what deviates, the guide says why it matters.

Implementing issues

#243 (mode, catalog, fence, exposure), #244 (marked), #245 (hidden), #246 (enforced).