dorfteich/docs/vs-nfd/40-abgrenzungserklaerung.md
Claude Fable 5 2c6eff85f3 #227: hardening guide with the VS-NfD reference configuration
docs/vs-nfd/50-haertungsleitfaden.md: one adoptable profile — every
entry with the exact switch name, value, default and the reason, split
into instance settings (registration closed, api/mcp off, feeds off,
plugins off, classification defaults vs_nfd + upload block, svg reject,
minimal extension list) and deploy-level configuration (empty
BACKUP_ALLOWED_TARGETS enforces backup-local-only outside Site-Admin
reach; tightened session hours; SMTP deliberately unconfigured with the
consequence stated honestly). auth.local.enabled is listed as the one
pending row (#216) with its compensation until then; the guide states
the binding updated-in-same-PR rule for every future switch. Includes
an operator verification checklist (four unauthenticated 404 curls +
readyz + admin spot checks). Cross-referenced from the delimitation
statement (file names made concrete) and consumed by the Grundschutz
mapping (#230).

Co-Authored-By: Claude Fable 5 (1M context) <noreply@anthropic.com>
2026-07-31 10:35:26 +02:00

20 KiB
Raw Permalink Blame History

Abgrenzungserklärung nach §52 VSA — Dorfteich

Liefergegenstand zu Issue #226 (Meilenstein M30, compliance documentation). Grundlage: ADR 0019 (Entwurfsfassung dieser Erklärung); bei inhaltlicher Abweichung wird zuerst das ADR geändert, dann diese Erklärung nachgezogen — nie umgekehrt. Code-Stand der Belege: main = fd07f71 (Prod v0.12.0); Fundorte in der Form datei:zeile beziehen sich auf diesen Stand und sind in docs/vs-nfd/10-ist-aufnahme.md ausführlich hergeleitet. Status: Entwurf zur Prüfung. Die juristische Prüfung durch einen Rechtsbeistand steht aus und ist nicht Teil dieses Dokuments.

1. Zweck und Adressat

Dorfteich soll in einer nach der Verschlusssachenanweisung (VSA) freigegebenen IT-Umgebung einer Behörde betrieben werden können, für Inhalte bis einschließlich VS-NUR FÜR DEN DIENSTGEBRAUCH (VS-NfD). Eine BSI-Zulassung von Dorfteich selbst wird nicht angestrebt.

§51 VSA unterwirft IT-Produkte, die eine Sicherheitsgrundfunktion erbringen, der Zulassungspflicht. §52 VSA benennt diese Grundfunktionen: Verschlüsselung, Datenträgerschutz, Netzabschluss und Authentisierung. Diese Erklärung legt dar, dass Dorfteich keine dieser Grundfunktionen selbst erbringt, welche Partei sie stattdessen erbringt, und wo der heutige Code-Stand dieser Erklärung noch nicht entspricht (Abschnitt 7).

Adressat sind Geheimschutzbeauftragte und IT-Sicherheitsbeauftragte der betreibenden Behörde sowie prüfende Stellen. Die Erklärung ist zugleich die schriftliche Übergabe der Betreiberpflichten (Abschnitt 6): was die Anwendung bewusst nicht leistet, muss die Plattform der Behörde leisten — das ist die Arbeitsteilung, die §52 VSA vorzeichnet, keine Lücke der Anwendung.

2. Geltungsbereich und Betriebsmodell

Die Erklärung gilt für die Anwendung Dorfteich in der Referenz-Zusammensetzung aus deploy/compose/docker-compose.yml: die vier eigenen Dienste web, api, collab und backup sowie die Sidecars PostgreSQL, pandoc und Gotenberg (Caddy optional als Compose-Profil). Vorausgesetzt wird das Betriebsmodell aus ADR 0019:

  • Eine Instanz je Einstufungsniveau. Die Anwendung trennt Einstufungsniveaus nicht selbst; die Trennung geschieht außerhalb der Anwendung durch getrennte Instanzen. Innerhalb einer Instanz kennzeichnet die Anwendung eingestufte Inhalte lediglich (ADR 0022).
  • Die Instanz ist Single-Tenant (33 Prisma-Modelle, kein Mandanten-Modell; Ist-Aufnahme I-35) — Teiche sind Container innerhalb einer Instanz, keine Sicherheitsgrenze zwischen Einstufungsniveaus.
  • Betrieb in der VS-NfD-Referenzkonfiguration des Härtungsleitfadens (#227): lokale Anmeldung aus, Public-API aus, MCP aus, Feeds aus, Plugins aus, Backup nur lokal.

3. Grundsatz

Dorfteich erbringt keine Sicherheitsgrundfunktion im Sinne von §52 VSA. Verschlüsselung, Datenträgerschutz, Netzabschluss und Authentisierung fallen der Plattform des Betreibers zu (ADR 0019).

Das ist Architektur, nicht Unterlassung: Jede dieser Funktionen in der Anwendung selbst würde Dorfteich zum Träger einer Grundfunktion machen und in die Zulassungspflicht nach §51 VSA ziehen. Die Anwendung hält sich deshalb bewusst frei von Inhaltsverschlüsselung, Backup-Verschlüsselung, eigenem MFA und eigenen Krypto-Primitiven — und jeder künftige Funktionsvorschlag wird an ADR 0019 gemessen, bevor er gebaut wird.

Was die Anwendung an Sicherheit selbst beiträgt, ist ein anderer, ihr zufallender Satz von Eigenschaften (Abschnitt 5): zentrales default-closed-Berechtigungsmodell, vollständige Abwesenheit ausgehender Verbindungen, Kennzeichnung eingestufter Inhalte in jedem Ausgabekanal und ein Audit-Trail.

4. Die Grundfunktionen im Einzelnen

Je Grundfunktion: was die Anwendung tut, was sie bewusst nicht tut, und wer die Funktion erbringt. Jede Aussage ist am Code belegt.

4.1 Verschlüsselung

Was die Anwendung tut. Die vollständige Inventur eigener Krypto-Aufrufe (Ist-Aufnahme, Abschnitt 3.1):

Zweck Verfahren Fundort
Passwörter Argon2id (Bibliothek argon2) apps/api/src/users/password.ts:925
Session-Ids SHA-256 über das Token apps/api/src/auth/sessions.service.ts:84
Auth-Tokens (Mail-Flows) SHA-256 apps/api/src/auth/auth-tokens.service.ts:55
PATs SHA-256 apps/api/src/public-api/api-tokens.service.ts:149
Feed-Tokens SHA-256 apps/api/src/public/feed-tokens.service.ts:73
Collab-Tokens (TTL 60 s) HS256-JWT packages/shared/src/token-crypto.ts
Unsubscribe-Tokens HMAC-SHA-256 apps/api/src/notifications/unsubscribe-token.ts

Sämtliche Verfahren dienen der Absicherung von Zugangsdaten und kurzlebigen Tokens — nirgends im Code werden Inhalte ver- oder entschlüsselt.

Was die Anwendung bewusst nicht tut. Keine Verschlüsselung von Inhalten in Datenbank oder Dateisystem (Anhänge liegen unverschlüsselt unter UPLOADS_DIR/<pondId>/<fileId>, apps/api/src/files/file-storage.service.ts:21,25). Keine Backup-Verschlüsselung (apps/backup/, ADR 0015, ADR 0026). Keine TLS-Implementierung. Keine eigenen kryptographischen Primitive über die obige Tabelle hinaus; die vorhandene Token-Signatur wird auf eine geprüfte Bibliothek mit zweckgebundenen Schlüsseln umgestellt (ADR 0020, #188) — eine Verengung bestehender Krypto, keine neue Grundfunktion.

Wer die Funktion erbringt. Die Plattform des Betreibers: Vertraulichkeit ruhender Daten durch Volume- bzw. Festplattenverschlüsselung der Hosts (Datenbank, Upload-Verzeichnis, Backup-Ablage), Transportverschlüsselung durch die vom Betreiber betriebene TLS-Terminierung (Abschnitt 4.3).

4.2 Datenträgerschutz

Was die Anwendung tut. Sie hält die Zahl und Lebensdauer der Datenkopien klein und benennt sie vollständig (Ist-Aufnahme, Abschnitt 3.2): Inhalte liegen ausschließlich in PostgreSQL (fünf Repräsentationen je Seite), Anhänge im Dateisystem, Backups in der konfigurierten Ablage mit konfigurierbarer Retention. Löschung ist zweistufig (Papierkorb → Purge-Job), der Seiten-Purge erfasst Anhänge, Content-Cache, Update-Log und abhängige Tabellen (Ist-Aufnahme I-42). Der PWA-Service-Worker cached keine Inhalte, nur Build-Assets (apps/web/vite.config.ts:1220). Künftig beschränkt die Anwendung, wohin Backups gehen dürfen (Deploy-Allowlist, leere Liste = nur lokal; ADR 0026, #192) — mehr nicht.

Was die Anwendung bewusst nicht tut. Keine Verschlüsselung ruhender Daten (s. 4.1), keine sichere Vernichtung physischer Datenträger, kein Schutz der Endgeräte.

Wer die Funktion erbringt. Der Betreiber: Festplatten-/ Volume-Verschlüsselung der Server, Behandlung und Vernichtung von Datenträgern (einschließlich Backup-Medien) nach den Regeln der Behörde, und — ausdrücklich — der Schutz der Endgeräte:

Inhaltskopie auf dem Endgerät (Betreiberpflicht). Jede im Editor geöffnete Seite wird als Yjs-Dokument in die IndexedDB des Browsers gespiegelt (apps/web/src/editor/use-collab-provider.ts:76, Datenbank dorfteich-page-<pageId>; Ist-Aufnahme I-25). Beim Verlassen der Seite wird die Kopie gelöscht, sobald der Server synchronisiert hat; bei unsynchronisierten Offline-Änderungen bleibt sie absichtlich stehen, und bei einem Browser-Abbruch läuft die Aufräum-Routine nicht. Die Vertraulichkeit dieser Kopie ist Datenträgerschutz des Endgeräts — eine Funktion der Plattform (Endgeräteverschlüsselung, Gerätehärtung nach den VS-NfD-Regeln der Behörde), nicht der Anwendung. Die Anwendung behauptet ausdrücklich nicht, keine Spuren auf Endgeräten zu hinterlassen.

4.3 Netzabschluss

Was die Anwendung tut. Nichts — und das belegbar auch in der Gegenrichtung: Die Anwendung baut keine Verbindungen nach außen auf. Jeder ausgehende Aufruf im Code geht an einen internen Sidecar (PANDOC_URL, GOTENBERG_URL), an den konfigurierten SMTP-Server oder an das konfigurierte Backup-Ziel (Ist-Aufnahme I-31, mit vollständiger Fundortliste). Keine Telemetrie, keine Update-Checks, kein Analytics, kein Crash-Reporting, keine Link-Vorschauen, kein oEmbed, keine externen Schriften, Karten oder Skripte; drawio ist vendored, Mermaid und Excalidraw sind gebündelte Workspace-Pakete, und die CSP default-src 'self' des Web-Tiers würde Nachlader ohnehin blocken.

Was die Anwendung bewusst nicht tut. Keine TLS-Terminierung, keine Netzsegmentierung, keine Firewall-Funktion, kein VPN. Die Dienste bieten unverschlüsseltes HTTP/WebSocket auf ihren Compose-internen Ports an.

Wer die Funktion erbringt. Der Betreiber: Netzabschluss, Zonierung und Zugangskontrolle seines Netzes; TLS-Terminierung am Reverse-Proxy der Behörde. Der Netzplan mit allen Ports und Vertrauensgrenzen ist Gegenstand der Sicherheitsdokumentation (#228); die Vertrauensstellung zum Reverse-Proxy wird in #215 ausgestaltet.

4.4 Authentisierung

Zielbild (das diese Erklärung beschreibt). Authentisierung ist an den Identity-Provider des Betreibers delegiert (ADR 0021): Anmeldung per OIDC Authorization Code mit PKCE gegen den IdP der Behörde (#214), lokale Anmeldung einschließlich Registrierung, Passwort-Reset, PATs und Feed-Tokens per hartem Schalter auth.local.enabled = false vollständig abgeschaltet (#216), Gruppen-/Rollen-Mapping aus dem IdP (#217). MFA, Passwort-Richtlinien und Konto-Lebenszyklus sind damit Sache des IdP.

Was die Anwendung heute tut — und der heutige Stand entspricht dem Zielbild noch nicht (Ist-Aufnahme I-01/I-02, dort als BLOCKIEREND bewertet): Es existiert nur die lokale Anmeldung (Benutzername/Passwort, Argon2id) mit eigener serverseitiger Session-Verwaltung (Session-Id = SHA-256-Hash des Tokens, httpOnly/sameSite: lax/secure-Cookie, apps/api/src/auth/sessions.service.ts, auth.guard.ts:5258). Eine OIDC-Anbindung ist vorbereitet (UserIdentity.provider, apps/api/prisma/schema.prisma:562577), aber nicht implementiert; die lokale Anmeldung ist nicht abschaltbar. Bis #214/#216 umgesetzt sind, ist Dorfteich faktisch Träger der Grundfunktion Authentisierung — die Delta-Liste (Abschnitt 7) weist das als die wichtigste offene Position aus.

Was die Anwendung dauerhaft behält. Die Autorisierung (wer darf welche Inhalte sehen und ändern) bleibt anwendungsseitig — sie ist keine Grundfunktion nach §52 VSA, sondern Fachlogik: zentrales default-closed-Berechtigungsmodell mit deny-wins, durchgesetzt über Guards und abgesichert durch einen Route-Enumeration-Test (apps/api/src/permissions/; Ist-Aufnahme I-33). Die serverseitige Session-Haltung bleibt als Sitzungsverwaltung nach erfolgter Authentisierung ebenfalls bestehen (konfigurierbare Lebensdauer und Idle-Timeout: #190).

Wer die Funktion erbringt. Der Identity-Provider des Betreibers, einschließlich MFA und aller Credential-Richtlinien. Für Umgebungen mit Client-Zertifikaten oder vorgelagerter Proxy-Authentisierung ist #215 der vorgesehene Pfad.

4.5 Integrität (soweit anwendbar)

Integrität ist in §52 VSA keine eigene Grundfunktion, wird hier aber der Vollständigkeit halber abgegrenzt, weil sie zwischen Plattform und Anwendung geteilt ist:

Bei der Anwendung liegt, was nur sie leisten kann (ADR 0019):

  • Kennzeichnung eingestufter Inhalte — nur die Anwendung kennt die Einstufung einer Seite (ADR 0022; Einführung des Metadatums #204/#205, Aufdruck in allen Ausgabekanälen #206#212).
  • Integrität der eigenen Nutzdaten: SHA-256-Prüfsummen auf Anhängen (#199, heute nicht vorhanden — Ist-Aufnahme I-18) und Hash-Pinning für Plugin-Bundles statt Code-Signierung (ADR 0025, #232).

Bei der Plattform liegt die Integrität von Betriebssystem, Container-Runtime, Netz und Datenträgern. Die Reproduzierbarkeit der Auslieferung (Image-Digests #203, Node-Pin #236, Offline-Build #219) ist Zulieferung der Anwendung an die Integritätskette des Betreibers, keine eigene Grundfunktion.

5. Was die Anwendung selbst beiträgt

Die Sicherheitsleistung der Anwendung besteht — neben der Abwesenheit der Grundfunktionen — aus vier Eigenschaften, die sie selbst trägt und belegt:

  1. Zentrales Berechtigungsmodell, default-closed, deny-wins, mit Route-Enumeration-Test; auch Export, Suche, MCP und die Collab-Ebene laufen über den zentralen PermissionService (Ist-Aufnahme I-33, I-41; unautorisierte Reads antworten 404, Existenz wird versteckt).
  2. Keine ausgehenden Verbindungen außer Sidecars, SMTP und Backup-Ziel (Ist-Aufnahme I-31) — die Grundlage der Airgap-Tauglichkeit, deren empirischer Nachweis als Testlauf #220 geführt wird.
  3. Kennzeichnung eingestufter Inhalte in jedem Ausgabekanal (ADR 0022, #204#212 — geplant, s. Delta-Liste).
  4. Audit-Trail für Authentisierungs- und Administrations-Ereignisse (audit_log, apps/api/src/audit/audit.service.ts), künftig mit konfigurierbarer Retention (#196), stabilem Ereigniskatalog für SIEM-Anbindung (#201) und einem zuschaltbaren Lesetrail für eingestufte Inhalte (ADR 0023, #222#225). Logs gehen als pino-JSON auf stdout mit Redaction von authorization/cookie (apps/api/src/app.module.ts:8493); die Weiterleitung ins SIEM ist bewusst Sache der Container-Runtime des Betreibers.

6. Betreiberpflichten (Übergabe)

Aus der Arbeitsteilung folgt, was der Betreiber leisten muss. Diese Liste ist die schriftliche Übergabe; die Referenzkonfiguration und die Prüf-Checkliste dazu liefert der Härtungsleitfaden (#227):

Nr. Pflicht Grundfunktion
B1 Volume-/Festplattenverschlüsselung der Hosts für Datenbank, Upload-Verzeichnis und Backup-Ablage Verschlüsselung
B2 TLS-Terminierung vor der Anwendung; kein unverschlüsselter Zugriff außerhalb der Compose-internen Netze Verschlüsselung
B3 Netzabschluss, Zonierung und Zugangskontrolle; Egress-Blockade bis auf SMTP und ggf. Backup-Ziel Netzabschluss
B4 Identity-Provider einschließlich MFA, Passwort-Richtlinien und Konto-Lebenszyklus (sobald #214/#216 umgesetzt; bis dahin s. Delta-Liste) Authentisierung
B5 Endgeräteschutz einschließlich Geräteverschlüsselung — Seiteninhalte liegen als IndexedDB-Kopie auf jedem Endgerät, das sie geöffnet hat (s. 4.2) Datenträgerschutz
B6 Behandlung und Vernichtung von Datenträgern und Backup-Medien nach den Regeln der Behörde Datenträgerschutz
B7 Betrieb einer Instanz je Einstufungsniveau; keine Mischinstanz (Betriebsmodell)
B8 Log-Weiterleitung und -Aufbewahrung (stdout → SIEM/Syslog der Behörde) (Protokollierung)
B9 Betrieb in der VS-NfD-Referenzkonfiguration (#227) und Nachvollzug von Abweichungen (Konfiguration)

7. Delta-Liste — wo der heutige Stand dieser Erklärung noch nicht entspricht

Diese Erklärung beschreibt das Zielbild. Am Code-Stand fd07f71 bestehen folgende Abweichungen; jede ist einem Issue zugeordnet, das sie schließt (Meilensteine M24M31, Herleitung docs/vs-nfd/10-ist-aufnahme.md):

Abweichung vom Zielbild Befund Issue
Lokale Anmeldung ist der einzige und nicht abschaltbare Auth-Pfad — Grundfunktion liegt noch in der Anwendung I-01, I-02 #214, #216
IdP-Gruppen-/Rollen-Mapping fehlt I-01 #217
Kein Einstufungsmetadatum, kein Aufdruck in irgendeinem Ausgabekanal I-03, I-04 #204#212
Backup-Ziel frei wählbar (keine Allowlist, kein Deploy-Kill-Switch) I-11 #192
Ein Secret signiert zwei Token-Zwecke; JWT handgeschrieben statt Bibliothek I-06, I-07 #188
CSRF-Origin-Prüfung fail-open bei fehlenden Headern I-08 #189
Session 30 Tage gleitend, hart kodiert, ohne Idle-Timeout I-09 #190
Feed-Token im Query-Parameter; Feeds nicht abschaltbar I-10 #191
Plugins nicht instanzweit abschaltbar I-19 #200
Keine Security-Response-Header, CORS-Haltung nicht als Entscheidung dokumentiert I-16 #197
Keine Integritäts-Prüfsummen auf Anhängen I-18 #199
Kein Plugin-Hash-Pinning #232
audit_log ohne Retention; Ereigniskatalog nicht stabil; kein Lesetrail I-15, I-20, I-21 #196, #201, #222#225
Teich-Papierkorb ohne endgültiges Löschen; Papierkorb-Inhalte im Suchindex I-12, I-14 #193, #195
Rohdokument-Bytes und Mail-Outbox unbefristet; Slug-Residuum nach Purge I-22I-24 #233#235
Container-Images nicht per Digest gepinnt, Node-Version nicht gepinnt, Airgap unverifiziert I-05, I-26, I-28 #203, #218#221, #236

Bewusst offene Punkte, die keine Abweichung, sondern akzeptierte Restrisiken sind (z. B. Seitentitel in Logs und Digest-Mails, Slug-Residuum falls in #235 so entschieden), führt die Restrisikoliste (#231) — nicht diese Erklärung.

8. Pflege dieser Erklärung

  • Maßgeblich ist ADR 0019; Abweichungen werden dort aufgelöst, diese Erklärung folgt dem ADR.
  • Jedes Feature, das die Anwendung zum Träger einer Grundfunktion machen würde, erfordert zuerst eine Änderung von ADR 0019 — und damit dieser Erklärung.
  • Die Delta-Liste (Abschnitt 7) wird mit jedem geschlossenen Issue gekürzt; die Erklärung ist erst dann uneingeschränkt gültig, wenn die Delta-Liste leer ist oder alle Restpositionen in der Restrisikoliste (#231) vom Betreiber gebilligt sind.
  • Querbezüge: Härtungsleitfaden (#227, 50-haertungsleitfaden.md), Sicherheitsdokumentation (#228, 60-sicherheitsdokumentation.md), Betriebshandbuch (#229, 70-betriebshandbuch.md), IT-Grundschutz-Zuarbeit (#230, 80-grundschutz-mapping.md), Restrisikoliste (#231, 90-restrisiken.md).