129 lines
6.7 KiB
Markdown
129 lines
6.7 KiB
Markdown
# Gemeinsames Result-Read-Model
|
||
|
||
Stand: 2026-08-04
|
||
Zugehörige Planphase: Phase 13B, Umsetzungsschritte 10 und 11
|
||
Status: Policy-Finding- und Read-Vertikalschnitt umgesetzt; Gesamtmodell in Arbeit
|
||
|
||
## Zweck
|
||
|
||
Das gemeinsame Result-Read-Model stellt Scanner-Finding-Vorkommen und
|
||
nachvollziehbar erzeugte bestätigte Policy-Abweichungen über eine einheitliche,
|
||
nicht schreibbare Abfragegrenze bereit. Es ersetzt weder das kanonische
|
||
Finding-Modell noch die GPO-, Baseline- oder Evaluationsentitäten.
|
||
|
||
## Schritt 0 – technischer Ist-Zustand
|
||
|
||
| Bereich | Status | Vorhandener Stand | Differenz zum Ziel |
|
||
|---|---|---|---|
|
||
| Projekt, Assessment, Scan-Lauf | erfüllt | Getrennte Domainobjekte, Tabellen, Repository- und API-Operationen | keine neue Besitzstruktur erforderlich |
|
||
| Importdatei und Source View | erfüllt | `ImportFileRecord` und `SourceTableRecord` mit Herkunft und Locators | spätere Benennung darf die bestehenden Objekte nicht duplizieren |
|
||
| FindingDefinition und FindingOccurrence | erfüllt | getrennte Objekte und Tabellen; dauerhafte und unresolved Identität sind abgesichert | keine zweite Finding-Ablage anlegen |
|
||
| Original- und Normalwerte | erfüllt | `MappedValue`, `originalFields`, Feldmapping und SourcePosition; Outcome und technische Ausführung sind separat typisiert | historische Occurrences werden konservativ über `status` gelesen |
|
||
| Reviews | erfüllt | eigenständige, optimistisch versionierte Definition-/Occurrence-Reviews | Read-Projektion muss Status und Disposition auseinanderziehen |
|
||
| Kategorien | erfüllt | namespaced, profilversionierte Scannerkategorien und kanonische Policykategorien | UI-Anbindung bleibt offen |
|
||
| Scannerpipeline | erfüllt | Formatadapter, Source Extractor, Candidate-Mapping und kanonische Persistenz sind getrennt | keine werkzeugspezifische Resultpipeline ergänzen |
|
||
| GPO-Ingestion | teilweise | technische Identität, Baselineanalyse, Snapshotaggregation, Evaluation und Finding Factory sind vorhanden | freigegebene Inbox-ADMX-/Regelkataloge und UI fehlen |
|
||
| PostgreSQL | erfüllt für den Read-Pfad | Migrationen 001–017 persistieren Scanner-, Policy-Evaluation- und Policy-Finding-Provenienz | vollständig SQL-seitige Facetten bleiben optional |
|
||
| Repository/API | erfüllt | gemeinsame Result-, Facetten-, Detail- und Kategorienqueries lesen Scanner- und bestätigte Policy-Findings in Local, PostgreSQL, HTTP und Client | UI-Anbindung bleibt offen |
|
||
| UI-Filter | teilweise | generische dynamische Dataset-Facetten sind vorhanden | serverseitige gemeinsame Resultfacetten sind noch nicht angebunden |
|
||
|
||
Gefährliche Doppelimplementierungen wären insbesondere eine zweite Scanner-
|
||
Finding-Tabelle, ein zweiter Importweg für bekannte Werkzeuge, die Behandlung
|
||
von `PolicyObservation` als Finding oder eine schreibbare Resulttabelle.
|
||
|
||
## Fachliche Grenzen
|
||
|
||
- Jedes Scanner-Vorkommen bleibt genau ein Result der Projektion.
|
||
- Die Projektion dedupliziert weder innerhalb eines Laufs noch zwischen Tools.
|
||
- Definitionen werden nur über die bereits abgesicherte stabile Identität
|
||
wiederverwendet.
|
||
- Originalwerte und Locators werden nur gelesen und niemals verändert.
|
||
- GPO-Backups und Policy-Beobachtungen erscheinen nicht als Scanner-Findings.
|
||
- Ein Policyresult wird erst nach einer versionierten Evaluation projiziert.
|
||
- React erhält weder SQL noch PostgreSQL-Tabellennamen.
|
||
|
||
## Beziehungen
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A["Assessment"] --> S["Scan Run"]
|
||
S --> O["Finding Occurrence"]
|
||
D["Finding Definition"] --> O
|
||
O --> R["Unified Result Projection"]
|
||
E["Evaluation Run"] --> P["Policy Evaluation Result"]
|
||
P --> F["Policy Finding Occurrence"]
|
||
D --> F
|
||
F --> R
|
||
C["Result Categories"] --> R
|
||
V["Reviews"] --> R
|
||
```
|
||
|
||
Die Pfeile zur Projektion sind lesende Ableitungen und keine Ownership- oder
|
||
Kaskadenbeziehungen.
|
||
|
||
## Scannerpipeline
|
||
|
||
```text
|
||
Quelle -> Formatadapter -> DecodedSourceDocument -> Source Extractor
|
||
-> FindingCandidate -> Mappingprofil -> FindingOccurrence
|
||
-> Unified Result Projection
|
||
```
|
||
|
||
## GPO-Pipeline
|
||
|
||
```text
|
||
GPO-Backup -> GPOBackupInstance -> PolicyObservation -> PolicyIdentity
|
||
-> EvaluationRun -> PolicyEvaluationResult
|
||
-> Policy Finding Factory -> Policy Finding Occurrence
|
||
-> Unified Result Projection
|
||
```
|
||
|
||
Die Policyseite projiziert ausschließlich vollständig belegte, bereits als
|
||
`eligible` bestätigte konfigurierte Abweichungen. Review- und Lückenfälle
|
||
bleiben außerhalb der Finding-Projektion.
|
||
|
||
## Statusdimensionen
|
||
|
||
Die Read-Sicht trennt `severityNormalized`, `outcomeNormalized`,
|
||
`technicalExecutionState`, `reviewStatus`, `reviewDisposition`,
|
||
`lifecycleState` und `effectiveState`. Neue Scannerimporte schreiben
|
||
Outcome und technische Ausführung als getrennte `MappedValue`-Dimensionen
|
||
und in getrennte PostgreSQL-Spalten. Das historische
|
||
`FindingOccurrence.status` bleibt kompatibel lesbar und wird nur dann
|
||
konservativ abgeleitet, wenn die neuen Dimensionen fehlen. Ein technisches
|
||
„Failed to run“ ergibt `execution_error` plus `failed`, nicht das fachliche
|
||
Outcome `fail`. Unbelegte Lebenszyklus- oder Wirksamkeitsaussagen bleiben
|
||
`unknown`.
|
||
|
||
## Kategorienmodell
|
||
|
||
Kategorien werden in der Projektion als strukturierte Liste mit Namespace,
|
||
Code, Label, Primärkennzeichen sowie Tool- und Profilprovenienz ausgegeben.
|
||
Migration 007 persistiert den Katalog in `assessor_result_categories` und die
|
||
mehrwertige Zuordnung in `assessor_finding_occurrence_categories`. Der
|
||
Primärwert aus der Definition und weitere gemappte Quellkategorien bleiben
|
||
einzelne Zuordnungen; gleiche Labels verschiedener Namespaces oder
|
||
Profilversionen werden nicht zusammengeführt.
|
||
|
||
## PostgreSQL- und API-Abbildung
|
||
|
||
Die Repository-Projektion liest Scanner- und Policy-Occurrences aus getrennten
|
||
relationalen Provenienzpfaden und führt sie erst als `UnifiedResultProjection`
|
||
zusammen. Migration 007 ergänzt Scanner-Outcome/-Execution und Kategorien;
|
||
Migration 017 bindet Policy-Occurrences relational an ein `eligible`
|
||
`confirmed_configured_deviation`-Evaluationsergebnis und an dieselbe kanonische
|
||
Finding-Definitionstabelle. Es wird bewusst keine materialisierte View angelegt.
|
||
Die API stellt Results, Facetten, Kategorien und Details unter `/api/v1/results` bereit.
|
||
|
||
## Bekannte Grenzen und nächste Schritte
|
||
|
||
- Die PostgreSQL-Read-Projektion leitet Kategorien derzeit weiterhin aus den
|
||
versionierten Domainobjekten ab; die relationale Struktur ist für den
|
||
folgenden vollständig SQL-seitigen Filterpfad vorbereitet.
|
||
- Der produktive Policy-Regelkatalog ist bis zur fachlichen Kuratierung leer;
|
||
deshalb entstehen aus dem realen Bestand weiterhin keine Policy-Findings.
|
||
- Konflikte, Katalog-/Parserlücken, partielle Analysen und unaufgelöste
|
||
Identitäten benötigen noch eine gemeinsame UI-Darstellung.
|
||
- Lebenszykluswerte aus Vergleichen werden im ersten Schnitt nicht erfunden.
|
||
|