From 0e4ceed01af4cbb6da68cd4421477d2bd52311a2 Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 22 Sep 2026 00:52:40 +0200 Subject: [PATCH] Gesamtprojekt: Pruefprotokoll Nachtrag 10 (#109/#108, Token-Modus-Smoke mit echtem Kontodienst, QA und Entscheidungen) Co-Authored-By: Claude Sonnet 5 --- docs/GESAMTPROJEKT-PRUEFPROTOKOLL.md | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/GESAMTPROJEKT-PRUEFPROTOKOLL.md b/docs/GESAMTPROJEKT-PRUEFPROTOKOLL.md index e829421b..f8260441 100644 --- a/docs/GESAMTPROJEKT-PRUEFPROTOKOLL.md +++ b/docs/GESAMTPROJEKT-PRUEFPROTOKOLL.md @@ -122,3 +122,58 @@ Fix-Iterationen: 1 (Testfehler im neuen Vertragstest: Fremd-Mandanten-Client sen **Vertragslücken Core↔DMS:** (1) JWKS-Route, (2) Rolle im Modul-JWT, (3) `dms.*`-Rechte, (4) `GET /legal-hold` sind geschlossen (siehe PR #106, #107). Weiter offen: Mandant und Modulaktivierung in `POST /authorize` (Ticketvorschlag RBAC-10), persistente Modul-Schlüssel (API-16), Token-Widerruf, Oberflächen im Token-Modus (Login → Bearer), Reverse-Proxy-Regel für die JWKS-Route, DMS-Entscheidung zu `registered:false`, Testisolation der Mail-Pakete (Zustand in der gemeinsamen DB), Core-Testisolation. **Zu beachten:** `core-cluster.sh` ist jetzt gegen versehentliches Stoppen abgesichert (`stop` ist ein No-Op, `FORCE=1` erzwingt), `reset`/`resettenant` sind nur innerhalb der Sperre `runhost-locks-204` zu verwenden. + +## 10. Nachtrag: #109 (API-16), #108 (RBAC-10) und Token-Modus-Smoke mit echtem Kontodienst (Stand 2026-09-22) + +**Merges** (`integration/gesamtprojekt`, Reihenfolge #109, #108): beide konfliktfrei (`1e3ec00`, `7238181`). Migrationsstand: Core Registry 30 (`0012_dms_module_scopes` aus RBAC-10), Core Mandant 18 (`0008_module_signing_keys` aus API-16, andere Verzeichnisse, keine Kollision), DMS 32, Archive 15, Mail 12 (Postgres). Nichts umbenannt. `scripts/e2e-core-dms.sh` enthält beide Änderungen (Mandanten-/Modulfälle und Verschlüsselungsschlüssel). + +**Prüfungen auf 204** (frische Klone des gepushten Branches, seriell, Sperre `runhost-locks-204`, Wegwerf-Cluster `17/coredev`, `archivdms`-Cluster nicht berührt): + +| Prüfung | Ergebnis | +|---|---| +| Core `build`, `vet` | sauber (13 Bestands-Dateien unformatiert, keine geänderte) | +| Core Tests je Paket mit Cluster-Reset | alle 53 Pakete `ok`, 0 FAIL | +| Archive `build`, `vet`, `test -p 1` | sauber, 28 Pakete `ok` | +| Mail `build`, `vet`, `test -p 1` | sauber; `indexworker` 2 FAIL (`TestDequeue_WorkerCrashMidRunLosesNoJob`, `TestEnqueueAndStatus_RoundTrip`), Bestandsfehler (Zustand zwischen Mail-Paketen in der gemeinsamen Datenbank, identisch vor allen Merges, allein grün), nicht repariert | +| DMS `go test ./...` (mit `TEST_KOSIT_ADDR`), nach der Guard-Änderung | 75 Pakete `ok`, 0 FAIL | +| `check-port-defaults.sh`, `check-route-prefixes.sh` | ok | +| `legalhold-contract-test.sh` ohne und mit `LH_TOKEN` | bestanden | +| `e2e-core-dms.sh` | bestanden | +| `e2e-module-keys.sh` | 8 von 8 (Neustart mit derselben KID, zwei Instanzen, Rotation, Ausfall) | +| `migrations-fresh-check.sh` | Core Registry 30, Core Mandant 18, DMS 32, Archive 15, Mail 12; 88 Tabellen in der gemeinsamen Mandanten-DB | + +**Hauptnachweis: Token-Modus-Smoke mit ECHTEM Core-Kontodienst** (`scripts/gesamt-token-smoke.sh`, Modus `core` in `scripts/fdn19_smoke.py`, Zusatzprüfungen `scripts/gesamt_token_smoke.py`). Laufende Prozesse als transiente Units `nexarch-gesamt-*` (eigener Benutzer, Loopback, MemoryMax/CPUQuota): echter Kontodienst (Login, Modul-Token, JWKS, persistente Schlüssel), zweiter Kontodienst für einen anderen Mandanten, echter Policy-Dienst (mit Flag `dms`), `dms-app` und `dms-worker` im Token-Modus, gemeinsame Wegwerf-Mandanten-DB mit Core- und DMS-Migrationen, eigener Suchindex `dms_gesamt_smoke`, KoSIT-Validator (nexarch-dms-kosit). Schlüsselbezug (KEK) und Nutzungsmeldung laufen weiter über den Stellvertreter, weil `kek-api` nicht Teil dieses Laufs ist. + +| Bereich | Ergebnis | +|---|---| +| Lebenszyklus (Health, OpenAPI, Migrationen, Upload, OCR, Suche, Facetten, gespeicherte Suche, E-Rechnung mit KoSIT, Download mit signierter URL, Tags, Papierkorb, Löschschutz mit Audit, Mandantentrennung, Audit-Kette, CMIS, Tokenfehler) | 45 von 45 | +| Rollen `user` und `tenant_admin` (`/audit-log`, `/auto-rules`, `/ocr/review`, `/trash/purge`, Standardrolle lädt hoch) | 9 von 9 | +| Neustart des Kontodienstes: Token von vorher gültig, JWKS mit derselben KID, Neu-Login (API-16) | 4 von 4 | +| Modul `dms` im Mandanten abwählen (403) und wieder aktivieren (200) (RBAC-10) | 2 von 2 | +| Policy-Dienst gestoppt: 503 (fail closed); nach Wiederanlauf 200 | bestanden | +| Fremder Mandant (echtes Token des zweiten Kontodienstes), manipuliertes Token, `caller` ohne Token, gefälschter `caller` neben fremdem Token | 401 / 401 / 401 / 403 | +| Rückbau (Dienste, Benutzer, Verzeichnis, Suchtabelle) mit Vorher-/Nachher-Snapshot | identisch | + +Nicht erzeugbar im Lauf: abgelaufenes Token (durch `e2e-core-dms.sh` mit TTL 5 s abgedeckt). + +**Ressourcen (204, 4 GB):** Ruhebetrieb 589 bis 592 MB (App 10, Worker 11, Stellvertreter 7, Kontodienst 7, zweiter Kontodienst 6, Policy 4, KoSIT 544), nach dem Smoke 643 bis 644 MB (App 15, Worker 57). Host belegt 1043 bis 1108 MB von 4096 MB, keine OOM-Ereignisse. CPU-Druck (PSI, `some`, avg10) höchstens 3,6. + +**QA und Entscheidungen** + +| Nr. | Befund oder Entscheidung | Alternativen | Grund | Iterationen | +|---|---|---|---|---| +| E1 | Der Guard im `dms-app` kannte als Admin nur die Nutzer-IDs aus `NEXARCH_DMS_APP_ADMIN_USER_IDS`. Ein Nutzer mit der Rolle `tenant_admin` im echten Core-Token bekam auf `/auto-rules` und `/ocr/review` 403, obwohl die Core-Rechteentscheidung sie erlaubt (im Trockenlauf der in-process-Kette unsichtbar). Behoben: `PoolChecker.IsAdmin` wertet zusätzlich die Rolle `tenant_admin` aus dem verifizierten Modul-Token aus (nur wenn die Token-Identität zum Aufrufer passt), Test `TestIsAdmin_RoleFromVerifiedTokenCountsAsAdmin`. | Rolle im Guard ignorieren und Admins per Env pflegen (nicht praktikabel: Core-Nutzer-IDs sind UUIDs je Mandant) | Rolle stammt aus dem mit dem Core-Schlüssel signierten Token, die Core-Policy wird trotzdem zusätzlich erzwungen (doppelte Prüfung) | 1 | +| E2 | `/audit-log` bleibt für `tenant_admin` 403, solange der Nutzer nicht in `NEXARCH_DMS_APP_AUDITOR_USER_IDS` steht. Entscheidung: Aufgabentrennung beibehalten (Prüfer ≠ Admin), im Smoke wird der Admin als Prüfer eingetragen, Doku ergänzt (`BETRIEB-UMGEBUNGSVARIABLEN.md`). | Prüferrecht ebenfalls aus der Token-Rolle ableiten | Audit-Zugriff ist ein bewusst eigenes Recht; die Entscheidung berührt Datenschutz/Produkt und ist bei Bedarf umkehrbar | 1 | +| E3 | Schritt S15 (endgültiges Löschen wird ohne Archive verweigert und im Audit-Log vermerkt) lief im Token-Modus ohne Eintrag: die Standardrolle `user` hat das Recht `dms.trash.purge` nicht, die Anfrage endete an der Core-Policy (403) vor dem Löschschutz. Entscheidung: Im Modus `core` läuft der Lebenszyklus mit dem `tenant_admin` (`bob`) als Akteur, die Standardrolle wird separat in den Rollenprüfungen (R1 bis R5) geprüft. | Recht `dms.trash.purge` der Standardrolle gewähren (widerspricht RBAC-09) | Das Verhalten ist beabsichtigt; der Smoke muss die Rolle haben, die den Pfad erreicht | 1 | +| E4 | Admins erhalten keinen Zugriff auf fremde Dokumente (Guard: nur Eigentümer). Nicht geändert, als Grenze notiert. | Admin-Zugriff auf alle Dokumente des Mandanten | Produktentscheidung (Berechtigungsmodell), nicht im Scope dieses Tickets | 0 | +| E5 | QA-Durchgang am eigenen Diff: versehentlich eingecheckte `__pycache__`-Dateien entfernt und in `.gitignore` aufgenommen, das Aufräum-Muster `/tmp/[0-9][0-9]-*.txt` im Smoke-Skript entfernt (hätte fremde Dateien treffen können), tote Variable entfernt. Negativfälle für die neue Admin-Prüfung im Test (falscher Nutzer, Rolle `user`, ohne Token-Identität, ohne `AdminRole`). | | | 1 | + +**Regression je Modul:** Core, Archive und Mail sind durch diesen Nachtrag unverändert (nur Merge #108/#109 und Skripte); DMS wurde nach der Guard-Änderung vollständig neu getestet (75 Pakete `ok`), der Smoke lief auf dem endgültigen Stand erneut grün. + +**Offen (unverändert oder neu):** +- `kek-api` und die Nutzungsmeldung sind im Smoke ersetzt (Stellvertreter), ein Lauf mit dem echten KEK-Dienst fehlt. +- Login-zu-Token-Weg in den Oberflächen (senden weiter `caller`) und der Betrieb hinter dem Reverse Proxy fehlen. +- Der Token-Modus-Smoke lief nur auf 204. Auf 131 wurde dafür nichts ausgeführt (keine Freigabe). +- Schlüssel-Neuverpackung bei Wechsel des Verschlüsselungsschlüssels, Token-Widerruf und Rotations-Oberfläche (API-16) fehlen. +- Mail-Bestandsfehler `indexworker`, `gofmt`-Bestand in Core/Mail, S3-, Backup- und Manticore-Tests in Mail, `soffice`, `clamd`. +- Ohne `NEXARCH_POLICY_ALLOWED_TENANTS` darf jeder Token-Inhaber jeden gültigen Mandanten angeben (RBAC-10).