All checks were successful
CI / Auth e2e pack (pull_request) Successful in 8m34s
CI / Import/export fidelity gate (pull_request) Successful in 57s
CI / Lint, typecheck, test (pull_request) Successful in 6m19s
CI / Build container images (pull_request) Successful in 1m14s
CD / Build and push images (push) Successful in 17s
CD / Deploy to Test (push) Successful in 15s
CD / Smoke tests against Test (push) Successful in 1m16s
CD / Promote to Int (push) Successful in 12s
CI / Lint, typecheck, test (push) Successful in 6m25s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 8m24s
CI / Import/export fidelity gate (push) Successful in 59s
Stefan reviewed and accepted all nine VS-NfD ADRs one by one. Two adjustments from the review: ADR 0021 decision 3 now states the #216 refinement in the decision itself (PAT/feed-token issuance stays available to IdP-authenticated sessions — API authorization under its own switches, not interactive sign-in) instead of contradicting the later Decisions section; and the ADR 0020 dual-verify window will be removed early (issue #296) rather than waiting for its stated expiry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AUtYMxwTCMHG9mVHnwbFg8
67 lines
3.4 KiB
Markdown
67 lines
3.4 KiB
Markdown
# ADR 0027: VS-NfD hardening-profile mode and configuration catalog
|
|
|
|
- Status: accepted (2026-07-31)
|
|
- 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`).
|