From 2c6eff85f399860502829e5afb3659d48fdb206b Mon Sep 17 00:00:00 2001 From: Claude Fable 5 Date: Fri, 31 Jul 2026 09:59:27 +0200 Subject: [PATCH 1/2] #227: hardening guide with the VS-NfD reference configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- docs/vs-nfd/20-massnahmenplan.md | 6 +- docs/vs-nfd/40-abgrenzungserklaerung.md | 7 +- docs/vs-nfd/50-haertungsleitfaden.md | 94 +++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 docs/vs-nfd/50-haertungsleitfaden.md diff --git a/docs/vs-nfd/20-massnahmenplan.md b/docs/vs-nfd/20-massnahmenplan.md index f4aad76..5765811 100644 --- a/docs/vs-nfd/20-massnahmenplan.md +++ b/docs/vs-nfd/20-massnahmenplan.md @@ -184,9 +184,9 @@ nach sich zieht. - [x] **Abgrenzungserklärung §52 VSA** — welche Sicherheitsgrundfunktionen die Anwendung _nicht_ erbringt und wem sie zufallen. Wichtigstes Einzeldokument. · 3 AT · #226 → `40-abgrenzungserklaerung.md` -- [ ] **Härtungsleitfaden** mit Referenzkonfiguration „VS-NfD-Betrieb": - lokale Auth aus, Public-API aus, MCP aus, Feeds aus, Plugins aus, - Backup nur lokal · 3 AT · #227 +- [x] **Härtungsleitfaden** mit Referenzkonfiguration „VS-NfD-Betrieb": + lokale Auth aus (Zeile ⏳ bis #216), Public-API aus, MCP aus, Feeds aus, + Plugins aus, Backup nur lokal · 3 AT · #227 → \`50-haertungsleitfaden.md\` - [x] **Sicherheitsdokumentation**: Architektur, Datenflüsse, Netzplan, Ports/Dienste, Vertrauensgrenzen · 4 AT · #228 → `60-sicherheitsdokumentation.md` - [x] **Betriebshandbuch**: Installation (inkl. Airgap), Update, Backup/Restore, diff --git a/docs/vs-nfd/40-abgrenzungserklaerung.md b/docs/vs-nfd/40-abgrenzungserklaerung.md index 21fc2bd..382b0cb 100644 --- a/docs/vs-nfd/40-abgrenzungserklaerung.md +++ b/docs/vs-nfd/40-abgrenzungserklaerung.md @@ -313,5 +313,8 @@ Slug-Residuum falls in #235 so entschieden), führt die Restrisikoliste 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), Sicherheitsdokumentation (#228), - Betriebshandbuch (#229), IT-Grundschutz-Zuarbeit (#230). +- 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`). diff --git a/docs/vs-nfd/50-haertungsleitfaden.md b/docs/vs-nfd/50-haertungsleitfaden.md new file mode 100644 index 0000000..6323c22 --- /dev/null +++ b/docs/vs-nfd/50-haertungsleitfaden.md @@ -0,0 +1,94 @@ +# Härtungsleitfaden — Referenzkonfiguration „VS-NfD-Betrieb" (Issue #227) + +Zweck: **eine** benannte Konfiguration, die ein Betreiber als Ganzes +übernehmen kann. Jeder Eintrag nennt den exakten Schalter, den Wert und +das **Warum** — wer abweicht, tut es wissentlich. Der Leitfaden macht +zugleich die in M1/M2/M4 gebauten Schalter prüfbar. + +**Pflegeregel (verbindlich):** Jeder PR, der einen neuen Instanz- oder +Deploy-Schalter einführt, ergänzt diesen Leitfaden **im selben PR** um +dessen Referenzwert. Ein Schalter ohne Leitfaden-Zeile gilt im Review +als unvollständig. (Gleiches Muster wie der Ereigniskatalog-Zaun #201.) + +Geltungsbereich: Konfiguration der Anwendung. Die Härtung der Plattform +(Betriebssystem, Netz, Reverse Proxy, Datenträger) ist Betreibersache +(Abgrenzungserklärung `40-abgrenzungserklaerung.md` — von dort wird +hierher verwiesen; das IT-Grundschutz-Mapping +`80-grundschutz-mapping.md` nimmt diese Referenzkonfiguration als +Produkt-Beleg). + +--- + +## 1 Referenzkonfiguration + +### 1.1 Instanz-Settings (Site-Admin → Einstellungen; Tabelle `instance_settings`) + +Nach jeder Änderung an Instanz-Settings die api neu starten — der +Settings-Cache ist in-process (operations.md). + +| Setting | Referenzwert | Default | Warum | +| ----------------------------------------------------------------------------------------------------------- | --------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `auth.registrationMode` | `closed` | `open` | Konten entstehen in einer VS-Umgebung nur kontrolliert; Selbstregistrierung öffnet den Nutzerkreis unkontrolliert. | +| `api.enabled` | `false` | `false` | Public REST API ist ein zusätzlicher Egress-Kanal; ohne dokumentierten Bedarf bleibt er zu (404 auf allen `/api/public/v1`-Routen). | +| `mcp.enabled` | `false` | `false` | gleiches Argument für den MCP-Endpoint (`/api/mcp`); unabhängiger Schalter. | +| `feeds.enabled` | `false` | `true` | **explizit setzen** — Atom-Feeds liefern Inhalte an Reader außerhalb der Kontrolle der Instanz (Feed-Token umgehen die Session); Kopien in Feed-Readern sind nicht einholbar (Kopienliste, Sicherheitsdokumentation §5). Schaltet Routen UND Feed-Token-Verwaltung auf 404. | +| `plugins.enabled` | `false` | `true` | **explizit setzen** — kein Fremdcode in der VS-Zone (#200): alle Plugin-Flächen 404, Dropzone quarantänisiert; bestehende Blöcke degradieren zu ihrem deklarierten Text-Fallback. Hash-Pinning ist verschoben (#232, Restrisikoliste) — der Kill-Switch deckt das Risiko für diesen Betriebsmodus vollständig. | +| `classification.newPageDefault` | `vs_nfd` | `unclassified` | in einer VS-NfD-Instanz beginnt nichts unmarkiert (#204); die Vererbung (#205) hält den Baum konsistent. | +| `classification.uploadPolicy` | `block` | `warn` | Anhänge können die Kennzeichnung im Inhalt nicht tragen (#212) — die Referenzkonfiguration lehnt Uploads auf eingestufte Seiten serverseitig ab (403 `classified_upload_blocked`, #213) statt nur zu warnen. | +| `upload.svgPolicy` | `reject` | `sanitize` | SVG ist aktiver Inhalt; die Sanitisierung ist gut getestet, aber Ablehnen ist die kleinere Angriffsfläche. Abweichung vertretbar, wenn SVG gebraucht wird. | +| `upload.allowedExtensions` | nur das dienstlich Nötige (z. B. `pdf`) | Standardliste | jede zusätzliche Endung vergrößert die Menge nicht prüfbarer Binärformate im Bestand. Bilder sind davon unabhängig immer erlaubt (Magic-Byte-geprüft). | +| `backup.nextcloud.enabled` | `false` | `false` | „Backup nur lokal": kein Anwendungs-Upload von Restore-Sets zu Drittdiensten. Fernspiegel regelt ausschließlich die Deploy-Allowlist (1.2). | +| `trash.retentionDays`, `audit.retentionDays`, `conversion.payloadRetentionDays`, `mail.outboxRetentionDays` | Defaults (30/365/30/30) | ebd. | Aufbewahrung bewusst begrenzt; Verkürzung nach Betreiber-Löschkonzept zulässig (Betriebshandbuch §5). | +| `legal.imprint`, `legal.privacyPolicy` | befüllt | leer | Betreiberpflicht; leere Seiten zeigen einen Warnbanner. | + +### 1.2 Deploy-Konfiguration (`.env` / Compose — nur Plattformzugriff, bewusst nicht per Admin-UI) + +| Variable | Referenzwert | Warum | +| ----------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `BACKUP_ALLOWED_TARGETS` | leer lassen **oder** exakt der eine freigegebene Spiegel-Host | leere Allowlist schaltet ALLE Fernziele hart ab (ADR 0026, #192) — „Backup nur lokal" ist damit deploy-seitig erzwungen und vom Site-Admin nicht aufweichbar (Rollentrennung, Betriebshandbuch §6). | +| `SESSION_ABSOLUTE_HOURS` | `12` (Default 168) | eine Sitzung überdauert keinen Arbeitstag; Neuanmeldung am nächsten Tag ist der Preis. | +| `SESSION_IDLE_HOURS` | `2` (Default 72) | unbeaufsichtigte, noch angemeldete Arbeitsplätze fallen schnell zurück auf die Anmeldemaske. | +| `SMTP_HOST` etc. | **unkonfiguriert lassen** (oder internes Relay) | ohne SMTP verlassen keinerlei Inhaltstitel die Instanz per Mail (Digest-Restrisiko I-23 entfällt vollständig). Konsequenz ehrlich benannt: dann gibt es keine Verifikations- und Passwort-Reset-Mails — Kontenpflege läuft über den Site-Admin. Wer Mail braucht, nutzt ein internes Relay und akzeptiert I-23 (Restrisikoliste). | +| `WEB_PORT`/`API_PORT`/`COLLAB_PORT` | Defaults (127.0.0.1-gebunden) | Anwendungscontainer sind nie direkt exponiert; einzige Eintrittsstelle ist der Reverse Proxy (Sicherheitsdokumentation §2). | +| `LOG_LEVEL` | `info` | Audit-Zeilen (`audit: `-Präfix) müssen den Collector erreichen; `debug` nur zur Störungssuche. | + +### 1.3 Noch nicht verfügbar (Regel: landet hier im selben PR) + +| Schalter | Referenzwert (geplant) | Status | +| -------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `auth.local.enabled` | `false` — lokale Passwort-Auth aus, Anmeldung nur über die Fremdauthentisierung der Behörde | ⏳ kommt mit #216 (M27); bis dahin bleibt lokale Auth der einzige Anmeldeweg und `auth.registrationMode=closed` + Session-Verkürzung sind die Kompensation. Zeile wird im #216-PR scharfgestellt. | + +## 2 Verifikations-Checkliste + +Auf der laufenden Instanz (ersetze `HOST`); Erwartung jeweils dahinter. +Die vier 404-Prüfungen laufen unauthentifiziert: + +```sh +curl -s -o /dev/null -w '%{http_code}\n' https://HOST/api/public/v1/ponds # 404 (api.enabled=false) +curl -s -o /dev/null -w '%{http_code}\n' -X POST https://HOST/api/mcp # 404 (mcp.enabled=false) +curl -s -o /dev/null -w '%{http_code}\n' https://HOST/api/v1/public/IRGENDEIN-TEICH/feed.xml # 404 (feeds.enabled=false) +curl -s -o /dev/null -w '%{http_code}\n' https://HOST/api/v1/admin/plugins # 401/404, nie 200 ohne Session +curl -s https://HOST/api/v1/readyz # status ok +``` + +Als Site-Admin (UI → Administration bzw. `GET /api/v1/admin/settings`): + +- [ ] Registrierung „geschlossen"; neue Seite entsteht mit Kennzeichnung + (Einstufung neuer Seiten = VS-NfD); Upload auf eingestufte Seite + wird abgelehnt (403). +- [ ] Plugin-Verwaltung antwortet 404 (Kill-Switch aktiv). +- [ ] Backup-Panel zeigt keine aktiven Fernziele; auf dem Host ist + `BACKUP_ALLOWED_TARGETS` leer bzw. exakt der freigegebene Spiegel. +- [ ] Eine Testsitzung läuft nach `SESSION_IDLE_HOURS` Inaktivität ab. +- [ ] Kennzeichnungs-Stichprobe: eingestufte Seite zeigt den Aufdruck in + Web, Druckvorschau und PDF-Export (Konventionen: Kommentare auf + Issue #228 bzw. `60-sicherheitsdokumentation.md` §3.5). + +## 3 Querbezüge + +Abgrenzungserklärung (`40-abgrenzungserklaerung.md`, verweist hierher); +IT-Grundschutz-Mapping (`80-grundschutz-mapping.md`, nutzt dieses +Profil als Produkt-Beleg); Betriebshandbuch (`70-betriebshandbuch.md`, +Installation §1 wendet dieses Profil an); Restrisikoliste +(`90-restrisiken.md` — Abweichungen von der Referenzkonfiguration +gehören dorthin, wenn sie dauerhaft sind). -- 2.45.2 From 87c1c5ee88e0212d985e85367c680562f82be89b Mon Sep 17 00:00:00 2001 From: Claude Fable 5 Date: Fri, 31 Jul 2026 10:01:11 +0200 Subject: [PATCH 2/2] #231: residual-risk list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit docs/vs-nfd/90-restrisiken.md: nine entries, each with risk, why it is accepted, compensating control and decider — unmarked attachment content (#212), local auth not yet switchable incl. the open runtime- flippability question (#216), deferred plugin hash pinning (#232), the one-time git-history secret check with its pattern caveat (#198), digest-mail titles (I-23, revisit M32), page_links slug residue (I-24), the IndexedDB endpoint copy (I-25), deliberately unscheduled features, and the Site-Admin read bypass. Binding same-PR maintenance rule stated; referenced from the delimitation statement and consumed by the Grundschutz mapping. Co-Authored-By: Claude Fable 5 (1M context) --- docs/vs-nfd/20-massnahmenplan.md | 2 +- docs/vs-nfd/90-restrisiken.md | 154 +++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 docs/vs-nfd/90-restrisiken.md diff --git a/docs/vs-nfd/20-massnahmenplan.md b/docs/vs-nfd/20-massnahmenplan.md index 5765811..f1bdafe 100644 --- a/docs/vs-nfd/20-massnahmenplan.md +++ b/docs/vs-nfd/20-massnahmenplan.md @@ -194,7 +194,7 @@ nach sich zieht. (Airgap-Kapitel verweist auf offene #218–#221) - [ ] **Zuarbeit IT-Grundschutz** APP.3.1 und CON.11.1, je Anforderung „Produkt / Betreiber / nicht anwendbar" · 3–4 AT · #230 -- [ ] **Restrisikoliste** mit bewusst offenen Punkten · 1 AT · #231 +- [x] **Restrisikoliste** mit bewusst offenen Punkten · 1 AT · #231 → `90-restrisiken.md` --- diff --git a/docs/vs-nfd/90-restrisiken.md b/docs/vs-nfd/90-restrisiken.md new file mode 100644 index 0000000..f6e76c7 --- /dev/null +++ b/docs/vs-nfd/90-restrisiken.md @@ -0,0 +1,154 @@ +# Restrisikoliste (VS-NfD, Issue #231) + +Zweck: benennen, was **bewusst** offen bleibt. Ein Prüfer, der eine +Lücke hier bereits verzeichnet findet, kann ihr zustimmen; eine +unverzeichnete Lücke diskreditiert die gesamte Einreichung. Jeder +Eintrag nennt das Risiko, warum es akzeptiert ist, die kompensierende +Kontrolle und wer entschieden hat. + +**Pflegeregel (verbindlich):** Schließt ein Issue mit einem wissentlich +offenen Rest, wird diese Liste **im selben PR** ergänzt. Die formale +Billigung der Einträge durch den jeweiligen Betreiber ist Teil seiner +Risikoübernahme (Abgrenzungserklärung §8) — Bewertung/Scoring ist +bewusst nicht Teil dieser Liste. + +Entscheidungsvermerk: „Projektleitung" = Stefan Waidele; +Entscheidungen sind über die genannten PRs/Issues/ADRs im Repository +nachvollziehbar. + +--- + +## R-01 Attachment-Inhalt trägt keine interne Kennzeichnung + +- **Risiko:** Eine heruntergeladene, umbenannte Datei (bzw. eine ohne + Begleitdatei weitergegebene) ist ein eingestuftes Binärobjekt ohne + sichtbare Kennzeichnung. +- **Warum akzeptiert:** Kennzeichnung **in** beliebige Binärformate zu + schreiben hieße, fremde Formate umzuschreiben — ausgeschlossen durch + ADR 0019/0022 (keine Übernahme von Grundfunktions-/Formatgarantien). +- **Kompensation:** Download-Präfix `VS-NfD_` + Begleitdatei/Manifest + im ZIP (#212); alle internen Darstellungen und alle übrigen + Exportkanäle kennzeichnen selbst (#206–#211); Upload-Warnung bzw. + serverseitiger Block (#213); organisatorische VS-Handhabung beim + Empfänger. +- **Entscheidung:** Projektleitung, PR #271 / Issue #212, 31.07.2026. + +## R-02 Lokale Passwort-Authentifizierung noch nicht abschaltbar + +- **Risiko:** Bis #216 (M27) existiert kein Schalter + `auth.local.enabled=false`; die Anwendung führt eigene + Passwort-Konten, obwohl die Behördenumgebung Fremdauthentisierung + vorsieht. Zusätzlich ist noch offen, ob der Schalter zur Laufzeit + umschaltbar sein wird oder einen Neustart verlangt — das entscheidet + #216 und trägt es hier nach. +- **Warum akzeptiert:** Reihenfolge der Umsetzung (M26 vor M27); + produktiver VS-NfD-Betrieb beginnt erst nach M27. +- **Kompensation:** Referenzkonfiguration (`50-haertungsleitfaden.md`): + Registrierung geschlossen, kurze Sessions (12 h absolut / 2 h idle), + Argon2id-Hashes, Rate-Limits, Audit der Anmeldungen. +- **Entscheidung:** Projektleitung, Maßnahmenplan Rev. 2 (M27-Planung), + 30.07.2026. + +## R-03 Plugin-Hash-Pinning verschoben + +- **Risiko:** Installierte Plugin-Pakete sind nicht gegen einen + festgeschriebenen Hash verankert (#232); ein manipuliertes Paket + gleichen Namens wäre beim Neuinstallieren nicht erkennbar. +- **Warum akzeptiert:** Die Referenzkonfiguration betreibt Plugins + **gar nicht** (`plugins.enabled=false`, #200) — der Kill-Switch deckt + den VS-NfD-Betriebsmodus vollständig; Pinning lohnt erst, wenn ein + Betreiber Plugins tatsächlich freigibt. +- **Kompensation:** Kill-Switch (alle Plugin-Flächen 404, Dropzone + quarantänisiert); Sandbox mit Capability-Modell + CI-Escape- + Regressionstest (ADR 0008/0025); Install nur durch Site-Admin. +- **Entscheidung:** Projektleitung, ADR 0025 / Issue #232, 30.07.2026. + +## R-04 Git-Historie: einmalige Secret-Prüfung mit begrenztem Muster + +- **Risiko:** Die einmalige Prüfung der gesamten Repository-Historie + (#198, 30.07.2026) fand **keine** getrackten `.env`-Dateien und + **keine** Treffer der Muster Private-Key-Block / AKIA / ghp\_ / + glpat- / xox[baprs]-. Unstrukturierte Passwörter als schlichte + Strings würde ein generisches Muster jedoch nicht finden. +- **Warum akzeptiert:** Ein Negativbeweis über beliebige Strings ist + nicht führbar; das strukturierte Muster deckt die realistischen + Token-Formate. +- **Kompensation:** CI-Zaun „No tracked .env files or secret material" + auf jedem PR (#198) hält beide Invarianten ab jetzt; Review-Disziplin + - Regel „Passwörter nie als CLI-Argument/Commit". +- **Entscheidung:** Projektleitung, Issue #198, 30.07.2026 (Protokoll + als Kommentar auf #231). + +## R-05 Digest-/Benachrichtigungs-Mails tragen Seitentitel (I-23) + +- **Risiko:** Zugestellte Mails enthalten Titel (Inhalts-Metadaten) + eingestufter Seiten und liegen beim Empfänger außerhalb der Instanz. +- **Warum akzeptiert:** Es gab bis M26 kein Einstufungs-Metadatum für + eine Unterdrückung; die titelbasierte Unterdrückung wird in M32 + (#243–#246, `VS_NFD_MODE`) revisitiert. +- **Kompensation:** Kopie zeitlich begrenzt + (`mail.outboxRetentionDays`, #234); Referenzkonfiguration lässt SMTP + unkonfiguriert — dann verlässt kein Titel die Instanz per Mail + (`50-haertungsleitfaden.md` §1.2). +- **Entscheidung:** Projektleitung, PR #255 / Issue #234, 30.07.2026; + Revisit-Marker M32. + +## R-06 `page_links.target_slug` überlebt den Ziel-Purge (I-24) + +- **Risiko:** Nach dem endgültigen Löschen einer Seite bleibt ihr Slug + (≈ Titel) als Linkziel-Text in den Zeilen verweisender Seiten. +- **Warum akzeptiert:** Der Slug steht ohnehin sichtbar im Inhalt der + verweisenden Seite (deren Autor das Ziel lesen durfte); die Zeile zu + löschen entfernte nichts Sichtbares, bräche aber die gewollte + Phantom-Link-Reauflösung. +- **Kompensation:** Zugriff auf die verweisende Seite bleibt + permissions-geprüft; vollständige Begründung in + `docs/architecture/operations.md` (Purge-Abschnitt). +- **Entscheidung:** Projektleitung, PR #256 / Issue #235, 30.07.2026. + +## R-07 Offline-Kopie im Browser (IndexedDB, I-25) + +- **Risiko:** Der Editor hält zuletzt geöffnete Seiten als + Yjs-Offline-Kopie in der IndexedDB des Endgeräts + (`apps/web/src/editor/use-collab-provider.ts`); sie übersteht + Browser-Crashes und existiert für unsynchronisierte Offline-Edits. +- **Warum akzeptiert:** Die Kopie ist Voraussetzung für + verlustfreies kollaboratives Arbeiten (CRDT) und liegt in der + Endgeräte-Zone, deren Schutz (Festplattenverschlüsselung, + Gerätekontrolle) nach Abgrenzungserklärung ohnehin der Plattform- + bzw. Organisationsverantwortung zufällt. +- **Kompensation:** VS-Endgeräte-Vorgaben des Betreibers + (Datenträgerverschlüsselung, kontrollierte Geräte); kurze Sessions + (Referenzkonfiguration) begrenzen den angemeldeten Zeitraum. +- **Entscheidung:** Projektleitung, Ist-Aufnahme I-25 + (`10-ist-aufnahme.md`), 29.07.2026. + +## R-08 Bewusst nicht geplante Funktionen + +- **Risiko/Inhalt:** Externe Suchengine (Suche bleibt in Postgres), + Admin-Freigabe von Selbstregistrierungen, Plugin-Netzwerk-Allowlist — + bewusst unscheduled. +- **Warum akzeptiert:** Kein Bedarf im Zielbetrieb: die + Referenzkonfiguration schließt Selbstregistrierung und Plugins ohnehin + aus; die interne Suche vermeidet einen weiteren Dienst mit + Inhaltskopie (die Kopienliste bliebe sonst nicht klein). +- **Kompensation:** entfällt (kein zusätzliches Risiko gegenüber dem + Status quo; Wiedervorlage bei realem Bedarf). +- **Entscheidung:** Projektleitung, Projektplanung (dokumentiert im + Workspace-Handoff), Stand 07/2026. + +## R-09 Site-Admin liest jeden Inhalt (Rollen-Bypass) + +- **Risiko:** Die App-Rolle Site-Admin umgeht die Permission-Resolution + vollständig (permissions.md) — App-seitig gibt es keine absolute + Trennung zwischen Plattform-Betrieb und Inhalts-Kenntnisnahme. +- **Warum akzeptiert:** Ein Admin ohne Durchgriff könnte zentrale + Pflichten (Purge, Quoten, Störungsanalyse) nicht erfüllen; eine + echte Trennung wäre eine neue Grundfunktion (ADR 0019). +- **Kompensation:** organisatorisch (Vergabe der Rolle nach + Need-to-know, Vier-Augen-Prinzip); Lesetrail für eingestufte Inhalte + macht Zugriffe nachvollziehbar (M29, #222–#225 — bis dahin trägt der + bestehende Audit-Trail nur Verwaltungsereignisse); Betriebshandbuch + §6 benennt die Grenze ausdrücklich. +- **Entscheidung:** Projektleitung, permissions.md-Design (Issue #51) + bzw. Aufnahme hier, 31.07.2026. -- 2.45.2