ims integraated into e-compliance

This commit is contained in:
ValueOn AG 2026-06-03 13:20:17 +02:00
parent 388771fbf6
commit 671be8adf9
41 changed files with 6317 additions and 633 deletions

View file

@ -26,7 +26,7 @@ PowerOn PORTA ist eine Multi-Tenant SaaS-Plattform mit Feature-Store-Modell, AI-
| **b-reference/** | Wie das System funktioniert (code-verifiziert) | System verstehen, Architektur-Fragen |
| **c-work/** | Laufende Arbeit -- Kanban (plan → build → validate → done) | Feature planen, bauen, testen |
| **d-guides/** | How-to: Dev-Setup, Deployment, Testing, Coding-Regeln | Etwas tun, Prozess nachschlagen |
| **e-compliance/** | Sicherheit, Datenschutz, Audit-Dokumente | Regulatorische Fragen |
| **e-compliance/** | Sicherheit, Datenschutz, Audit-Dokumente; **ISO 9001/27001 IMS** unter `e-compliance/ims/` (Handbuch, Politiken, SoA, Prozesse, Cockpit) | Regulatorische Fragen, Zertifizierung |
| **f-decisions/** | Entscheidungen (ADR-light): Kontext, Entscheidung, Konsequenz | Warum wurde X so entschieden? |
| **z-archive/** | Veraltete Docs mit Forward-Link zum Nachfolger | Historischer Kontext |

View file

@ -21,6 +21,7 @@ Lade immer zuerst diese Datei. Dann gezielt die passende(n) Referenz-Datei(en).
| Gateway-Architektur | b-reference/platform-core/architecture.md | Backend-Module, Services, Interfaces |
| AI Agent & Tools | b-reference/platform-core/ai-agent.md | Agent-Verhalten, Tool-Registrierung, RAG |
| Agent-Tool File Bridge | b-reference/platform-core/agent-file-bridge.md | Wie Agent-Tool-Outputs (download / writeFile / renderDocument / generateImage / createChart) als ChatDocument im Workflow landen, `docItem:<id>`-Pattern, runAgent Workflow-Propagation |
| Dokumenten-Rendering & Style-System | b-reference/platform-core/document-rendering.md | Rendering-Pipeline (MD->JSON->File), Style-Resolution (4 Schichten: DEFAULT_STYLE -> Agent-Overrides -> AI-Enhancement -> Per-Element), Tabellen-Styling, Renderer-Architektur (PDF/DOCX/PPTX/XLSX/HTML) |
| Workflow-Engine | b-reference/platform-core/workflow.md | Methoden, Aktionen, WorkflowManager |
| Automation | b-reference/platform-core/automation.md | Graphical Editor, Scheduler, System-Automatisierung (`/automations`, `/api/system/workflow-runs/*`) |
| Billing & Subscriptions | b-reference/platform-core/billing.md | Abrechnung, Prepaid, State Machine |
@ -93,5 +94,8 @@ Lade immer zuerst diese Datei. Dann gezielt die passende(n) Referenz-Datei(en).
| Thema | Datei | Wann laden |
|-------|-------|------------|
| Sicherheitsuebersicht | e-compliance/security-overview.md | Kunden/Audit: DSGVO, RBAC, Verschluesselung |
| Neutralisierung Detail | e-compliance/neutralisierung-detail.md | Technische Neutralisierungs-Flows |
| Sicherheitsübersicht | e-compliance/ims/05_betrieb/security-overview.md | Kunden/Audit: DSGVO, RBAC, Verschlüsselung |
| Neutralisierung Detail | e-compliance/ims/05_betrieb/neutralisierung-detail.md | Technische Neutralisierungs-Flows |
| IMS (ISO 9001 + 27001) | e-compliance/ims/00_IMS-Handbuch.md | Integriertes Managementsystem: Kontext, Politiken, Risiko/SoA, Audit, KVP; Betriebsprozesse in ims/05_betrieb/ |
| IMS Management-Cockpit | e-compliance/ims/cockpit/IMS-Cockpit.html | Offline-HTML zur Navigation/Einsicht aller IMS-Dokumente; neu bauen via build_cockpit.py |
| Pendenzen / Massnahmen | e-compliance/ims/07_verbesserung/massnahmen-register.md | Zentrale Pendenzenliste (CAPA), Quelle fuer Cockpit-Pendenzenseite |

View file

@ -269,7 +269,7 @@ herunterladen), gelten drei Schichten:
| `walkUdmBlocks` | UDM traversieren: alle `ContentBlock`-Knoten mit Pfad und Kurz-Preview |
| `filterUdmByType` | UDM: alle Blöcke mit gegebenem `contentType` (z.B. `table`, `image`) |
| `describeImage` | Vision-Analyse |
| `renderDocument` | Dokument rendern |
| `renderDocument` | Dokument rendern (PDF/DOCX/PPTX/XLSX/HTML); optionaler `style`-Parameter fuer Agent-Overrides; AI-enhanced Styling basierend auf Dokumentkontext; Smart Table Styling via `tableStyle` pro Tabelle. Details: `b-reference/platform-core/document-rendering.md` |
| `generateImage` | Bildgenerierung |
| `createChart` | Chart erzeugen |

View file

@ -0,0 +1,226 @@
<!-- status: canonical -->
<!-- lastReviewed: 2026-06-03 -->
<!-- verifiedAgainst: platform-core/modules/serviceCenter/services/serviceGeneration/ (styleDefaults.py, mainServiceGeneration.py, renderers/*) -->
# Dokumenten-Rendering & Style-System
## Ueberblick
Der **Generation-Service** (`serviceGeneration` / `mainServiceGeneration.py`) wandelt strukturierten JSON-Content in formatierte Dokumente um. Pipeline: **Markdown -> JSON -> Rendered File** (PDF, DOCX, PPTX, XLSX, HTML).
Styling wird ueber ein **4-Schichten-Modell** aufgeloest — von generischen Defaults bis zu element-spezifischen Overrides. Keine statischen Theme-Presets; stattdessen AI-getriebene kontextuelle Anpassung.
---
## Style-Resolution-Pipeline
```mermaid
flowchart TD
Default["DEFAULT_STYLE<br/>(Cursor/VS-Code-Aesthetik)"] --> Resolve["resolveStyle()<br/>deep-merge: defaults + agentStyle"]
Resolve --> AI["_enhanceStyleWithAi()<br/>AI Delta basierend auf<br/>Titel, Typ, User-Request"]
AI --> Global["Resolved Global Style<br/>(12 Sektionen)"]
Global --> Convert["_convertUnifiedStyleToInternal()<br/>Renderer-internes Format"]
Convert --> Renderer["Renderer"]
Renderer --> PerElement["Per-Element Overrides<br/>z.B. tableStyle pro Tabelle"]
PerElement --> Final["Gerendertes Element"]
```
### Schicht 1: DEFAULT_STYLE (Basis)
Datei: `styleDefaults.py`. Neutrale, moderne Basis-Aesthetik inspiriert von Cursor/VS-Code Markdown-Rendering.
| Sektion | Schluessel | Beschreibung |
|---------|-----------|-------------|
| `fonts` | `primary`, `monospace` | Calibri / Consolas |
| `colors` | `primary`, `secondary`, `accent`, `background` | GitHub-inspirierte Farbpalette (#24292e, #586069, #0366d6) |
| `documentTitle` | `sizePt`, `weight`, `color`, `align`, `spaceBeforePt`, `spaceAfterPt` | Dokumenttitel-Formatierung |
| `headings` | `h1`-`h4` mit `sizePt`, `weight`, `color`, `spaceBeforePt`, `spaceAfterPt` | Ueberschriften-Hierarchie |
| `paragraph` | `sizePt`, `lineSpacing`, `color`, `align` | Fliesstext |
| `table` | `headerBg/Fg`, `headerSizePt`, `bodySizePt`, `rowBandingEven/Odd`, `borderColor`, `borderWidthPt`, `borderStyle`, `bandingEnabled`, `cellPaddingPt` | Tabellen-Styling |
| `list` | `bulletChar`, `indentPt`, `sizePt` | Aufzaehlungen |
| `image` | `defaultWidthPt`, `maxWidthPt`, `alignment` | Bild-Defaults |
| `codeBlock` | `fontSizePt`, `background`, `borderColor` | Code-Bloecke |
| `coverPage` | `titleSizePt`, `subtitleSizePt`, `authorSizePt`, `dateSizePt`, `titleColor`, `subtitleColor` | Deckblatt |
| `caption` | `sizePt`, `color`, `italic`, `align` | Bild-/Tabellen-Beschriftungen |
| `page` | `format`, `marginsPt`, `showPageNumbers`, `headerHeight/footerHeight`, `headerLogo`, `headerText`, `footerText` | Seitenlayout |
### Schicht 2: Agent Explicit Overrides
Der Agent kann ein `style`-Objekt in `metadata.style` des JSON-Dokuments mitgeben. `resolveStyle(agentStyle)` macht ein rekursives Deep-Merge: `DEFAULT_STYLE <- agentStyle`. Nur explizit gesetzte Keys werden ueberschrieben.
### Schicht 3: AI Style Enhancement
`_enhanceStyleWithAi()` in `mainServiceGeneration.py`:
1. Empfaengt das **vollstaendige** resolved Style-Set als JSON (~920 Bytes)
2. Kontext: Dokumenttitel, Dokumenttyp, User-Request (Auszug)
3. AI liefert ein **Delta-JSON** mit nur den zu aendernden Properties
4. `deepMerge(resolvedStyle, delta)` wendet die Aenderungen an
5. Bei Fehler: graceful fallback auf den unmodifizierten Style
Beispiele fuer AI-Anpassungen:
- Rechtsschrift: Serif-Fonts, justified Paragraphs
- Finanzbericht: konservative Farben, rechtausgerichtete Zahlen-Spalten
- Marketing: kraeftige Farben, groessere Abstände
### Schicht 4: Per-Element Overrides
JSON-Content-Bloecke koennen element-spezifische Style-Overrides tragen. Aktuell unterstuetzt:
- **`tableStyle`** auf Table-Bloecken: `content.tableStyle` wird per deep-merge mit dem globalen `table`-Style zusammengefuehrt. Erlaubt pro Tabelle eigene Banding-Farben, Border-Style, Column-Alignments etc.
- **`columnAlignments`** auf Table-Bloecken: Explizite Liste (`["left", "right", "center"]`) pro Spalte.
---
## Tabellen-Rendering-Modell
### Globale Tabellen-Styles
Aus `DEFAULT_STYLE["table"]`:
| Key | Default | Beschreibung |
|-----|---------|-------------|
| `headerBg` / `headerFg` | `#f6f8fa` / `#24292e` | Header-Hintergrund und -Textfarbe |
| `headerSizePt` / `bodySizePt` | 10 / 10 | Schriftgroessen |
| `rowBandingEven` / `rowBandingOdd` | `#f6f8fa` / `#FFFFFF` | Alternierende Zeilenfarben |
| `borderColor` / `borderWidthPt` | `#e1e4e8` / 0.5 | Rahmenfarbe und -staerke |
| `borderStyle` | `"grid"` | `grid` (Vollraster), `horizontal` (nur horizontale Linien), `none` (kein Rahmen) |
| `bandingEnabled` | `true` | Aktiviert/deaktiviert Zeilenbanding |
| `cellPaddingPt` | 4 | Zellen-Innenabstand |
### Per-Table Overrides
Ein Table-Block im JSON kann ein `tableStyle`-Objekt tragen:
```json
{
"content_type": "table",
"elements": [{
"headers": ["Name", "Betrag", "Datum"],
"rows": [...],
"tableStyle": {
"borderStyle": "horizontal",
"bandingEnabled": false,
"columnAlignments": ["left", "right", "center"]
}
}]
}
```
Der Renderer mergt: `globalTableStyle <- perTableStyle` (deep-merge).
### Spaltenausrichtung
1. **Explizit:** `tableStyle.columnAlignments` (Array von `"left"` / `"center"` / `"right"`)
2. **Auto-Inferenz** (`_inferColumnAlignments` in BaseRenderer):
- Zahlenspalten (>=60% numerisch) -> `right`
- Datumsspalten (>=60% Datumsformat) -> `center`
- Sonst -> `left`
---
## Renderer-Architektur
### Basisklasse
`DocumentRendererBaseTemplate` (ABC) stellt bereit:
- `_convertUnifiedStyleToInternal(style)` — Wandelt das 12-Sektionen Unified-Style-Dict in ein flaches internes Format um
- `_inferColumnAlignments(headers, rows, tableStyle)` — Spaltenausrichtungs-Heuristik
- `_inlineRunsFromContent()` / `_inlineRunsForCell()` / `_inlineRunsForListItem()` — Inline-Run-Normalisierung
- `_lazyResolveImageBase64()` — On-Demand Bild-Aufloesung fuer Grossdokumente
### Format-Renderer
| Renderer | Bibliothek | Formate | Besonderheiten |
|----------|-----------|---------|----------------|
| `rendererPdf.py` | ReportLab | PDF | TTF-Font-Registration (`_resolveFontFamily`), Temp-File-Bilder fuer Memory-Effizienz, Emoji-Fallback (NotoEmoji) |
| `rendererDocx.py` | python-docx | DOCX | XML-basierte Tabellen-Borders, Word-Styles fuer h1-h4, Inline-Run-Formatting |
| `rendererPptx.py` | python-pptx | PPTX | Slide-Layout pro Section, RGBColor-Konvertierung, Shape-basierte Bilder |
| `rendererXlsx.py` | openpyxl | XLSX | PatternFill fuer Banding, Side/Border fuer Rahmen, Cell-Anchor fuer Bilder |
| `rendererHtml.py` | Jinja2/String | HTML | CSS-Generierung aus Unified Style, Inline-Styles |
### Font-Resolution (PDF)
`_resolveFontFamily(fontName)` in rendererPdf.py:
1. Pruefe ob TTF-Datei unter `assets/fonts/` registrierbar ist
2. Registriere bei ReportLab (`pdfmetrics.registerFont`)
3. Fallback-Kette: gewuenschter Font -> Helvetica (ReportLab Core) -> Courier
---
## AI Style Enhancement — Details
### Prompt-Struktur
```
You are a document styling expert. [...]
Document title: {docTitle}
Document type: {docType}
User request (excerpt): {userHint}
Current style (full schema):
{vollstaendiges resolvedStyle JSON}
You may adjust any property: fonts, colors, documentTitle, headings, paragraph, table, list, image, codeBlock, coverPage, caption, page.
[...]
Return ONLY a valid JSON object.
```
### Erwartete Antwort
Ein JSON-Delta-Objekt mit NUR den zu aendernden Keys:
```json
{
"fonts": {"primary": "Georgia"},
"paragraph": {"align": "justified"},
"colors": {"primary": "#1a1a2e"}
}
```
Leeres `{}` = keine Aenderungen noetig.
### Fehlerbehandlung
- Leere Antwort -> Original-Style beibehalten
- Ungültiges JSON -> Markdown-Fences strippen, `{` bis `}` extrahieren, nochmal parsen
- Parse-Fehler oder Exception -> Warning loggen, Original-Style beibehalten
- Operation Type: `DATA_GENERATE`
---
## Design-Entscheidungen
| Datum | Entscheidung | Begruendung |
|-------|-------------|-------------|
| 2026-04-29 | Kein Theme-Katalog, kein Mandate-CI-Konzept | ADR: Agent fuellt generischen Style-Block |
| 2026-06-02 | THEME_PRESETS + documentTheme temporaer eingefuehrt | A3-Reconciliation |
| 2026-06-03 | THEME_PRESETS + documentTheme entfernt, AI-Enhancement statt Presets | Zurueck zum ADR-Original; AI passt kontextbasiert an |
| 2026-06-03 | DEFAULT_STYLE: Cursor/VS-Code-Aesthetik | Moderne, neutrale Basis; GitHub-Farbpalette |
| 2026-06-03 | AI bekommt vollstaendiges Style-Set im Prompt | Alle 12 Sektionen muessen anpassbar sein |
| 2026-06-03 | Per-Table Overrides via content.tableStyle | Jede Tabelle kann eigene Styles haben |
| 2026-06-03 | Auto-Column-Alignment via _inferColumnAlignments | Zahlen rechts, Daten zentriert — ohne AI-Call |
---
## Schluessel-Dateien
| Datei | Rolle |
|-------|-------|
| `serviceGeneration/styleDefaults.py` | `DEFAULT_STYLE`, `resolveStyle()`, `deepMerge()` |
| `serviceGeneration/mainServiceGeneration.py` | `renderReport()`, `_enhanceStyleWithAi()` |
| `serviceGeneration/renderers/documentRendererBaseTemplate.py` | `BaseRenderer`, `_convertUnifiedStyleToInternal()`, `_inferColumnAlignments()` |
| `serviceGeneration/renderers/rendererPdf.py` | PDF via ReportLab |
| `serviceGeneration/renderers/rendererDocx.py` | DOCX via python-docx |
| `serviceGeneration/renderers/rendererPptx.py` | PPTX via python-pptx |
| `serviceGeneration/renderers/rendererXlsx.py` | XLSX via openpyxl |
| `serviceGeneration/renderers/rendererHtml.py` | HTML via String/Jinja |
| `serviceAgent/coreTools/_mediaTools.py` | `renderDocument` Agent-Tool |
---
## Auch wichtig
- **Grossdokumente:** Lazy File-Ref-Bilder (`_lazyResolveImageBase64`) + Temp-File-Bilder fuer PDF vermeiden OOM bei vielen eingebetteten Bildern. Siehe `c-work/4-done/2026-06-po-cleanup-neutralization-docgen.md` (A3/AC15).
- **Markdown-Renderer/Text-Renderer** ignorieren `style` (dokumentiert, kein Bug).
- **Agent-Tool `renderDocument`:** Akzeptiert optionalen `style`-Parameter im Tool-Schema; kein `documentTheme`-Parameter mehr.

View file

@ -7,12 +7,19 @@
# AI Reports: Generisches Style-Management, AI-Call-Konfiguration, Inline-Bilder
> **Nachtrag 2026-06-02 (A3-Reconciliation):** Der damalige Entscheid "Theme als reiner
> **Nachtrag 2026-06-02 (A3-Reconciliation, SUPERSEDED):** Der damalige Entscheid "Theme als reiner
> Prompt-Hint, keine Renderer-Theme-Presets" wurde teilweise revidiert. `documentTheme`
> ist seit 2026-06 als **agent-ueberschreibbare** Preset-Bibliothek (`THEME_PRESETS`/
> `resolveTheme` in `styleDefaults.py`) end-to-end an `renderReport` verkabelt. Presets sind
> Defaults, kein Hard-Mandate: ein explizites `style`-Objekt ueberschreibt einzelne
> Preset-Keys weiterhin. Details: c-work/1-plan/2026-06-po-cleanup-neutralization-docgen.md.
> wurde als agent-ueberschreibbare Preset-Bibliothek (`THEME_PRESETS`/`resolveTheme`) verkabelt.
> **Dieser Schritt wurde am 2026-06-03 rueckgaengig gemacht (siehe unten).**
> **Nachtrag 2026-06-03 (Style-System-Overhaul):** `THEME_PRESETS`, `resolveTheme()` und der
> `documentTheme`-Parameter wurden vollstaendig entfernt — zurueck zum ADR-Originalentscheid
> (kein Theme-Katalog). Stattdessen: AI-getriebene Style-Enhancement (`_enhanceStyleWithAi`
> in `mainServiceGeneration.py`) analysiert Dokumenttitel, -typ und User-Request und liefert
> ein Style-Delta auf den modernisierten `DEFAULT_STYLE` (Cursor/VS-Code-Aesthetik). Neue
> Features: Smart Table Styling (per-table `tableStyle`-Overrides, `borderStyle` grid/horizontal/none,
> `bandingEnabled`, `cellPaddingPt`, automatische `columnAlignments`), `coverPage`- und
> `caption`-Style-Sektionen. Kanonische Referenz: `b-reference/platform-core/document-rendering.md`.
## Beschreibung und Kontext

View file

@ -173,6 +173,7 @@ Bis dahin gilt als Mitigation der bestehende `writeFile`+`renderDocument(sourceF
| 2026-06-02 | A3: Theme-Wahl agent-getrieben via `documentTheme`-Tool-Param (Enum + Beschreibung), kein serverseitiges Auto-Select | ADR-konform (Agent treibt Style); kein zusaetzlicher LLM-Call noetig |
| 2026-06-02 | A3: Layout-Primitive = `cover_page` + `image_grid` (Markdown-Fenced-Bloecke); `letterhead`/`multi-column` zurueckgestellt | Hoechster Nutzen (Klageschrift-Titelseite, Marketing-Bildraster); multi-column ist Page-Template-Thema, nicht Block-Primitive |
| 2026-06-02 | A3: HTML-first-Backend (WeasyPrint/Chrome) — ENTSCHIEDEN: nein | Lazy+Temp-File-Bilder loesen Memory-Engpass; ADR sagte "kein WeasyPrint-Ersatz" |
| 2026-06-03 | A3: THEME_PRESETS + documentTheme entfernt, AI-Style-Enhancement statt Presets | ADR 2026-04 Originalentscheid wiederhergestellt; AI passt Styles kontextbasiert an statt statischer Presets; Smart Table Styling als Erweiterung |
## Umsetzungs-Checkliste
@ -208,6 +209,7 @@ Bis dahin gilt als Mitigation der bestehende `writeFile`+`renderDocument(sourceF
- [x] JSON-Layout-Primitive `cover_page` + `image_grid` (Markdown-Fenced-Bloecke) + PDF/DOCX-Handler; `letterhead`/`multi-column` zurueckgestellt
- [x] Grossdokumente: File-Referenz-Bilder statt base64 (Schritt 1) + Temp-File-PDF-Bilder (Schritt 2)
- [x] HTML-first-Backend evaluiert -> ENTSCHIEDEN: nein (nicht benoetigt)
- [x] **Nachtrag 2026-06-03:** `THEME_PRESETS` + `documentTheme` nachtraeglich entfernt zugunsten AI-getriebener Style-Enhancement (`_enhanceStyleWithAi`). `DEFAULT_STYLE` auf Cursor/VS-Code-Aesthetik modernisiert. Alle 5 Renderer refactored (Dead-Code entfernt, Hardcodes durch Unified-Style-Reads ersetzt). Folge-Feature: Smart Table Styling (per-table Overrides, borderStyle, bandingEnabled, columnAlignments, coverPage, caption). Kanonische Doku: `b-reference/platform-core/document-rendering.md`
### Querschnitt
- [x] RBAC / Permissions: A0 entfernt Chatbot-RBAC-Objekte/Template-Rollen aus Code; A1 Tool-Zugriff ueber bestehende Neutralisierungs-Rechte

View file

@ -0,0 +1,60 @@
<!-- status: done -->
<!-- started: 2026-06-03 -->
<!-- component: gateway -->
# Style-System Overhaul + Smart Table Styling
## Beschreibung
Vollstaendige Ueberarbeitung des Dokumenten-Styling-Systems in `serviceGeneration`:
1. **Statische Presets entfernt:** `THEME_PRESETS`, `resolveTheme()` und der `documentTheme`-Parameter wurden end-to-end entfernt (styleDefaults, mainServiceGeneration, _mediaTools, methodAi, generateDocument, documentPath, mainServiceAi, mainTrustee). Zurueck zum ADR-Originalentscheid 2026-04 (kein Theme-Katalog).
2. **AI-getriebene Style-Enhancement:** `_enhanceStyleWithAi()` in `mainServiceGeneration.py` analysiert Dokumenttitel, -typ und User-Request und liefert ein JSON-Delta auf den Basis-Style. Das vollstaendige Style-Set (~920 Bytes, alle 12 Sektionen) wird dem AI als Kontext mitgegeben.
3. **DEFAULT_STYLE modernisiert:** Cursor/VS-Code-inspirierte Basis-Aesthetik (Calibri, GitHub-Farbpalette, subtile Rahmen, leichte Header-Hintergruende).
4. **Style-Chain-Luecken geschlossen:**
- `_convertUnifiedStyleToInternal()` erweitert um page, image, table font sizes, codeBlock.borderColor, coverPage, caption, table_banding, table_padding, fonts, colors
- Heading-Key-Mismatch in XLSX/PPTX behoben
- DOCX h3/h4 Styles registriert
- Fallback-Farben an DEFAULT_STYLE angeglichen
- HTML Legacy-Pfad (`_getStyleSet`, `_getDefaultStyleSet`) entfernt
5. **Smart Table Styling:**
- Neue Style-Keys: `borderStyle` (grid/horizontal/none), `bandingEnabled` (Toggle), `cellPaddingPt`
- Per-Table Overrides via `content.tableStyle` im JSON (deep-merge mit globalem Style)
- Automatische Spaltenausrichtung (`_inferColumnAlignments`: Zahlen rechts, Daten zentriert, Text links)
- Neue Schema-Sektionen `coverPage` und `caption`
6. **Dead Code entfernt:** `_getStyleSet`, `_enhanceStylesWithAI`, `_getDefaultStyleSet`, `_validateStylesContrast` und weitere Legacy-Methoden aus allen 5 Renderern.
## Entscheidungen
| Datum | Entscheidung | Begruendung |
|-------|-------------|-------------|
| 2026-06-03 | THEME_PRESETS + documentTheme entfernt | ADR 2026-04 Originalentscheid wiederhergestellt |
| 2026-06-03 | AI-Enhancement statt statischer Presets | Kontextbasierte Anpassung ohne Pflege eines Preset-Katalogs |
| 2026-06-03 | Vollstaendiges Style-Set im AI-Prompt | Alle 12 Sektionen muessen anpassbar sein |
| 2026-06-03 | Per-Table Overrides via content.tableStyle | Jede Tabelle kann eigene Styles haben |
| 2026-06-03 | Auto-Column-Alignment | Deterministische Heuristik ohne AI-Call |
## Betroffene Dateien
- `serviceGeneration/styleDefaults.py` — DEFAULT_STYLE, resolveStyle, deepMerge
- `serviceGeneration/mainServiceGeneration.py` — renderReport, _enhanceStyleWithAi
- `serviceGeneration/renderers/documentRendererBaseTemplate.py` — _convertUnifiedStyleToInternal, _inferColumnAlignments
- `serviceGeneration/renderers/rendererPdf.py` — Smart Table, Cover, Caption, Code Border
- `serviceGeneration/renderers/rendererDocx.py` — h3/h4, List, Code, Cover, Caption, Smart Table
- `serviceGeneration/renderers/rendererPptx.py` — Heading-Fix, List, Code, Smart Table
- `serviceGeneration/renderers/rendererXlsx.py` — Heading-Fix, List, Code Border, Smart Table
- `serviceGeneration/renderers/rendererHtml.py` — Legacy entfernt, Heading Spacing, Caption CSS
- `serviceAgent/coreTools/_mediaTools.py` — documentTheme entfernt
- `workflows/methods/methodAi/*` — documentTheme entfernt
- `serviceAi/mainServiceAi.py` — documentTheme entfernt
## Links
- Kanonische Referenz: [b-reference/platform-core/document-rendering.md](../../b-reference/platform-core/document-rendering.md)
- ADR: [c-work/4-done/2026-04-ai-reports-theming-and-pipeline.md](2026-04-ai-reports-theming-and-pipeline.md)
- Vorgaenger: [c-work/4-done/2026-06-po-cleanup-neutralization-docgen.md](2026-06-po-cleanup-neutralization-docgen.md) (A3)

View file

@ -14,6 +14,11 @@ Skip: reine Refactors, Formatting, Lint, Dep-Bumps, Test-only, Wiki-Tippfehler.
## 2026-06-03
- 2026-06-03 | refactor | platform-core | **Style-System Overhaul: THEME_PRESETS + documentTheme entfernt, AI-Enhancement aktiviert**: `THEME_PRESETS`, `resolveTheme()` und `documentTheme`-Parameter end-to-end entfernt (styleDefaults, mainServiceGeneration, _mediaTools, methodAi, generateDocument, documentPath, mainServiceAi, mainTrustee). Statische Presets ersetzt durch AI-getriebene Style-Enhancement (`_enhanceStyleWithAi` in mainServiceGeneration); DEFAULT_STYLE auf Cursor/VS-Code-Aesthetik modernisiert (Calibri, GitHub-Farben, subtile Rahmen). Dead Code aus allen 5 Renderern entfernt (_getStyleSet, _enhanceStylesWithAI, _getDefaultStyleSet, _validateStylesContrast etc.). (c-work: c-work/4-done/2026-06-style-system-overhaul-smart-tables.md)
- 2026-06-03 | fix | platform-core | **Style-Chain-Luecken geschlossen**: AI-Enhancement-Prompt bekommt jetzt das vollstaendige Style-Set (~920 Bytes) statt nur fonts/colors/table (3 von 12 Sektionen). `_convertUnifiedStyleToInternal` erweitert um page, image, table font sizes, borderWidth, codeBlock.borderColor, coverPage, caption, table_banding, table_padding, fonts, colors. Fallback-Farben an DEFAULT_STYLE angeglichen (#1F3864->#24292e, lineSpacing 1.15->1.5). Heading-Key-Mismatch in XLSX/PPTX behoben (heading->heading{level}); DOCX h3/h4 Styles registriert.
- 2026-06-03 | feat | platform-core | **Smart Table Styling**: Per-Table Style-Overrides via `content.tableStyle` im JSON-Block (deep-merge mit globalem Table-Style). Neue Style-Keys: `borderStyle` (grid/horizontal/none), `bandingEnabled` (Toggle), `cellPaddingPt`. Automatische Spaltenausrichtung (`_inferColumnAlignments`: Zahlen rechts, Daten zentriert, Text links) oder explizit via `columnAlignments`. Neue Schema-Sektionen `coverPage` und `caption` in DEFAULT_STYLE. Alle 5 Renderer (PDF/DOCX/PPTX/XLSX/HTML) implementieren borderStyle-Varianten, banding-Toggle und columnAlignments.
- 2026-06-03 | refactor | platform-core | **HTML-Renderer Legacy-Pfad entfernt**: `_getStyleSet`, `_getDefaultStyleSet` und zugehoerige Legacy-AI-Styling-Logik aus rendererHtml.py entfernt. Nur noch der Unified-Style-Pfad ueber `_convertUnifiedStyleToInternal` + `_generateCssFromUnifiedStyle` ist aktiv.
- 2026-06-03 | docs | wiki | **Kanonische Referenzseite Dokumenten-Rendering**: Neue `b-reference/platform-core/document-rendering.md` dokumentiert die vollstaendige Style-Resolution-Pipeline (DEFAULT_STYLE -> Agent-Overrides -> AI-Enhancement -> Per-Element-Overrides), Table-Rendering-Modell, Renderer-Architektur, Font-Resolution, AI-Style-Enhancement-Prompt. TOPICS.md ergaenzt. ADR- und PO-Cleanup-Docs nachgefuehrt.
- 2026-06-03 | refactor | * | **Scope von DataSource entfernt (Datenschutz)**: Scope-Flag, -Icon und -Funktionalitaet komplett aus der UDB (Sources-Tab) entfernt — persoenliche Datenquellen duerfen nicht gescoped werden. DB-Spalte `DataSource.scope` bleibt als deprecated, wird nicht mehr gelesen/geschrieben. UDB-Backend (`udbNodes.py`, `_inheritFlags.py`, `routeUdb.py`), Frontend (`UdbSourcesProvider.tsx`), Ingest (`subConnectorIngestConsumer.py`), Auth (`routeDataSources.py`) bereinigt. Scope existiert nur noch bei Files (folder-files). Wiki (`unified-data-bar.md`) aktualisiert. Tests angepasst.
## 2026-06-02

View file

@ -0,0 +1,59 @@
<!-- docId: IMS-00 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:4-10; 27001:4-10 -->
# IMS-Handbuch -- Integriertes Managementsystem PowerOn AG
Dachdokument des integrierten Managementsystems (IMS) der PowerOn AG. Das IMS deckt **ISO 9001 (Qualität)** und **ISO/IEC 27001 (Informationssicherheit)** gemeinsam ab. Beide Normen teilen die High-Level-Structure (Annex SL, Kapitel 4-10); dieses Handbuch und die referenzierten Dokumente bilden ein einziges, doppelt verwendetes Dokumentenset.
## 1. Zweck
Das IMS stellt sicher, dass PowerOn
- Produkte und Dienstleistungen in gleichbleibender Qualität liefert (ISO 9001),
- Informationen und Kundendaten vertraulich, integer und verfügbar hält (ISO 27001),
- gesetzliche, vertragliche und regulatorische Anforderungen erfüllt,
- sich kontinuierlich verbessert (KVP) und auditierbar bleibt.
## 2. Geltungsbereich (Kurzfassung)
Gesamte PowerOn AG inkl. Entwicklung, Betrieb und Produktmanagement der **PORTA Enterprise KI-Plattform** (`api.poweron.swiss`). Vollständige Fassung: [01_kontext/geltungsbereich-scope.md](01_kontext/geltungsbereich-scope.md).
## 3. Aufbau des IMS (Navigationskarte)
| Kapitel (ISO) | Ordner | Inhalt |
|---|---|---|
| 4 Kontext | `01_kontext/` | Kontext & interessierte Parteien, Geltungsbereich |
| 5 Führung | `02_fuehrung/` | QM-Politik, IS-Politik, Rollen |
| 6 Planung | `03_planung/` | Risikomethodik, Risikoregister, SoA, Ziele/KPI |
| 7 Unterstützung | `04_unterstuetzung/` | Kompetenz/Schulung, Kommunikation, Dokumentenlenkung, Register |
| 8 Betrieb + Annex A | `05_betrieb/` | Operative Prozesse & Sicherheits-Controls |
| 9 Bewertung | `06_bewertung/` | Internes Audit, Management-Review, Monitoring |
| 10 Verbesserung | `07_verbesserung/` | Korrekturmassnahmen/KVP, Massnahmenregister |
| Mappings | `mappings/` | SoA/Annex-A-, ISO-9001-Klausel-, CACC-Crosswalk |
| Cockpit | `cockpit/` | HTML-Management-Cockpit (Generator + generierte Datei) |
## 4. Dokumentenpyramide
1. **Ebene 1 -- Politiken / Handbuch:** dieses Handbuch, QM-Politik, IS-Politik, Geltungsbereich, Ziele.
2. **Ebene 2 -- Verfahren / Prozesse:** Risiko, Change, Incident, internes Audit, Management-Review, KVP.
3. **Ebene 3 -- Arbeitsanweisungen / Runbooks:** BCM-Runbook, Datenbank-Handling, Deployment.
4. **Ebene 4 -- Records / Nachweise:** Risikoregister, Audit-Berichte, Schulungsnachweise, Logs, Massnahmenregister.
## 5. Verantwortung der obersten Leitung
Die Geschäftsführung verpflichtet sich zum Aufbau, Betrieb und zur kontinuierlichen Verbesserung des IMS, stellt die erforderlichen Ressourcen bereit, gibt die Politiken frei und führt das Management-Review durch (Details: [Führung](02_fuehrung/), [Management-Review](06_bewertung/management-review.md)).
## 6. Dokumentenlenkung
Alle gelenkten Dokumente tragen einen einheitlichen Metadaten-Header und werden über Git/Forgejo versioniert und per Pull-Request-Review freigegeben. Verfahren: [04_unterstützung/dokumentenlenkung.md](04_unterstuetzung/dokumentenlenkung.md). Zentrale Übersicht: [04_unterstützung/dokumentenregister.md](04_unterstuetzung/dokumentenregister.md).
## 7. Status des IMS
Aufbauphase (Fast-Track). Ziel: ein gelebtes, audit-reifes IMS; Auswahl der Zertifizierungsstelle ist bewusst nachgelagert. Offene Punkte werden im [Massnahmenregister](07_verbesserung/massnahmen-register.md) geführt.

View file

@ -0,0 +1,47 @@
<!-- docId: IMS-04-02 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:4.3-4.4; 27001:4.3 -->
# Geltungsbereich (Scope) des IMS
**Dokumenttyp:** Grundlagendokument (Pflichtdokument ISO 9001 4.3 / ISO 27001 4.3)
## 1. Scope-Statement
> Das integrierte Managementsystem der PowerOn AG umfasst die **Entwicklung, den Betrieb, das Produktmanagement und den Support der PORTA Enterprise KI-Plattform** (Multi-Tenant-SaaS, `api.poweron.swiss`) sowie die zugehörigen unterstützenden Prozesse der gesamten PowerOn AG.
>
> Es deckt **ISO 9001:2015** (Qualitätsmanagement) und **ISO/IEC 27001:2022** (Informationssicherheit) ab.
## 2. Eingeschlossen
- Software-Entwicklung (SDLC), Release- und Change-Management.
- Betrieb der Plattform auf Infomaniak Public Cloud (Schweiz): `api.poweron.swiss`, `db.poweron.swiss`.
- Entwicklungs-/Deployment-System (Forgejo, CI/CD).
- Produktmanagement, Anforderungsmanagement, Kundensupport.
- Verwaltung von Drittdiensten/Subunternehmern (inkl. externe LLM-Provider).
- Unterstützungsprozesse: Personal/Kompetenz, Beschaffung, IT-Sicherheit, Dokumentenlenkung.
## 3. Standorte und Mittel
- Cloud-Infrastruktur: Infomaniak (Schweiz).
- Verteiltes Klein-Team; Arbeitsmittel und Remote-Zugriff gemäss [Zugriffsmanagement](../05_betrieb/02_Zugriffsmanagement_IAM_PAM.md).
## 4. Schnittstellen und Abhängigkeiten
- Externe LLM-Provider (Primär OpenAI/USA) -- Inhaltsdaten verlassen zur KI-Verarbeitung die Schweiz; abgesichert über AVV/DPA + EU-SCC und Neutralisierung. Siehe [Drittanbieter-Inventar](../05_betrieb/20260528_drittanbieter-inventar.md).
- Authentifizierungs-Dienste (Microsoft Entra, Google), E-Mail-Dienste.
## 5. Ausschlüsse / Nichtanwendbarkeit
- ISO 9001 Kap. 8.3 (Entwicklung) ist **anwendbar** (PowerOn entwickelt eigenes Produkt) -- kein Ausschluss.
- Annex-A-Controls von ISO 27001 werden nicht pauschal ausgeschlossen; Nichtanwendbarkeit wird einzeln im [SoA](../03_planung/statement-of-applicability-soa.md) begründet (z. B. rein physische Rechenzentrums-Controls, die beim Cloud-Provider liegen).
## 6. Begründung kompensierender Massnahmen
Aufgrund der kleinen Teamgrösse ist eine vollständige Funktionstrennung nicht überall möglich. Wo Controls eine grössere Organisation voraussetzen, greifen kompensierende Massnahmen (Vier-Augen-Prinzip bei Releases, Protokollierung privilegierter Zugriffe, externe Vergabe des internen Audits). Diese sind in den jeweiligen Betriebsdokumenten und im SoA dokumentiert.

View file

@ -0,0 +1,72 @@
<!-- docId: IMS-04-01 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:4.1-4.2; 27001:4.1-4.2 -->
# Kontext der Organisation & interessierte Parteien
**Dokumenttyp:** Grundlagendokument
ISO 9001 / 27001 Kap. 4.1-4.2: Bestimmung des organisatorischen Kontexts und der relevanten interessierten Parteien samt deren Anforderungen.
## 1. Organisation
PowerOn AG ist ein Schweizer Software-Unternehmen und betreibt die **PORTA Enterprise KI-Plattform** -- eine Multi-Tenant-SaaS-Lösung mit Feature-Store-Modell, AI-Agent-Workspace und mandantenweiter Datenneutralisierung. Zielkunden sind mittlere bis grosse Unternehmen in datenschutzsensiblen Branchen (Finanzwesen, Treuhand, Immobilien, Beratung). Sehr kleines Team (2-5 Personen).
## 2. Externe Themen (Kontext)
- Regulatorik: CH nDSG/revDSG, EU-DSGVO, für Bankkunden FINMA-Rundschreiben 2018/3 & 2023/1, GLKB Cloud Assessment (CACC).
- Markt: hohe Erwartung an Datensouveränität (CH-Hosting), KI-Transparenz, Nachweisbarkeit (ISO 27001/9001 als Einkaufskriterium).
- Technologie: Abhängigkeit von externen LLM-Providern (OpenAI USA u. a.), Cloud-Hosting Infomaniak (CH).
- Bedrohungslage: Web-/Cloud-Angriffe, Lieferkettenrisiken, KI-spezifische Risiken (Prompt-Injection, Datenabfluss).
## 3. Interne Themen (Kontext)
- Kleines Team -> Rollenbuendelung, eingeschränkte Funktionstrennung (kompensierende Massnahmen).
- Hoher Automatisierungsgrad (Forgejo CI/CD, Infrastruktur, Wiki-basierte Doku).
- Wissenskonzentration auf wenige Personen (Schlüsselpersonenrisiko).
## 4. Interessierte Parteien und Anforderungen
| Interessierte Partei | Wesentliche Anforderungen |
|---|---|
| Kunden (inkl. Banken/Treuhänder) | Datenschutz, Vertraulichkeit, Verfügbarkeit (SLA), Nachweise/Zertifikate, Auditierbarkeit |
| Endnutzer | Funktionierende, sichere, performante Plattform; Datenschutzrechte |
| Geschäftsführung/Eigner | Wirtschaftlichkeit, Reputation, Compliance, beherrschbares Risiko |
| Mitarbeitende | Klare Prozesse, sichere Arbeitsmittel, Kompetenzentwicklung |
| Aufsicht/Regulatoren | Einhaltung Datenschutz- und Finanzmarktvorgaben |
| Lieferanten/Subunternehmer | Klare Verträge, AVVs, Sicherheitsanforderungen |
| Zertifizierungsstelle | Normkonformes, gelebtes, nachweisbares Managementsystem |
## 5. Geltungsbereich des IMS
Festlegung in [geltungsbereich-scope.md](geltungsbereich-scope.md).
## 6. Wesentliche Prozesse (Prozesslandkarte)
```mermaid
flowchart LR
subgraph fuehrung [Führungsprozesse]
F1["Strategie & Management-Review"]
F2["Risiko- & Compliance-Management"]
end
subgraph kern [Kernprozesse]
K1["Produktmanagement & Anforderungen"]
K2["Software-Entwicklung (SDLC)"]
K3["Release & Change Management"]
K4["Betrieb & Support der PORTA-Plattform"]
end
subgraph support [Unterstützungsprozesse]
S1["Beschaffung & Lieferanten"]
S2["Personal & Kompetenz"]
S3["IT-Sicherheit & Infrastruktur"]
S4["Dokumentenlenkung"]
end
F1 --> K1 --> K2 --> K3 --> K4
F2 --> K2
support --> kern
```

View file

@ -1,3 +1,13 @@
<!-- docId: IMS-05-02 -->
<!-- status: entwurf -->
<!-- version: 1.0 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 27001:5.2,5.1; 9001:5.2 -->
# Informationssicherheitsrichtlinie (ISMS-Dachdokument)
**Dokumenttyp:** Richtlinie

View file

@ -0,0 +1,35 @@
<!-- docId: IMS-05-01 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: öffentlich -->
<!-- isoRefs: 9001:5.2 -->
# Qualitätspolitik
**Dokumenttyp:** Politik (Pflichtdokument ISO 9001 5.2)
**Geltungsbereich:** Gesamte PowerOn AG
## 1. Unser Qualitätsverständnis
Die PowerOn AG entwickelt und betreibt mit der PORTA-Plattform sichere, zuverlässige und nutzbringende KI-Lösungen für datenschutzsensible Branchen. Qualität bedeutet für uns: zugesagte Funktionalität, Verfügbarkeit und Sicherheit verlässlich zu liefern und kontinuierlich zu verbessern.
## 2. Grundsätze
1. **Kundenorientierung:** Wir verstehen Kundenanforderungen und setzen sie nachvollziehbar in Produkt und Service um.
2. **Nachvollziehbare Prozesse:** Entwicklung, Release und Support folgen dokumentierten, wiederholbaren Prozessen (siehe [Feature-/Release-/Bug-Prozess](../05_betrieb/20260528_feature_release_bugfix.md)).
3. **Qualität vor Tempo:** Vier-Augen-Prinzip, Staging-Verifikation und Akzeptanzkriterien vor jedem Produktiv-Release.
4. **Datenschutz & Sicherheit als Qualitätsmerkmal:** Qualität und Informationssicherheit sind untrennbar (integriertes Managementsystem).
5. **Faktenbasierte Entscheidungen:** Wir steuern über Kennzahlen (siehe [Ziele & Kennzahlen](../03_planung/ziele-und-kennzahlen.md)).
6. **Kontinuierliche Verbesserung:** Abweichungen werden als Chance verstanden und über den [KVP-Prozess](../07_verbesserung/korrekturmassnahmen-und-kvp.md) behandelt.
## 3. Verpflichtung der Leitung
Die Geschäftsführung verpflichtet sich zur Erfüllung anwendbarer Anforderungen, zur Bereitstellung der nötigen Ressourcen und zur fortlaufenden Verbesserung des Qualitätsmanagementsystems. Qualitätsziele werden in [Ziele & Kennzahlen](../03_planung/ziele-und-kennzahlen.md) festgelegt und im [Management-Review](../06_bewertung/management-review.md) bewertet.
## 4. Verbindlichkeit
Diese Politik ist für alle Mitarbeitenden verbindlich, wird kommuniziert ([Kommunikation](../04_unterstuetzung/kommunikation.md)) und mindestens jährlich auf Angemessenheit überprüft.

View file

@ -0,0 +1,41 @@
<!-- docId: IMS-05-03 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:5.3; 27001:5.3 -->
# Rollen, Verantwortlichkeiten und Befugnisse
**Dokumenttyp:** Grundlagendokument (ISO 9001 / 27001 Kap. 5.3)
Aufgrund der kleinen Teamgrösse (2-5 Personen) werden Rollen gebuendelt. Bündelung ist zulässig; entscheidend ist die dokumentierte, namentliche Zuweisung. Wo Funktionstrennung fehlt, greifen kompensierende Massnahmen.
## 1. Rollenmatrix
| Rolle | Verantwortung / Befugnis | Träger |
|---|---|---|
| Oberste Leitung (Geschäftsführung) | Gesamtverantwortung IMS, Freigabe Politiken, Ressourcen, Management-Review | Patrick Motsch (p.motsch@poweron.swiss) |
| Informationssicherheits-Beauftragter (ISB / CISO-Funktion) | ISMS-Pflege, Risikobeurteilung, SoA, Steuerung Annex-A-Controls | Patrick Motsch |
| Qualitätsmanagement-Beauftragter (QMB) | QMS-Pflege, Prozesssteuerung, KVP, Audit-Koordination | Patrick Motsch |
| Dokumentenlenkungs-Verantwortlicher | Pflege Header-Standard, Dokumentenregister, Review-Zyklen | Patrick Motsch |
| Datenschutzverantwortlicher | DSG/DSGVO, AVV-Management | Patrick Motsch |
| Betrieb / DevOps & Incident-Verantwortlicher | Server, Deployment, Backups, Vorfallbehandlung | Patrick Motsch |
| Drittdienst-/Lieferanten-Verantwortlicher | Drittanbieter-Inventar, AVVs, Subunternehmer | Patrick Motsch |
| Risiko-Eigner (Risk Owner) | Verantwortung je wesentlichem Risiko/Asset | gemäss [Risikoregister](../03_planung/risikoregister.md) |
| Interner Auditor | Unabhängige Prüfung des IMS | **Extern, noch zu benennen** (Unabhängigkeit erforderlich) |
## 2. Hinweis zur Funktionstrennung
Da derzeit zentrale Rollen bei einer Person liegen, sind folgende kompensierende Massnahmen verbindlich:
- **Vier-Augen-Prinzip** bei Code-Review und Produktiv-Releases ([feature_release_bugfix.md](../05_betrieb/20260528_feature_release_bugfix.md)).
- **Protokollierung privilegierter Zugriffe** ([Logging & Monitoring](../05_betrieb/11_Logging_und_Monitoring.md)).
- **Internes Audit wird extern vergeben**, um Unabhängigkeit sicherzustellen ([Internes Audit](../06_bewertung/internes-audit.md)).
## 3. Pflege
Änderungen an der Rollenzuweisung werden hier nachgeführt und im Management-Review bestätigt. Bei Teamwachstum sind Rollen zu entflechten (insb. interner Auditor, Release-Freigabe vs. Entwicklung).

View file

@ -0,0 +1,61 @@
<!-- docId: IMS-06-01 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 27001:6.1.2,6.1.3,8.2,8.3; 9001:6.1 -->
# Risikomanagement-Methodik
**Dokumenttyp:** Verfahren (Pflichtdokument ISO 27001 6.1.2)
**Geltungsbereich:** Informationssicherheits- und Qualitätsrisiken im IMS-Scope
## 1. Zweck
Dieses Verfahren legt fest, wie PowerOn Risiken und Chancen identifiziert, bewertet, behandelt und überwacht -- für ISO 27001 (Informationssicherheitsrisiken) und ISO 9001 (Risiken/Chancen für die Prozess- und Produktqualität).
## 2. Vorgehen
```mermaid
flowchart LR
id["1 Identifikation (Assets, Bedrohungen, Schwachstellen, Prozessrisiken)"] --> an["2 Analyse (Eintritt x Auswirkung)"]
an --> ev["3 Bewertung gegen Akzeptanzkriterien"]
ev --> tr["4 Behandlung (vermeiden/vermindern/übertragen/akzeptieren)"]
tr --> mo["5 Überwachung & Review"]
mo --> id
```
## 3. Bewertungsskala
**Eintrittswahrscheinlichkeit (W)** und **Auswirkung (A)** je 1-4:
| Stufe | W (Wahrscheinlichkeit) | A (Auswirkung) |
|---|---|---|
| 1 | selten (< 1x/Jahr) | gering (kaum spuerbar) |
| 2 | möglich | spuerbar (begrenzt, intern) |
| 3 | wahrscheinlich | erheblich (Kunde/Daten betroffen) |
| 4 | sehr wahrscheinlich (laufend) | kritisch (Datenverlust, Ausfall, Rechtsbruch) |
**Risikowert = W x A** (1-16).
| Risikowert | Klasse | Vorgabe |
|---|---|---|
| 1-3 | niedrig | akzeptieren, beobachten |
| 4-8 | mittel | Behandlung planen, terminiert |
| 9-12 | hoch | Behandlung priorisiert, zeitnah |
| 13-16 | sehr hoch | sofortige Massnahmen, Leitung informieren |
## 4. Risikoakzeptanzkriterium
Risiken der Klasse **niedrig** können ohne weitere Massnahme akzeptiert werden. Ab **mittel** ist eine dokumentierte Behandlung mit Owner und Termin erforderlich. Restrisiken ab **hoch** müssen von der obersten Leitung formal akzeptiert werden.
## 5. Behandlungsoptionen und Bezug zum SoA
Für Informationssicherheitsrisiken werden Massnahmen primär aus den **ISO 27001 Annex-A-Controls** abgeleitet; die Anwendbarkeit und Umsetzung wird im [Statement of Applicability](statement-of-applicability-soa.md) dokumentiert. Umsetzungsmassnahmen und Restrisiken werden im [Risikoregister](risikoregister.md) geführt; offene Massnahmen laufen ins [Massnahmenregister](../07_verbesserung/massnahmen-register.md).
## 6. Turnus
Risikobeurteilung mindestens **jährlich** sowie **anlassbezogen** (wesentliche Architektur-/Prozessänderung, schwerer Incident, neuer wesentlicher Lieferant). Ergebnisse fliessen ins [Management-Review](../06_bewertung/management-review.md).

View file

@ -0,0 +1,32 @@
<!-- docId: IMS-06-02 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2026-12-03 -->
<!-- classification: vertraulich -->
<!-- isoRefs: 27001:6.1.2,8.2; 9001:6.1 -->
# Risikoregister
**Dokumenttyp:** Record (Ergebnis der Risikobeurteilung)
Bewertung gemäss [Risikomanagement-Methodik](risikomanagement-methodik.md). W = Wahrscheinlichkeit, A = Auswirkung, R = W x A. Behandlungsmassnahmen mit Owner/Termin laufen ins [Massnahmenregister](../07_verbesserung/massnahmen-register.md).
**Stand der Erstbeurteilung:** 2026-06-03 (Entwurf -- in einer Erst-Risikoworkshop-Sitzung zu validieren).
| ID | Risiko | Kategorie | W | A | R | Klasse | Behandlung | Owner | Annex-A-Bezug |
|---|---|---|---|---|---|---|---|---|---|
| R-01 | Schlüsselpersonenrisiko (Wissen/Zugriffe auf eine Person konzentriert) | Organisation | 3 | 4 | 12 | hoch | Vertretung, Dokumentation, Notfallzugriff (Break-Glass) | Patrick Motsch | A.5.2, A.5.4 |
| R-02 | Abfluss sensibler Inhaltsdaten an externe LLM-Provider (OpenAI/USA) | Datenschutz | 3 | 4 | 12 | hoch | Neutralisierung, AVV/DPA + EU-SCC, Zero-Retention prüfen | Patrick Motsch | A.5.14, A.8.12 |
| R-03 | Fehlende/unbestätigte MFA auf Admin-/Server-Zugängen | Zugriff | 2 | 4 | 8 | mittel | MFA flächendeckend bestätigen/erzwingen | Patrick Motsch | A.5.17, A.8.5 |
| R-04 | Backup nicht wiederherstellbar (Restore nie getestet) | Verfügbarkeit | 2 | 4 | 8 | mittel | Restore-Test durchführen & protokollieren | Patrick Motsch | A.8.13 |
| R-05 | Ausfall Schlüssel-Lieferant (Infomaniak / LLM-Provider) | Lieferkette | 2 | 3 | 6 | mittel | BCM/DR-Plan, Exit-Strategie, Provider-Alternativen | Patrick Motsch | A.5.19, A.5.30 |
| R-06 | Sicherheitsluecke durch verspäteten Patch | Technik | 2 | 3 | 6 | mittel | Patch-/Schwachstellenprozess einhalten | Patrick Motsch | A.8.8 |
| R-07 | Unzureichende Log-Aufbewahrung/Manipulationsschutz | Nachweis | 2 | 3 | 6 | mittel | Retention & Integritätsschutz festlegen | Patrick Motsch | A.8.15 |
| R-08 | Fehlerhafte Release führt zu Produktionsstörung | Qualität | 2 | 3 | 6 | mittel | Staging-Verifikation, Vier-Augen, Rollback | Patrick Motsch | A.8.31 (9001:8.5) |
| R-09 | Prompt-Injection / Missbrauch KI-Funktionen | KI/Technik | 3 | 2 | 6 | mittel | Eingabebereinigung, Read-only DB-Zugriff, Rate-Limit | Patrick Motsch | A.8.28 |
## Pflegehinweis
Neue Risiken fortlaufend ergänzen, R bei Massnahmenwirkung neu bewerten (Restrisiko). Restrisiken der Klasse hoch+ erfordern formale Akzeptanz durch die oberste Leitung (Vermerk in Spalte Behandlung oder im Management-Review-Protokoll).

View file

@ -0,0 +1,137 @@
<!-- docId: IMS-06-03 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2026-12-03 -->
<!-- classification: vertraulich -->
<!-- isoRefs: 27001:6.1.3,AnnexA -->
# Statement of Applicability (SoA) -- ISO/IEC 27001:2022 Annex A
**Dokumenttyp:** Pflichtdokument (ISO 27001 6.1.3 d)
**Stand:** 2026-06-03 (Entwurf)
Dieses SoA listet alle 93 Annex-A-Controls (2022) mit Anwendbarkeit, Begründung, Umsetzungsstatus und Verweis auf das umsetzende Dokument. Status: **Umgesetzt / Teilweise / Geplant / N/A**. Offene/teilweise Punkte sind im [Massnahmenregister](../07_verbesserung/massnahmen-register.md) geführt.
Legende Anwendbarkeit: **Ja** = anwendbar; **N/A** = nicht anwendbar (mit Begründung). Cloud-Betrieb bei Infomaniak (CH): bestimmte physische Controls liegen beim Provider (Anwendbar, "geerbt").
## A.5 Organisatorische Controls
| Control | Titel | Anwend. | Status | Referenz / Begründung |
|---|---|---|---|---|
| A.5.1 | Informationssicherheits-Politiken | Ja | Umgesetzt | [informationssicherheitspolitik.md](../02_fuehrung/informationssicherheitspolitik.md) |
| A.5.2 | Rollen & Verantwortlichkeiten | Ja | Umgesetzt | [rollen-verantwortlichkeiten.md](../02_fuehrung/rollen-verantwortlichkeiten.md) |
| A.5.3 | Aufgabentrennung | Ja | Teilweise | Klein-Team; kompensierend Vier-Augen-Prinzip, externes Audit |
| A.5.4 | Verantwortung der Leitung | Ja | Umgesetzt | [00_IMS-Handbuch.md](../00_IMS-Handbuch.md), Management-Review |
| A.5.5 | Kontakt zu Behörden | Ja | Geplant | Meldewege (EDOEB/FINMA) in [Incident Response](../05_betrieb/07_Incident_Response_und_Meldewesen.md) festhalten |
| A.5.6 | Kontakt zu Interessengruppen | Ja | Teilweise | Security-Quellen/CERT-Feeds; formalisieren |
| A.5.7 | Threat Intelligence | Ja | Teilweise | [Schwachstellenmanagement](../05_betrieb/10_Schwachstellenmanagement.md) |
| A.5.8 | IS im Projektmanagement | Ja | Umgesetzt | [SDLC](../05_betrieb/15_Sichere_Softwareentwicklung_SDLC.md), Tech-Workshop |
| A.5.9 | Inventar der Werte (Assets) | Ja | Teilweise | [Drittanbieter-Inventar](../05_betrieb/20260528_drittanbieter-inventar.md); Asset-Inventar ergänzen |
| A.5.10 | Zulässige Nutzung von Werten | Ja | Geplant | Acceptable-Use in IS-Politik konkretisieren |
| A.5.11 | Rückgabe von Werten | Ja | Geplant | Offboarding-Checkliste ([Mitarbeitersicherheit](../05_betrieb/03_Mitarbeitersicherheit_und_Screening.md)) |
| A.5.12 | Klassifizierung von Information | Ja | Teilweise | Klassifizierungsschema (Header `classification`); ausweiten |
| A.5.13 | Kennzeichnung von Information | Ja | Teilweise | Header-Klassifizierung; Daten-Labeling ergänzen |
| A.5.14 | Informationsübertragung | Ja | Umgesetzt | [Verschlüsselung](../05_betrieb/04_Verschluesselung_und_Schluesselmanagement.md), TLS, [Neutralisierung](../05_betrieb/neutralisierung-detail.md) |
| A.5.15 | Zugangssteuerung | Ja | Umgesetzt | [Zugriffsmanagement](../05_betrieb/02_Zugriffsmanagement_IAM_PAM.md), RBAC |
| A.5.16 | Identitätsmanagement | Ja | Umgesetzt | [Zugriffsmanagement](../05_betrieb/02_Zugriffsmanagement_IAM_PAM.md) |
| A.5.17 | Authentisierungsinformation | Ja | Teilweise | MFA-Status bestätigen (R-03) |
| A.5.18 | Zugangsrechte | Ja | Umgesetzt | [Zugriffsmanagement](../05_betrieb/02_Zugriffsmanagement_IAM_PAM.md) |
| A.5.19 | IS in Lieferantenbeziehungen | Ja | Umgesetzt | [Subunternehmer](../05_betrieb/17_Subunternehmer_Management.md) |
| A.5.20 | IS in Lieferantenvereinbarungen | Ja | Teilweise | AVVs vervollständigen (OpenAI Zero-Retention) |
| A.5.21 | IS in der IKT-Lieferkette | Ja | Teilweise | [Drittanbieter-Inventar](../05_betrieb/20260528_drittanbieter-inventar.md) |
| A.5.22 | Überwachung der Lieferantenleistung | Ja | Geplant | Review-Turnus Lieferanten festlegen |
| A.5.23 | IS bei Nutzung von Cloud-Diensten | Ja | Umgesetzt | Infomaniak (CH); [Netzwerk/Infra](../05_betrieb/12_Netzwerk_und_Infrastruktursicherheit.md) |
| A.5.24 | Incident-Management Planung | Ja | Umgesetzt | [Incident Response](../05_betrieb/07_Incident_Response_und_Meldewesen.md) |
| A.5.25 | Bewertung von IS-Ereignissen | Ja | Umgesetzt | [Incident Response](../05_betrieb/07_Incident_Response_und_Meldewesen.md) |
| A.5.26 | Reaktion auf IS-Vorfälle | Ja | Umgesetzt | [Incident Response](../05_betrieb/07_Incident_Response_und_Meldewesen.md) |
| A.5.27 | Lernen aus Vorfällen | Ja | Teilweise | Post-Incident-Review -> [KVP](../07_verbesserung/korrekturmassnahmen-und-kvp.md) |
| A.5.28 | Sammlung von Beweismitteln | Ja | Teilweise | Logs/Forensik in [Logging](../05_betrieb/11_Logging_und_Monitoring.md) |
| A.5.29 | IS während Störung | Ja | Umgesetzt | [BCM/DR](../05_betrieb/06_Business_Continuity_und_Disaster_Recovery.md) |
| A.5.30 | IKT-Bereitschaft für BC | Ja | Umgesetzt | [BCM-Runbook](../05_betrieb/20260528_bcm_runbook.md) |
| A.5.31 | Gesetzliche & vertragliche Anforderungen | Ja | Umgesetzt | [Recht/BestPractice](../05_betrieb/18_Analyse_Recht_und_BestPractice.md), AGB |
| A.5.32 | Geistiges Eigentum | Ja | Teilweise | Lizenz-/OSS-Compliance dokumentieren |
| A.5.33 | Schutz von Aufzeichnungen | Ja | Umgesetzt | [Datenaufbewahrung](../05_betrieb/13_Datenaufbewahrung_Loeschung_LegalHold.md) |
| A.5.34 | Datenschutz & PII-Schutz | Ja | Umgesetzt | [security-overview.md](../05_betrieb/security-overview.md), DSGVO-Funktionen |
| A.5.35 | Unabhängige IS-Prüfung | Ja | Geplant | Externes [internes Audit](../06_bewertung/internes-audit.md) |
| A.5.36 | Konformität mit Politiken | Ja | Teilweise | Audit + Konformitätskontrolle |
| A.5.37 | Dokumentierte Betriebsabläufe | Ja | Umgesetzt | Runbooks in `05_betrieb/` |
## A.6 Personenbezogene Controls
| Control | Titel | Anwend. | Status | Referenz / Begründung |
|---|---|---|---|---|
| A.6.1 | Sicherheitsüberprüfung (Screening) | Ja | Teilweise | [Mitarbeitersicherheit](../05_betrieb/03_Mitarbeitersicherheit_und_Screening.md); Hintergrundprüfung klären |
| A.6.2 | Arbeitsvertragsbedingungen | Ja | Teilweise | IS-Klauseln in Verträgen ergänzen |
| A.6.3 | Awareness, Schulung & Ausbildung | Ja | Geplant | [Kompetenz/Schulung](../04_unterstuetzung/ressourcen-kompetenz-schulung.md) |
| A.6.4 | Disziplinarverfahren | Ja | Geplant | Verfahren in HR-Doku festhalten |
| A.6.5 | Verantwortung nach Beendigung | Ja | Teilweise | Offboarding; NDA-Fortgeltung |
| A.6.6 | Vertraulichkeits-/NDA-Vereinbarungen | Ja | Teilweise | NDA-Vorlage sicherstellen |
| A.6.7 | Remote-Arbeit | Ja | Umgesetzt | [Zugriffsmanagement](../05_betrieb/02_Zugriffsmanagement_IAM_PAM.md), VPN/Geräte |
| A.6.8 | Meldung von IS-Ereignissen | Ja | Umgesetzt | [Incident Response](../05_betrieb/07_Incident_Response_und_Meldewesen.md) |
## A.7 Physische Controls
Eigene Büro-Infrastruktur minimal (Remote-Team); Rechenzentrums-Controls liegen beim Cloud-Provider Infomaniak (CH) und werden über dessen Zertifizierungen (ISO 27001) geerbt.
| Control | Titel | Anwend. | Status | Referenz / Begründung |
|---|---|---|---|---|
| A.7.1 | Physische Sicherheitsperimeter | Ja (geerbt) | Umgesetzt | Infomaniak RZ-Zertifizierung |
| A.7.2 | Physischer Zutritt | Ja (geerbt) | Umgesetzt | Infomaniak |
| A.7.3 | Sicherung von Büros/Räumen | Ja | Teilweise | Home-/Büro-Grundschutz |
| A.7.4 | Physische Überwachung | Ja (geerbt) | Umgesetzt | Infomaniak |
| A.7.5 | Schutz vor physischen/umweltbed. Bedrohungen | Ja (geerbt) | Umgesetzt | Infomaniak |
| A.7.6 | Arbeiten in Sicherheitsbereichen | N/A | N/A | Keine eigenen Sicherheitsbereiche |
| A.7.7 | Clear Desk / Clear Screen | Ja | Geplant | Regel in IS-Politik aufnehmen |
| A.7.8 | Platzierung & Schutz von Geräten | Ja | Teilweise | Endgeräte-Richtlinie |
| A.7.9 | Schutz von Werten ausserhalb | Ja | Teilweise | Geräteverschlüsselung |
| A.7.10 | Speichermedien | Ja | Teilweise | Verschlüsselung, sichere Löschung |
| A.7.11 | Versorgungseinrichtungen | Ja (geerbt) | Umgesetzt | Infomaniak |
| A.7.12 | Verkabelungssicherheit | Ja (geerbt) | Umgesetzt | Infomaniak |
| A.7.13 | Instandhaltung von Geräten | Ja | Teilweise | Patch/Wartung Endgeräte |
| A.7.14 | Sichere Entsorgung/Wiederverwendung | Ja | Geplant | Lösch-/Entsorgungsregel |
## A.8 Technologische Controls
| Control | Titel | Anwend. | Status | Referenz / Begründung |
|---|---|---|---|---|
| A.8.1 | Endgeräte der Nutzer | Ja | Teilweise | Endgeräte-Richtlinie, Verschlüsselung |
| A.8.2 | Privilegierte Zugangsrechte | Ja | Umgesetzt | [Zugriffsmanagement](../05_betrieb/02_Zugriffsmanagement_IAM_PAM.md) |
| A.8.3 | Informationszugriffsbeschränkung | Ja | Umgesetzt | RBAC, Mandantentrennung |
| A.8.4 | Zugriff auf Quellcode | Ja | Umgesetzt | Forgejo-RBAC |
| A.8.5 | Sichere Authentisierung | Ja | Teilweise | MFA bestätigen (R-03) |
| A.8.6 | Kapazitätsmanagement | Ja | Umgesetzt | [Kapazitätsmanagement](../05_betrieb/16_Kapazitaetsmanagement.md) |
| A.8.7 | Schutz vor Schadsoftware | Ja | Teilweise | Endpoint-Schutz, Dependency-Scans |
| A.8.8 | Management techn. Schwachstellen | Ja | Umgesetzt | [Schwachstellen](../05_betrieb/10_Schwachstellenmanagement.md), [Patch](../05_betrieb/09_Patch_Management.md) |
| A.8.9 | Konfigurationsmanagement | Ja | Teilweise | .env-Trennung; IaC/Konformität ausbauen |
| A.8.10 | Löschung von Information | Ja | Umgesetzt | [Datenaufbewahrung](../05_betrieb/13_Datenaufbewahrung_Loeschung_LegalHold.md), DSGVO-Löschung |
| A.8.11 | Datenmaskierung | Ja | Umgesetzt | [Neutralisierung](../05_betrieb/neutralisierung-detail.md) |
| A.8.12 | Verhinderung von Datenabfluss | Ja | Teilweise | Neutralisierung, Read-only DB-Zugriff KI |
| A.8.13 | Sicherung (Backup) | Ja | Teilweise | [Backup](../05_betrieb/05_Backup_und_Wiederherstellung.md); Restore-Test offen (R-04) |
| A.8.14 | Redundanz von Verarbeitungseinrichtungen | Ja | Teilweise | Provider-Redundanz; dokumentieren |
| A.8.15 | Protokollierung (Logging) | Ja | Umgesetzt | [Logging & Monitoring](../05_betrieb/11_Logging_und_Monitoring.md) |
| A.8.16 | Überwachung von Aktivitäten | Ja | Teilweise | Monitoring ausbauen |
| A.8.17 | Uhrzeitsynchronisation | Ja | Umgesetzt | NTP (Infra) |
| A.8.18 | Nutzung privilegierter Hilfsprogramme | Ja | Teilweise | Einschränkung/Protokollierung |
| A.8.19 | Software-Installation auf Betriebssystemen | Ja | Teilweise | Deployment über CI/CD |
| A.8.20 | Netzwerksicherheit | Ja | Umgesetzt | [Netzwerk/Infra](../05_betrieb/12_Netzwerk_und_Infrastruktursicherheit.md) |
| A.8.21 | Sicherheit von Netzwerkdiensten | Ja | Umgesetzt | TLS, Reverse Proxy |
| A.8.22 | Trennung von Netzwerken | Ja | Teilweise | Umgebungstrennung prod/int |
| A.8.23 | Web-Filterung | Ja | Teilweise | CORS, Egress-Kontrolle |
| A.8.24 | Nutzung von Kryptographie | Ja | Umgesetzt | [Verschlüsselung & Schlüsselmgmt](../05_betrieb/04_Verschluesselung_und_Schluesselmanagement.md) |
| A.8.25 | Sicherer Entwicklungslebenszyklus | Ja | Umgesetzt | [SDLC](../05_betrieb/15_Sichere_Softwareentwicklung_SDLC.md) |
| A.8.26 | Anforderungen an Anwendungssicherheit | Ja | Umgesetzt | [SDLC](../05_betrieb/15_Sichere_Softwareentwicklung_SDLC.md) |
| A.8.27 | Sichere Systemarchitektur & Engineering | Ja | Teilweise | Architektur-Prinzipien dokumentieren |
| A.8.28 | Sicheres Codieren | Ja | Umgesetzt | [Coding-Conventions](../../../d-guides/coding-conventions.md), Review |
| A.8.29 | Sicherheitstests in Entw./Abnahme | Ja | Teilweise | [Testing-Strategie](../../../d-guides/testing-strategy.md), Staging-Verifikation |
| A.8.30 | Ausgelagerte Entwicklung | N/A | N/A | Keine ausgelagerte Entwicklung |
| A.8.31 | Trennung Entw./Test/Produktion | Ja | Umgesetzt | env-prod/env-int, Staging |
| A.8.32 | Change Management | Ja | Umgesetzt | [Change Management](../05_betrieb/08_Change_Management.md) |
| A.8.33 | Testinformation | Ja | Geplant | Umgang mit Produktivdaten in Test klären |
| A.8.34 | Schutz von Systemen bei Audit-Tests | Ja | Teilweise | Auditzugriffe kontrolliert |
## Pflege
Bei jeder wesentlichen Änderung von Controls/Risiken aktualisieren. Das SoA wird im [Management-Review](../06_bewertung/management-review.md) bestätigt. Teilweise/Geplant-Einträge spiegeln sich im [Massnahmenregister](../07_verbesserung/massnahmen-register.md).

View file

@ -0,0 +1,47 @@
<!-- docId: IMS-06-04 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:6.2; 27001:6.2,9.1 -->
# Ziele & Kennzahlen (Qualität und Informationssicherheit)
**Dokumenttyp:** Pflichtdokument (ISO 9001 6.2 / ISO 27001 6.2)
**Messperiode:** Kalenderjahr 2026 (Erstfestlegung)
Ziele sind messbar, terminiert und einem Owner zugeordnet. Die Messung erfolgt gemäss [Monitoring & Messung](../06_bewertung/monitoring-messung.md); Bewertung im [Management-Review](../06_bewertung/management-review.md).
## 1. Qualitätsziele (ISO 9001)
| ID | Ziel | Kennzahl (KPI) | Zielwert | Owner |
|---|---|---|---|---|
| Q-1 | Stabile Releases | Anteil Releases ohne Rollback/Hotfix < 48h | >= 95 % | Patrick Motsch |
| Q-2 | Schnelle Fehlerbehebung | Einhaltung Bug-SLOs (kritisch 24h) | >= 90 % | Patrick Motsch |
| Q-3 | Nachvollziehbarkeit | Releases mit vollständigen Release Notes/CHANGELOG | 100 % | Patrick Motsch |
| Q-4 | Kundenzufriedenheit | Bearbeitete Support-Tickets in SLA | >= 90 % | Patrick Motsch |
## 2. Informationssicherheitsziele (ISO 27001)
| ID | Ziel | Kennzahl (KPI) | Zielwert | Owner |
|---|---|---|---|---|
| S-1 | Risiken unter Kontrolle | Offene Risiken Klasse hoch+ | 0 unbehandelt | Patrick Motsch |
| S-2 | Aktuelle Systeme | Kritische Schwachstellen gepatcht innert SLA | 100 % | Patrick Motsch |
| S-3 | Wiederherstellbarkeit | Erfolgreiche Restore-Tests pro Jahr | >= 2 | Patrick Motsch |
| S-4 | Zugriffssicherheit | Admin-/Server-Zugänge mit MFA | 100 % | Patrick Motsch |
| S-5 | Awareness | Mitarbeitende mit jährlicher IS-Schulung | 100 % | Patrick Motsch |
| S-6 | Vorfallreaktion | Incidents innerhalb Zielreaktionszeit behandelt | >= 95 % | Patrick Motsch |
## 3. IMS-Aufbauziel (2026)
| ID | Ziel | Kennzahl | Zielwert | Termin |
|---|---|---|---|---|
| IMS-1 | Gelebtes, audit-reifes IMS | 1 internes Audit + 1 Management-Review durchgeführt | erfüllt | 2026 Q3 |
| IMS-2 | Dokumentenpflege | Dokumente ohne überfälliges Review | 100 % | laufend |
## 4. Pflege
Zielwerte werden jährlich im Management-Review überprüft und neu festgelegt. Abweichungen lösen Massnahmen im [Massnahmenregister](../07_verbesserung/massnahmen-register.md) aus.

View file

@ -0,0 +1,73 @@
<!-- docId: IMS-07-03 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:7.5; 27001:7.5 -->
# Lenkung dokumentierter Information
**Dokumenttyp:** Verfahren
**Geltungsbereich:** Alle gelenkten Dokumente des IMS
ISO 9001:2015 Kap. 7.5 und ISO/IEC 27001:2022 Kap. 7.5 verlangen, dass dokumentierte Information erstellt, freigegeben, aktuell gehalten, geschuetzt und gelenkt wird. Dieses Verfahren beschreibt, wie PowerOn das umsetzt -- bewusst schlank und werkzeuggestützt über Git/Forgejo.
## 1. Einheitlicher Metadaten-Header
Jedes gelenkte IMS-Dokument beginnt mit folgendem Header (HTML-Kommentar, im gerenderten Markdown unsichtbar, vom Cockpit ausgewertet):
```
<!-- docId: IMS-XX -->
<!-- status: entwurf | freigegeben | abgelöst -->
<!-- version: 0.1 -->
<!-- owner: <Name> -->
<!-- approver: <Name/Gremium> -->
<!-- approvedDate: YYYY-MM-DD -->
<!-- nextReview: YYYY-MM-DD -->
<!-- classification: öffentlich | intern | vertraulich -->
<!-- isoRefs: 9001:<klausel>; 27001:<klausel/AnnexA> -->
```
| Feld | Bedeutung |
|---|---|
| `docId` | Eindeutige Dokument-ID (Schema: `IMS-<Kapitel>-<Laufnr>`) |
| `status` | `entwurf` (in Arbeit), `freigegeben` (gültig), `abgelöst` (ersetzt/veraltet) |
| `version` | Semantisch: 0.x = Entwurf, ab 1.0 = freigegeben; Minor bei inhaltlichen Änderungen |
| `owner` | Fachlich verantwortliche Person (Pflege) |
| `approver` | Freigebende Person/Gremium |
| `approvedDate` | Datum der letzten Freigabe |
| `nextReview` | Spätestes nächstes Review (Standard: +12 Monate) |
| `classification` | Schutzbedarf gemäss IS-Politik |
| `isoRefs` | Abgedeckte Normklauseln/Annex-A-Controls |
## 2. Lebenszyklus
```mermaid
flowchart LR
draft["entwurf (0.x)"] -->|"PR-Review + Freigabe"| released["freigegeben (>=1.0)"]
released -->|"Änderung"| draft
released -->|"ersetzt durch Nachfolger"| retired["abgelöst"]
```
1. **Erstellen/Ändern:** Auf Branch, Inhalt + Header pflegen.
2. **Freigabe:** Pull Request mit Review durch zweite Person (Vier-Augen-Prinzip); Merge = Freigabe. `status` -> `freigegeben`, `version` >= 1.0, `approvedDate` + `nextReview` setzen.
3. **Versionierung & Historie:** Git/Forgejo ist die verbindliche Versions- und Änderungshistorie (Commit = Änderungsnachweis).
4. **Ablösung:** Ersetzte Dokumente erhalten `status: abgelöst` und einen Vorwärts-Link zum Nachfolger; sie werden nicht gelöscht (Nachvollziehbarkeit).
## 3. Review-Zyklus ("gepflegt")
- Jedes Dokument hat ein `nextReview`-Datum (Standard 12 Monate, anlassbezogen früher).
- Das [Management-Cockpit](../cockpit/) listet überfällige und anstehende Reviews automatisch auf der Pendenzen-Seite.
- Reviews werden im [Dokumentenregister](dokumentenregister.md) nachgeführt; fällige Reviews erzeugen bei Bedarf einen Eintrag im [Massnahmenregister](../07_verbesserung/massnahmen-register.md).
## 4. Schutz und Zugriff
- Vertrauliche Dokumente folgen der Klassifizierung der IS-Politik; das Repository ist zugriffsgeschuetzt (Forgejo-RBAC).
- Externe Verteilung nur in freigegebenem Stand; das Cockpit kann als in sich geschlossene HTML zum Teilen erzeugt werden.
## 5. Externe Dokumente
Extern vorgegebene Dokumente (Normtexte, Verträge, AVVs der Lieferanten) werden im [Drittanbieter-Inventar](../05_betrieb/20260528_drittanbieter-inventar.md) bzw. als Records referenziert und als solche gekennzeichnet.

View file

@ -0,0 +1,43 @@
<!-- docId: IMS-07-04 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:7.5; 27001:7.5 -->
# Dokumentenregister
Zentrales Verzeichnis aller gelenkten IMS-Dokumente. Massgeblich für Status, Owner und nächstes Review ist der Header im jeweiligen Dokument; das [Management-Cockpit](../cockpit/) wertet diese automatisch aus. Diese Tabelle dient der manuellen Gesamtübersicht.
| docId | Dokument | Pfad | Owner | Status |
|---|---|---|---|---|
| IMS-00 | IMS-Handbuch | `00_IMS-Handbuch.md` | Patrick Motsch | entwurf |
| IMS-04-01 | Kontext & interessierte Parteien | `01_kontext/kontext-und-interessierte-parteien.md` | Patrick Motsch | entwurf |
| IMS-04-02 | Geltungsbereich / Scope | `01_kontext/geltungsbereich-scope.md` | Patrick Motsch | entwurf |
| IMS-05-01 | Qualitätspolitik | `02_fuehrung/qm-politik.md` | Patrick Motsch | entwurf |
| IMS-05-02 | Informationssicherheitspolitik | `02_fuehrung/informationssicherheitspolitik.md` | Patrick Motsch | entwurf |
| IMS-05-03 | Rollen & Verantwortlichkeiten | `02_fuehrung/rollen-verantwortlichkeiten.md` | Patrick Motsch | entwurf |
| IMS-06-01 | Risikomanagement-Methodik | `03_planung/risikomanagement-methodik.md` | Patrick Motsch | entwurf |
| IMS-06-02 | Risikoregister | `03_planung/risikoregister.md` | Patrick Motsch | entwurf |
| IMS-06-03 | Statement of Applicability (SoA) | `03_planung/statement-of-applicability-soa.md` | Patrick Motsch | entwurf |
| IMS-06-04 | Ziele & Kennzahlen | `03_planung/ziele-und-kennzahlen.md` | Patrick Motsch | entwurf |
| IMS-07-01 | Ressourcen, Kompetenz & Schulung | `04_unterstuetzung/ressourcen-kompetenz-schulung.md` | Patrick Motsch | entwurf |
| IMS-07-02 | Kommunikation | `04_unterstuetzung/kommunikation.md` | Patrick Motsch | entwurf |
| IMS-07-03 | Lenkung dokumentierter Information | `04_unterstuetzung/dokumentenlenkung.md` | Patrick Motsch | entwurf |
| IMS-07-04 | Dokumentenregister | `04_unterstuetzung/dokumentenregister.md` | Patrick Motsch | entwurf |
| IMS-09-01 | Internes Audit | `06_bewertung/internes-audit.md` | Patrick Motsch | entwurf |
| IMS-09-02 | Management-Review | `06_bewertung/management-review.md` | Patrick Motsch | entwurf |
| IMS-09-03 | Monitoring & Messung | `06_bewertung/monitoring-messung.md` | Patrick Motsch | entwurf |
| IMS-10-01 | Korrekturmassnahmen & KVP | `07_verbesserung/korrekturmassnahmen-und-kvp.md` | Patrick Motsch | entwurf |
| IMS-10-02 | Massnahmenregister | `07_verbesserung/massnahmen-register.md` | Patrick Motsch | entwurf |
## Betriebsdokumente (Kap. 8 / Annex A) -- `05_betrieb/`
Die operativen Prozess- und Sicherheitsdokumente (Zugriffsmanagement, Verschlüsselung, Backup, BCM/DR, Incident, Change, Patch, Schwachstellen, Logging, Netzwerk, Datenaufbewahrung, Exit, SDLC, Kapazität, Subunternehmer, Mitarbeitersicherheit) liegen in `05_betrieb/`. Ihre Zuordnung zu ISO-27001-Annex-A-Controls und ISO-9001-Klauseln steht im [SoA](../03_planung/statement-of-applicability-soa.md) bzw. in den [Mappings](../mappings/).
## Hinweis zur Pflege
Header-Felder (`owner`, `status`, `nextReview`) werden direkt im Dokument gepflegt. Bei neuen Dokumenten hier eine Zeile ergänzen. Die verbindliche Review-Fälligkeit zeigt das Cockpit.

View file

@ -0,0 +1,38 @@
<!-- docId: IMS-07-02 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:7.4; 27001:7.4 -->
# Kommunikation (intern und extern)
**Dokumenttyp:** Verfahren (ISO 9001/27001 Kap. 7.4)
Regelt, **was, wann, mit wem und wie** im Kontext des IMS kommuniziert wird.
## 1. Interne Kommunikation
| Was | Wann | Wer -> Wem | Kanal |
|---|---|---|---|
| Politiken, Ziele, IMS-Änderungen | Bei Änderung / jährlich | Leitung -> Team | Wiki, Teammeeting |
| Risiken, offene Massnahmen | laufend | ISB/QMB -> Team | Massnahmenregister, Cockpit |
| Incidents | sofort | Melder -> Incident-Verantwortlicher | definierter Meldeweg |
| Release Notes / Changes | je Release | Release-Verantwortlicher -> Team | CHANGELOG, Wiki |
| Management-Review-Ergebnisse | nach Review | Leitung -> Team | Protokoll |
## 2. Externe Kommunikation
| Was | Anlass | Wer -> Wem | Kanal |
|---|---|---|---|
| Datenschutzvorfall / Meldepflicht | gesetzliche Frist | Datenschutzverantw. -> EDOEB/Betroffene/FINMA | gemäss [Incident Response](../05_betrieb/07_Incident_Response_und_Meldewesen.md) |
| Sicherheits-/Compliance-Nachweise | auf Anfrage | Leitung -> Kunde/Prüfer | [security-overview.md](../05_betrieb/security-overview.md), SoA-Auszug |
| Wartung / Maintenance Window | mind. 5 Werktage vorab | Betrieb -> Kunden | E-Mail/Statusseite |
| Lieferantenanforderungen | bei Beauftragung | Lieferanten-Verantw. -> Lieferant | Vertrag/AVV |
## 3. Grundsatz
Externe sicherheits-/datenschutzrelevante Kommunikation wird ausschliesslich über die benannten Rollen geführt und im freigegebenen Stand verteilt.

View file

@ -0,0 +1,44 @@
<!-- docId: IMS-07-01 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:7.1-7.3; 27001:7.1-7.3,A.6.3 -->
# Ressourcen, Kompetenz, Awareness & Schulung
**Dokumenttyp:** Verfahren (ISO 9001/27001 Kap. 7.1-7.3, Annex A.6.3)
## 1. Ressourcen (7.1)
Die Geschäftsführung stellt die für Betrieb und Verbesserung des IMS erforderlichen Ressourcen bereit: Personal, Cloud-Infrastruktur (Infomaniak), Entwicklungs-/CI-Systeme (Forgejo), Tooling sowie Budget für externe Unterstützung (z. B. internes Audit, Penetrationstests).
## 2. Kompetenz (7.2)
| Kompetenzbereich | Anforderung | Nachweis |
|---|---|---|
| Sichere Softwareentwicklung | Kenntnis SDLC, Secure Coding, Review | Code-Reviews, Schulungsnachweis |
| Betrieb/DevOps | Deployment, Backup/Restore, Incident-Handling | Runbooks, durchgeführte Tests |
| Datenschutz/Compliance | DSG/DSGVO, AVV, ISO-Grundlagen | Schulungsnachweis |
| Informationssicherheit | Risiko, Annex-A-Controls | Schulungsnachweis |
Kompetenzluecken werden im Management-Review identifiziert und über Schulung/externe Unterstützung geschlossen. Kompetenznachweise (Zertifikate, Kursteilnahmen) werden als Records abgelegt.
## 3. Awareness (7.3 / A.6.3)
- Alle Mitarbeitenden werden im Onboarding auf IS-Politik, QM-Politik und Meldewege verpflichtet.
- Jährliche Auffrischung zu Informationssicherheit und Datenschutz (Ziel S-5: 100 %).
- Anlassbezogene Sensibilisierung nach relevanten Incidents.
## 4. Schulungsnachweis (Record-Vorlage)
| Datum | Person | Thema | Form | Nachweis |
|---|---|---|---|---|
| | | | | |
## 5. Pflege
Schulungsplanung und -nachweise werden jährlich aktualisiert; offene Schulungen laufen ins [Massnahmenregister](../07_verbesserung/massnahmen-register.md).

View file

@ -396,7 +396,7 @@ fix/payment-status-mapping
10. Release in Produktion,
11. Dokumentation in Release Notes / CHANGELOG,
12. Information an Melder,
13. Ticket schließen.
13. Ticket schliessen.
---
@ -566,11 +566,11 @@ Name des Release-Verantwortlichen
# 12. Freigabe und Review des Prozesses
Dieser Prozess sollte regelmäßig überprüft werden, mindestens jedoch:
Dieser Prozess sollte regelmässig überprüft werden, mindestens jedoch:
- bei wesentlichen Änderungen am Entwicklungsprozess,
- bei Einführung neuer Tools,
- nach größeren Incidents,
- nach grösseren Incidents,
- vor externen Audits,
- mindestens einmal jährlich.

View file

@ -18,7 +18,7 @@ Drei Quellen, von breit nach spezifisch:
|--------|-------------|-----------|
| **Feature-Instanz** | `DataNeutraliserConfig.enabled` (hat `featureInstanceId` + `mandateId`) | Alle Daten in dieser Feature-Instanz werden neutralisiert. Betrifft jeden Content-Einstieg innerhalb dieser Instanz. |
| **Chat-Workflow / Session** | `ServiceCenterContext.requireNeutralization` (gesetzt z. B. vom AI-Workspace oder Automation) | Dieser Workflow/Turn: jeder Content, der hier verarbeitet wird, wird neutralisiert. |
| **Dokument oder Quelle** | `FileItem.neutralize`, `FileFolder.neutralize`, `DataSource.neutralize`, `FeatureDataSource.neutralize`, `FeatureDataSource.neutralizeFields` | Dieses konkrete Objekt: Content daraus wird neutralisiert, egal ob die Feature-Instanz oder der Workflow es sonst fordern würden. `FileFolder.neutralize` propagiert auf alle enthaltenen Dateien. `neutralizeFields` ermoeglicht Feld-Level-Maskierung bei DB-Queries. |
| **Dokument oder Quelle** | `FileItem.neutralize`, `FileFolder.neutralize`, `DataSource.neutralize`, `FeatureDataSource.neutralize`, `FeatureDataSource.neutralizeFields` | Dieses konkrete Objekt: Content daraus wird neutralisiert, egal ob die Feature-Instanz oder der Workflow es sonst fordern würden. `FileFolder.neutralize` propagiert auf alle enthaltenen Dateien. `neutralizeFields` ermöglicht Feld-Level-Maskierung bei DB-Queries. |
**Auswertung:** Irgendeine Quelle sagt `True` → neutralisieren. Keine Quelle kann eine andere aufheben. Es gibt kein `False`-Override, das ein `True` von woanders aushebelt.
@ -59,7 +59,7 @@ Eine Engine, drei Einstiege, aufgerufen an den Content-Einstiegspunkten aus Absc
| `processBinaryBytes` / `Async` | Bytes + Dateiname + MIME | **Ist** |
| **`processImage(imageBytes, fileName)`** / `processImageAsync` | Bild-Datei oder Bild-ContentPart (image/png, image/jpeg, …) | **Ist** (seit ~2026 Q1) |
**Ist-Zustand Bilder (aktualisiert 2026-04-05):** `processImageAsync` ist implementiert und nutzt `NEUTRALIZATION_IMAGE` (Private LLM Vision). `_processBinaryFile` verarbeitet jetzt Bild-Parts ueber `processImageAsync`. **Einschraenkung:** Eigenstaendige Bild-Dateien (`image/*` MIME direkt an `processFile`) werden in `_isBinaryMimeType` weiterhin als Skip behandelt.
**Ist-Zustand Bilder (aktualisiert 2026-04-05):** `processImageAsync` ist implementiert und nutzt `NEUTRALIZATION_IMAGE` (Private LLM Vision). `_processBinaryFile` verarbeitet jetzt Bild-Parts über `processImageAsync`. **Einschränkung:** Eigenständige Bild-Dateien (`image/*` MIME direkt an `processFile`) werden in `_isBinaryMimeType` weiterhin als Skip behandelt.
**Ist (aktualisiert):** `processImageAsync` existiert als Einstieg. Ruft internes Vision-Modell (`NEUTRALIZATION_IMAGE` → Private-LLM) auf, um sensible Inhalte in Bildern zu erkennen/entfernen. Kein externer Provider. Modell nicht verfügbar → Bild blockieren (nicht unbehandelt weiterreichen).

View file

@ -35,7 +35,7 @@ Nutzer können über eine Self-Service-Funktion sämtliche über sie gespeichert
- Mandatszugehörigkeiten und zugewiesene Rollen
- Zugriffsrechte auf Funktionsmodule
- Erstellte und eingelöste Einladungen
- Zeitpunkte der Kontoerstellung und letzten Anmeldung
- Zeitpunkte der Kontörstellung und letzten Anmeldung
Der Export umfasst alle auf Plattformebene gespeicherten Daten. Feature-spezifische Daten (z.B. Chat-Verläufe, Treuhandpositionen) können über die jeweiligen Funktionsmodule eingesehen werden.

View file

@ -0,0 +1,52 @@
<!-- docId: IMS-09-01 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:9.2; 27001:9.2 -->
# Internes Audit
**Dokumenttyp:** Verfahren (Pflicht ISO 9001/27001 Kap. 9.2)
## 1. Zweck
Das interne Audit prüft regelmässig, ob das IMS den Normanforderungen (ISO 9001, ISO 27001) und den eigenen Vorgaben entspricht und wirksam umgesetzt ist.
## 2. Unabhängigkeit
Auditoren dürfen ihre eigene Arbeit nicht prüfen. Aufgrund der Teamgrösse wird das interne Audit **an eine externe, unabhängige Person/Stelle vergeben**. Die Auswahl wird dokumentiert.
## 3. Auditprogramm
| Element | Vorgabe |
|---|---|
| Turnus | Mindestens 1x jährlich, gesamtes IMS über max. 1 Zyklus |
| Umfang | Kap. 4-10 beider Normen + Annex-A-Controls (risikoorientiert priorisiert) |
| Erstes Audit | 2026 Q3 (Voraussetzung für Audit-Reife) |
| Kriterien | Normtext, IMS-Dokumente, SoA, gesetzliche/vertragliche Anforderungen |
## 4. Ablauf
```mermaid
flowchart LR
plan["Auditplan (Umfang, Termin, Kriterien)"] --> exec["Durchführung (Interviews, Nachweise, Stichproben)"]
exec --> report["Auditbericht (Feststellungen, Abweichungen)"]
report --> capa["Korrekturmassnahmen ins Massnahmenregister"]
capa --> followup["Nachverfolgung & Wirksamkeitsprüfung"]
```
## 5. Feststellungsklassen
| Klasse | Bedeutung | Folge |
|---|---|---|
| Hauptabweichung (major) | Norm-/Systemanforderung nicht erfüllt | sofortige Korrekturmassnahme |
| Nebenabweichung (minor) | punktuelle Schwäche | terminierte Korrekturmassnahme |
| Hinweis / Verbesserungspotenzial | Empfehlung | KVP-Prüfung |
## 6. Nachweise / Records
Auditplan, Auditbericht und Massnahmen werden als Records abgelegt; Abweichungen werden im [Massnahmenregister](../07_verbesserung/massnahmen-register.md) (Quelle: Audit) geführt. Ergebnisse sind Input für das [Management-Review](management-review.md).

View file

@ -0,0 +1,67 @@
<!-- docId: IMS-09-02 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Geschäftsführung PowerOn AG -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:9.3; 27001:9.3 -->
# Management-Review
**Dokumenttyp:** Verfahren + Protokollvorlage (Pflicht ISO 9001/27001 Kap. 9.3)
## 1. Zweck und Turnus
Die oberste Leitung bewertet das IMS mindestens **jährlich** sowie anlassbezogen auf Eignung, Angemessenheit und Wirksamkeit und entscheidet über Verbesserungen und Ressourcen.
## 2. Eingaben (Inputs)
- Status Massnahmen aus vorherigen Reviews
- Änderungen interner/externer Themen ([Kontext](../01_kontext/kontext-und-interessierte-parteien.md))
- Erfüllung der [Ziele & Kennzahlen](../03_planung/ziele-und-kennzahlen.md)
- Ergebnisse [interner Audits](internes-audit.md)
- Risikolage / [Risikoregister](../03_planung/risikoregister.md) + SoA-Status
- Incidents, Abweichungen, Reklamationen
- Rückmeldungen interessierter Parteien (Kunden, Lieferanten)
- Stand offener Pendenzen ([Massnahmenregister](../07_verbesserung/massnahmen-register.md))
## 3. Ergebnisse (Outputs)
- Bewertung der IMS-Wirksamkeit
- Entscheidungen zu Verbesserungen, Zielen, Ressourcen
- neue/aktualisierte Massnahmen mit Owner und Termin
- ggf. Anpassung von Politiken, Scope, SoA
## 4. Protokollvorlage
```markdown
# Management-Review-Protokoll
Datum:
Teilnehmende:
Berichtsperiode:
## Inputs (Zusammenfassung)
- Zielerreichung: ...
- Audit-Ergebnisse: ...
- Risiken/SoA: ...
- Incidents/Abweichungen: ...
- Rückmeldungen: ...
## Bewertung
- Eignung/Angemessenheit/Wirksamkeit: ...
## Entscheidungen & Massnahmen
| Massnahme | Owner | Termin |
|---|---|---|
| | | |
## Nächstes Review:
Freigabe (Geschäftsführung):
```
## 5. Records
Jedes Protokoll wird als Record abgelegt. Das erste Management-Review (2026 Q3) ist Voraussetzung für die Audit-Reife.

View file

@ -0,0 +1,32 @@
<!-- docId: IMS-09-03 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:9.1; 27001:9.1 -->
# Monitoring, Messung, Analyse und Bewertung
**Dokumenttyp:** Verfahren (Pflicht ISO 9001/27001 Kap. 9.1)
## 1. Was wird gemessen
| Gegenstand | Kennzahl | Quelle | Frequenz | Owner |
|---|---|---|---|---|
| Qualitätsziele Q-1..Q-4 | siehe [Ziele](../03_planung/ziele-und-kennzahlen.md) | Tickets, Releases, CHANGELOG | quartalsweise | Patrick Motsch |
| Sicherheitsziele S-1..S-6 | siehe [Ziele](../03_planung/ziele-und-kennzahlen.md) | Risikoregister, Patch-/Incident-Logs | quartalsweise | Patrick Motsch |
| Verfügbarkeit Plattform | Uptime % | Monitoring/Statusseite | laufend | Patrick Motsch |
| Vorfälle | Anzahl, Schweregrad, Reaktionszeit | [Incident Response](../05_betrieb/07_Incident_Response_und_Meldewesen.md) | je Vorfall | Patrick Motsch |
| Dokumentenpflege | überfällige Reviews | [Cockpit](../cockpit/) | laufend | Patrick Motsch |
| Schwachstellen | offen/behoben, SLA-Treue | [Schwachstellen](../05_betrieb/10_Schwachstellenmanagement.md) | laufend | Patrick Motsch |
## 2. Analyse und Bewertung
Die Kennzahlen werden quartalsweise zusammengefasst und im [Management-Review](management-review.md) bewertet. Zielverfehlungen lösen Einträge im [Massnahmenregister](../07_verbesserung/massnahmen-register.md) aus.
## 3. Werkzeuge
Das [Management-Cockpit](../cockpit/) liefert die laufende Sicht auf Dokumentenstatus, fällige Reviews und offene Pendenzen. Betriebskennzahlen stammen aus Monitoring, Forgejo und den Betriebs-Records.

View file

@ -0,0 +1,47 @@
<!-- docId: IMS-10-01 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:10; 27001:10 -->
# Korrekturmassnahmen & kontinuierliche Verbesserung (KVP)
**Dokumenttyp:** Verfahren (Pflicht ISO 9001/27001 Kap. 10)
## 1. Zweck
Abweichungen (Nichtkonformitäten), Vorfälle, Reklamationen und Verbesserungsideen werden systematisch erfasst, behandelt und auf Wirksamkeit geprüft. Ziel ist die kontinuierliche Verbesserung des IMS.
## 2. Ablauf der Korrekturmassnahme
```mermaid
flowchart LR
erfassen["1 Abweichung erfassen (Massnahmenregister)"] --> sofort["2 Sofortmassnahme / Eindämmung"]
sofort --> ursache["3 Ursachenanalyse (Root Cause)"]
ursache --> massnahme["4 Korrekturmassnahme definieren (Owner, Termin)"]
massnahme --> umsetzen["5 Umsetzen"]
umsetzen --> wirksam["6 Wirksamkeit prüfen"]
wirksam --> schliessen["7 Schliessen + dokumentieren"]
```
## 3. Quellen von Abweichungen/Pendenzen
- Interne Audits ([internes-audit.md](../06_bewertung/internes-audit.md))
- Sicherheitsvorfälle ([Incident Response](../05_betrieb/07_Incident_Response_und_Meldewesen.md))
- Risikobehandlung ([Risikoregister](../03_planung/risikoregister.md))
- Zielverfehlungen ([Monitoring](../06_bewertung/monitoring-messung.md))
- Kundenreklamationen, Lieferantenprobleme
- Überfällige Dokumenten-Reviews
- Verbesserungsvorschläge
## 4. Führung im Massnahmenregister
Alle Korrektur- und Verbesserungsmassnahmen werden zentral im [Massnahmenregister](massnahmen-register.md) geführt (Single Source of Truth). Das [Cockpit](../cockpit/) aggregiert daraus zusammen mit überfälligen Reviews und `[ZU PRÜFEN]`-Markern eine Gesamtsicht der Pendenzen.
## 5. Kontinuierliche Verbesserung
Trends (wiederkehrende Abweichungen, Incident-Muster) werden im [Management-Review](../06_bewertung/management-review.md) bewertet und führen zu präventiven Verbesserungen an Prozessen, Controls oder Dokumenten.

View file

@ -0,0 +1,38 @@
<!-- docId: IMS-10-02 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2026-09-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:10.2; 27001:10.1 -->
# Massnahmenregister (Pendenzen)
**Dokumenttyp:** Record (zentrale Pendenzenliste -- Single Source of Truth)
Zentrale Liste aller Korrektur- und Verbesserungsmassnahmen. Das [Management-Cockpit](../cockpit/) liest diese Tabelle und führt sie auf der Pendenzen-Seite mit überfälligen Reviews und `[ZU PRÜFEN]`-Markern zusammen.
**Spalten-Schema (bitte exakt einhalten):** `ID | Titel | Owner | Quelle | Erstellt | Faellig | Status`
**Status-Werte:** `offen`, `in Arbeit`, `erledigt`. **Quelle-Werte:** `Audit`, `Review`, `Risiko`, `Incident`, `Doku`, `Sonstiges`.
| ID | Titel | Owner | Quelle | Erstellt | Fällig | Status |
|---|---|---|---|---|---|---|
| M-01 | MFA auf Admin-/Server-Zugängen bestätigen/erzwingen | Patrick Motsch | Risiko | 2026-06-03 | 2026-07-15 | offen |
| M-02 | Restore-Test durchführen und protokollieren | Patrick Motsch | Risiko | 2026-06-03 | 2026-06-30 | offen |
| M-03 | AVV/Zero-Retention mit OpenAI und weiteren LLM-Providern ablegen | Patrick Motsch | Risiko | 2026-06-03 | 2026-07-31 | offen |
| M-04 | Log-Aufbewahrungsdauer und Manipulationsschutz festlegen | Patrick Motsch | Risiko | 2026-06-03 | 2026-07-31 | offen |
| M-05 | Verschlüsselung at-rest der Infomaniak-DB bestätigen | Patrick Motsch | Risiko | 2026-06-03 | 2026-06-30 | offen |
| M-06 | Entscheidung zu Produktivdaten in Testumgebung treffen | Patrick Motsch | Doku | 2026-06-03 | 2026-07-15 | offen |
| M-07 | Hintergrundprüfungen bei Einstellung klären | Patrick Motsch | Risiko | 2026-06-03 | 2026-08-15 | offen |
| M-08 | Externen internen Auditor benennen und beauftragen | Patrick Motsch | Audit | 2026-06-03 | 2026-07-15 | offen |
| M-09 | Erstes internes Audit durchführen | Patrick Motsch | Audit | 2026-06-03 | 2026-09-30 | offen |
| M-10 | Erstes Management-Review durchführen | Patrick Motsch | Review | 2026-06-03 | 2026-09-30 | offen |
| M-11 | Risikoworkshop zur Validierung des Risikoregisters | Patrick Motsch | Risiko | 2026-06-03 | 2026-06-30 | offen |
| M-12 | Asset-Inventar erstellen (A.5.9) | Patrick Motsch | Doku | 2026-06-03 | 2026-08-31 | offen |
| M-13 | Politiken formal freigeben (Status entwurf -> freigegeben) | Patrick Motsch | Doku | 2026-06-03 | 2026-07-31 | offen |
## Pflegehinweis
Neue Pendenzen mit fortlaufender ID ergänzen. Bei Abschluss `Status = erledigt` setzen (Zeile bleibt für Nachweis erhalten). Überfällige Einträge (Fällig < heute, Status != erledigt) hebt das Cockpit rot hervor.

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,37 @@
# IMS Management Cockpit
Offline nutzbares HTML-Cockpit zur Navigation und Einsicht aller IMS-Dokumente.
## Nutzen
`IMS-Cockpit.html` per Doppelklick im Browser öffnen. Es enthält alle IMS-Dokumente
gerendert (Markdown -> HTML), einen Navigationsbaum nach ISO-Kapitel, Volltextsuche,
ein Dashboard (Dokumentenzahl, Status, überfällige Reviews) und eine Pendenzen-Seite
(Massnahmenregister + überfällige Reviews + `[ZU PRÜFEN]`-Marker). Mermaid-Diagramme
sind eingebettet und werden offline gerendert. Keine Internetverbindung nötig.
## Neu generieren (nach Doku-Änderungen)
```bash
python build_cockpit.py
```
Das aktualisiert `IMS-Cockpit.html`. Beim ersten Lauf wird `mermaid.min.js` einmalig
vom CDN geladen und unter `_vendor/` zwischengespeichert; danach läuft der Build offline.
## Hintergrund (technisch)
Browser blockieren `fetch()` lokaler Dateien unter `file://`. Deshalb wird der gerenderte
Inhalt zur Build-Zeit in die HTML eingebettet (eine portable Datei, Mermaid inline) -- so
genügt ein Doppelklick. Der Generator hat keine externen Python-Abhängigkeiten.
## Automatisierung (optional)
`python build_cockpit.py` kann als Forgejo-CI-Schritt oder Pre-Commit-Hook laufen, damit
das Cockpit bei jeder Doku-Änderung automatisch aktuell bleibt.
## Dateien
- `build_cockpit.py` -- Generator
- `IMS-Cockpit.html` -- generierte Cockpit-Datei (Doppelklick)
- `_vendor/mermaid.min.js` -- lokal zwischengespeicherte Mermaid-Bibliothek

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,602 @@
#!/usr/bin/env python3
"""IMS Management Cockpit Generator.
Liest die IMS-Markdown-Dokumente (Ordner ../), parst die Dokumentenlenkungs-Header,
konvertiert Markdown -> HTML und erzeugt EINE in sich geschlossene Datei
``IMS-Cockpit.html`` (Mermaid inline), die per Doppelklick (file://) offline nutzbar ist.
Aufruf: python build_cockpit.py
Ergebnis: IMS-Cockpit.html im selben Ordner.
Keine externen Python-Pakete nötig. Mermaid wird einmalig von einem CDN geladen und
in ../cockpit/_vendor/ zwischengespeichert, danach in die HTML eingebettet (offline).
"""
import os
import re
import json
import html
import datetime
import urllib.request
HERE = os.path.dirname(os.path.abspath(__file__))
IMS_DIR = os.path.dirname(HERE) # .../ims
OUT_FILE = os.path.join(HERE, "IMS-Cockpit.html")
VENDOR_DIR = os.path.join(HERE, "_vendor")
MERMAID_URL = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"
CHAPTER_LABELS = {
"00": "Handbuch",
"01_kontext": "4 - Kontext",
"02_fuehrung": "5 - Führung",
"03_planung": "6 - Planung",
"04_unterstuetzung": "7 - Unterstützung",
"05_betrieb": "8 - Betrieb / Annex A",
"06_bewertung": "9 - Bewertung",
"07_verbesserung": "10 - Verbesserung",
"mappings": "Mappings",
}
CHAPTER_ORDER = list(CHAPTER_LABELS.keys())
TODAY = datetime.date.today()
# --------------------------------------------------------------------------- #
# Markdown -> HTML (dependency-free) #
# --------------------------------------------------------------------------- #
def _inline(text):
codes = []
def _grab(m):
codes.append(m.group(1))
return "\x00C%d\x00" % (len(codes) - 1)
text = re.sub(r"`([^`]+)`", _grab, text)
text = html.escape(text, quote=False)
text = re.sub(
r"\[([^\]]+)\]\(([^)]+)\)",
lambda m: '<a href="%s">%s</a>' % (html.escape(m.group(2), quote=True), m.group(1)),
text,
)
text = re.sub(r"\*\*([^*]+)\*\*", r"<strong>\1</strong>", text)
text = re.sub(r"(?<!\*)\*(?!\*)([^*]+?)\*(?!\*)", r"<em>\1</em>", text)
def _restore(m):
return "<code>" + html.escape(codes[int(m.group(1))], quote=False) + "</code>"
return re.sub(r"\x00C(\d+)\x00", _restore, text)
def _cells(row):
row = row.strip()
if row.startswith("|"):
row = row[1:]
if row.endswith("|"):
row = row[:-1]
return [c.strip() for c in row.split("|")]
def _table(header, rows):
head = "".join("<th>%s</th>" % _inline(c) for c in _cells(header))
body = ""
for r in rows:
body += "<tr>" + "".join("<td>%s</td>" % _inline(c) for c in _cells(r)) + "</tr>"
return "<table><thead><tr>%s</tr></thead><tbody>%s</tbody></table>" % (head, body)
def md_to_html(md):
lines = md.split("\n")
out = []
i, n = 0, len(lines)
while i < n:
line = lines[i]
if re.match(r"^\s*<!--.*-->\s*$", line):
i += 1
continue
m = re.match(r"^```(\w*)\s*$", line.strip())
if m:
lang = m.group(1)
i += 1
buf = []
while i < n and not lines[i].strip().startswith("```"):
buf.append(lines[i])
i += 1
i += 1
code = "\n".join(buf)
if lang == "mermaid":
out.append('<pre class="mermaid">%s</pre>' % html.escape(code, quote=False))
else:
out.append('<pre class="code"><code>%s</code></pre>' % html.escape(code, quote=False))
continue
if line.strip() == "":
i += 1
continue
if re.match(r"^\s*(---|\*\*\*|___)\s*$", line):
out.append("<hr>")
i += 1
continue
hm = re.match(r"^(#{1,6})\s+(.*)$", line)
if hm:
lvl = len(hm.group(1))
out.append("<h%d>%s</h%d>" % (lvl, _inline(hm.group(2).strip()), lvl))
i += 1
continue
if "|" in line and i + 1 < n and "-" in lines[i + 1] and re.match(r"^\s*\|?[\s:|-]+\|?\s*$", lines[i + 1]):
header = line
i += 2
rows = []
while i < n and "|" in lines[i] and lines[i].strip() != "":
rows.append(lines[i])
i += 1
out.append(_table(header, rows))
continue
if re.match(r"^\s*>\s?", line):
buf = []
while i < n and re.match(r"^\s*>\s?", lines[i]):
buf.append(re.sub(r"^\s*>\s?", "", lines[i]))
i += 1
out.append("<blockquote>%s</blockquote>" % _inline(" ".join(buf)))
continue
if re.match(r"^\s*([-*+])\s+", line) or re.match(r"^\s*\d+\.\s+", line):
ordered = bool(re.match(r"^\s*\d+\.\s+", line))
tag = "ol" if ordered else "ul"
items = []
while i < n and (re.match(r"^\s*([-*+])\s+", lines[i]) or re.match(r"^\s*\d+\.\s+", lines[i])):
item = re.sub(r"^\s*([-*+]|\d+\.)\s+", "", lines[i])
items.append("<li>%s</li>" % _inline(item))
i += 1
out.append("<%s>%s</%s>" % (tag, "".join(items), tag))
continue
buf = [line]
i += 1
while i < n and lines[i].strip() != "" and not re.match(
r"^(#{1,6})\s|^\s*```|^\s*([-*+])\s+|^\s*\d+\.\s+|^\s*>\s?", lines[i]
) and "|" not in lines[i]:
buf.append(lines[i])
i += 1
out.append("<p>%s</p>" % _inline(" ".join(b.strip() for b in buf)))
return "\n".join(out)
# --------------------------------------------------------------------------- #
# Parsing helpers #
# --------------------------------------------------------------------------- #
def parse_header(text):
"""Parse only the contiguous comment block at the very top of the file."""
meta = {}
for line in text.split("\n"):
s = line.strip()
if s == "":
continue
m = re.match(r"^<!--\s*([\w]+)\s*:\s*(.*?)\s*-->$", s)
if m:
meta[m.group(1)] = m.group(2).strip()
continue
break # first non-comment, non-blank line ends the header block
return meta
def doc_title(text, fallback):
m = re.search(r"^#\s+(.*)$", text, re.M)
return m.group(1).strip() if m else fallback
def parse_date(value):
if not value:
return None
try:
return datetime.datetime.strptime(value.strip(), "%Y-%m-%d").date()
except ValueError:
return None
def find_zu_pruefen(text):
hits = []
current = ""
for line in text.split("\n"):
hm = re.match(r"^#{1,6}\s+(.*)$", line)
if hm:
current = hm.group(1).strip()
scan = re.sub(r"`[^`]*`", "", line) # Inline-Code (Marker-Erklaerungen) ignorieren
if re.search(r"ZU\s*PR(?:UE|\u00dc)FEN", scan, re.I):
hits.append(current or "(Dokumentanfang)")
return hits
def parse_massnahmen(text):
"""Parse the markdown action register table -> list of dict."""
rows = []
lines = text.split("\n")
header_idx = None
for idx, line in enumerate(lines):
if "|" in line and re.search(r"\bID\b", line) and re.search(r"Titel", line, re.I):
nxt = lines[idx + 1] if idx + 1 < len(lines) else ""
if "-" in nxt and re.match(r"^\s*\|?[\s:|-]+\|?\s*$", nxt):
header_idx = idx
break
if header_idx is None:
return rows
cols = [c.strip().lower() for c in _cells(lines[header_idx])]
for line in lines[header_idx + 2:]:
if "|" not in line or line.strip() == "":
break
vals = _cells(line)
if len(vals) < len(cols):
continue
row = dict(zip(cols, vals))
rows.append(
{
"id": row.get("id", ""),
"titel": row.get("titel", ""),
"owner": row.get("owner", ""),
"quelle": row.get("quelle", ""),
"faellig": row.get("faellig", "") or row.get("f\u00e4llig", ""),
"status": row.get("status", ""),
}
)
return rows
# --------------------------------------------------------------------------- #
# Collect documents #
# --------------------------------------------------------------------------- #
def collect_docs():
docs = []
for root, dirs, files in os.walk(IMS_DIR):
dirs[:] = [d for d in dirs if d not in ("cockpit", "_vendor")]
for fn in files:
if not fn.endswith(".md"):
continue
full = os.path.join(root, fn)
rel = os.path.relpath(full, IMS_DIR).replace("\\", "/")
with open(full, "r", encoding="utf-8") as fh:
text = fh.read()
parts = rel.split("/")
chapter = "00" if len(parts) == 1 else parts[0]
meta = parse_header(text)
next_review = parse_date(meta.get("nextReview"))
overdue = bool(next_review and next_review < TODAY and meta.get("status") not in ("abgeloest", "abgelöst"))
docs.append(
{
"id": rel,
"path": rel,
"chapter": chapter,
"title": doc_title(text, fn),
"filename": fn,
"meta": meta,
"html": md_to_html(text),
"text": re.sub(r"\s+", " ", text).lower(),
"nextReview": meta.get("nextReview", ""),
"overdueReview": overdue,
"zuPruefen": find_zu_pruefen(text),
}
)
docs.sort(key=lambda d: (CHAPTER_ORDER.index(d["chapter"]) if d["chapter"] in CHAPTER_ORDER else 99, d["filename"]))
return docs
def get_mermaid_js():
os.makedirs(VENDOR_DIR, exist_ok=True)
cache = os.path.join(VENDOR_DIR, "mermaid.min.js")
if os.path.exists(cache):
with open(cache, "r", encoding="utf-8") as fh:
return fh.read()
try:
print("Lade mermaid.min.js vom CDN ...")
req = urllib.request.Request(MERMAID_URL, headers={"User-Agent": "Mozilla/5.0"})
data = urllib.request.urlopen(req, timeout=30).read().decode("utf-8")
with open(cache, "w", encoding="utf-8") as fh:
fh.write(data)
return data
except Exception as exc: # noqa: BLE001
print("WARNUNG: mermaid.min.js konnte nicht geladen werden (%s). Diagramme werden als Code angezeigt." % exc)
return ""
# --------------------------------------------------------------------------- #
# HTML assembly #
# --------------------------------------------------------------------------- #
def build():
docs = collect_docs()
pendenzen_reg = []
for d in docs:
if d["filename"] == "massnahmen-register.md":
with open(os.path.join(IMS_DIR, d["path"]), "r", encoding="utf-8") as fh:
pendenzen_reg = parse_massnahmen(fh.read())
overdue_reviews = [
{"id": d["id"], "title": d["title"], "owner": d["meta"].get("owner", ""), "nextReview": d["nextReview"]}
for d in docs
if d["overdueReview"]
]
zu_pruefen = [
{"id": d["id"], "title": d["title"], "section": s}
for d in docs
for s in d["zuPruefen"]
]
status_counts = {}
for d in docs:
st = d["meta"].get("status", "unbekannt")
status_counts[st] = status_counts.get(st, 0) + 1
open_reg = [p for p in pendenzen_reg if p["status"].lower() != "erledigt"]
overdue_reg = [p for p in open_reg if (parse_date(p["faellig"]) and parse_date(p["faellig"]) < TODAY)]
stats = {
"docs": len(docs),
"statusCounts": status_counts,
"overdueReviews": len(overdue_reviews),
"openPendenzen": len(open_reg),
"overduePendenzen": len(overdue_reg),
"generated": TODAY.isoformat(),
}
chapters = [{"key": k, "label": CHAPTER_LABELS[k]} for k in CHAPTER_ORDER]
payload = {
"docs": docs,
"chapters": chapters,
"pendenzenReg": pendenzen_reg,
"overdueReviews": overdue_reviews,
"zuPruefen": zu_pruefen,
"stats": stats,
"today": TODAY.isoformat(),
}
data_json = json.dumps(payload, ensure_ascii=False).replace("</", "<\\/")
mermaid_js = get_mermaid_js()
html_out = HTML_TEMPLATE.replace("/*__DATA__*/", "window.IMS_DATA = " + data_json + ";")
html_out = html_out.replace("/*__MERMAID__*/", mermaid_js)
with open(OUT_FILE, "w", encoding="utf-8") as fh:
fh.write(html_out)
print("OK: %s (%d Dokumente, %d offene Pendenzen, %d überfällige Reviews)" % (
OUT_FILE, stats["docs"], stats["openPendenzen"], stats["overdueReviews"]))
HTML_TEMPLATE = r"""<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>PowerOn IMS - Management Cockpit</title>
<style>
:root{
--bg:#0f1729; --panel:#16213a; --panel2:#1d2a48; --line:#2a3a5e;
--text:#e7edf7; --muted:#93a3c0; --accent:#4f8cff; --accent2:#6ee7b7;
--green:#34d399; --amber:#fbbf24; --red:#f87171; --grey:#8aa0c0;
}
*{box-sizing:border-box}
body{margin:0;font-family:'Segoe UI',system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);font-size:15px;line-height:1.55}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
.app{display:flex;min-height:100vh}
/* sidebar */
.sidebar{width:320px;flex:0 0 320px;background:var(--panel);border-right:1px solid var(--line);height:100vh;position:sticky;top:0;overflow-y:auto;padding:0}
.brand{padding:18px 20px;border-bottom:1px solid var(--line)}
.brand h1{font-size:16px;margin:0 0 2px}
.brand .sub{color:var(--muted);font-size:12px}
.search{padding:12px 16px;border-bottom:1px solid var(--line)}
.search input{width:100%;padding:9px 12px;border-radius:8px;border:1px solid var(--line);background:var(--bg);color:var(--text);font-size:13px}
.nav{padding:8px 0 40px}
.nav .special{padding:9px 20px;cursor:pointer;display:flex;align-items:center;gap:8px;font-weight:600}
.nav .special:hover{background:var(--panel2)}
.chapter{margin-top:6px}
.chapter > .ctitle{padding:8px 20px 4px;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.06em}
.nav .item{padding:6px 20px 6px 26px;cursor:pointer;font-size:13.5px;display:flex;gap:8px;align-items:center}
.nav .item:hover{background:var(--panel2)}
.nav .item.active{background:var(--accent);color:#fff}
.dot{width:8px;height:8px;border-radius:50%;flex:0 0 8px}
.dot.freigegeben{background:var(--green)} .dot.entwurf{background:var(--amber)}
.dot.abgeloest{background:var(--grey)} .dot.unbekannt{background:var(--line)}
.badge-od{margin-left:auto;background:var(--red);color:#fff;border-radius:10px;padding:0 7px;font-size:10px}
/* main */
.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{padding:14px 28px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:16px;background:var(--panel)}
.topbar .crumbs{color:var(--muted);font-size:13px}
.topbar .gen{margin-left:auto;color:var(--muted);font-size:12px}
.content{padding:30px 38px;max-width:1000px}
.metabar{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 22px;padding:12px 16px;background:var(--panel);border:1px solid var(--line);border-radius:10px}
.chip{font-size:12px;padding:3px 10px;border-radius:20px;background:var(--panel2);color:var(--muted);border:1px solid var(--line)}
.chip b{color:var(--text);font-weight:600}
.chip.s-freigegeben{border-color:var(--green);color:var(--green)}
.chip.s-entwurf{border-color:var(--amber);color:var(--amber)}
.chip.s-abgeloest{border-color:var(--grey);color:var(--grey)}
.chip.od{border-color:var(--red);color:var(--red)}
/* doc typography */
.doc h1{font-size:26px;margin:.2em 0 .6em;border-bottom:1px solid var(--line);padding-bottom:.3em}
.doc h2{font-size:20px;margin:1.3em 0 .5em}
.doc h3{font-size:16px;margin:1.1em 0 .4em}
.doc p{margin:.6em 0}
.doc table{border-collapse:collapse;width:100%;margin:1em 0;font-size:13.5px}
.doc th,.doc td{border:1px solid var(--line);padding:7px 10px;text-align:left;vertical-align:top}
.doc th{background:var(--panel2)}
.doc tr:nth-child(even) td{background:rgba(255,255,255,.02)}
.doc code{background:var(--panel2);padding:1px 6px;border-radius:5px;font-size:.9em;font-family:'Cascadia Code',Consolas,monospace}
.doc pre.code{background:#0b1220;border:1px solid var(--line);border-radius:8px;padding:14px;overflow:auto}
.doc pre.code code{background:none;padding:0}
.doc blockquote{margin:1em 0;padding:.4em 1em;border-left:3px solid var(--accent);background:var(--panel);color:var(--muted)}
.doc hr{border:none;border-top:1px solid var(--line);margin:1.5em 0}
.doc .mermaid{background:#0b1220;border:1px solid var(--line);border-radius:8px;padding:16px;margin:1em 0;text-align:center}
/* dashboard */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;margin-bottom:26px}
.card{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:18px 20px}
.card .num{font-size:30px;font-weight:700}
.card .lbl{color:var(--muted);font-size:13px;margin-top:4px}
.card.alert .num{color:var(--red)}
.card.ok .num{color:var(--green)}
.section-h{font-size:17px;margin:26px 0 10px;font-weight:600}
.filters{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.filters select,.filters button{background:var(--panel2);color:var(--text);border:1px solid var(--line);border-radius:7px;padding:6px 10px;font-size:13px;cursor:pointer}
table.grid{border-collapse:collapse;width:100%;font-size:13.5px}
table.grid th,table.grid td{border:1px solid var(--line);padding:7px 10px;text-align:left}
table.grid th{background:var(--panel2);position:sticky;top:0}
tr.od td{background:rgba(248,113,113,.12)}
.tag{font-size:11px;padding:1px 8px;border-radius:10px;border:1px solid var(--line)}
.tag.q-Audit{color:#c4b5fd;border-color:#c4b5fd}
.tag.q-Risiko{color:var(--amber);border-color:var(--amber)}
.tag.q-Review{color:var(--accent2);border-color:var(--accent2)}
.tag.q-Incident{color:var(--red);border-color:var(--red)}
.tag.q-Doku{color:var(--accent);border-color:var(--accent)}
.pill{font-size:11px;padding:1px 8px;border-radius:10px}
.pill.offen{background:rgba(251,191,36,.18);color:var(--amber)}
.pill.erledigt{background:rgba(52,211,153,.18);color:var(--green)}
.pill.inArbeit{background:rgba(79,140,255,.18);color:var(--accent)}
.hidden{display:none}
@media(max-width:820px){.sidebar{display:none}.content{padding:20px}}
</style>
</head>
<body>
<div class="app">
<aside class="sidebar">
<div class="brand"><h1>PowerOn IMS</h1><div class="sub">Integriertes Managementsystem - ISO 9001 + 27001</div></div>
<div class="search"><input id="q" placeholder="Dokumente durchsuchen ..."></div>
<nav class="nav" id="nav"></nav>
</aside>
<main class="main">
<div class="topbar"><div class="crumbs" id="crumbs">Dashboard</div><div class="gen" id="gen"></div></div>
<div class="content" id="content"></div>
</main>
</div>
<script>/*__MERMAID__*/</script>
<script>/*__DATA__*/</script>
<script>
const D = window.IMS_DATA;
const byId = {}; D.docs.forEach(d => byId[d.id] = d);
const hasMermaid = (typeof window.mermaid !== 'undefined');
if (hasMermaid) { try { mermaid.initialize({startOnLoad:false, theme:'dark'}); } catch(e){} }
document.getElementById('gen').textContent = 'Generiert: ' + D.stats.generated;
function statusClass(s){ return ({'freigegeben':'freigegeben','entwurf':'entwurf','abgeloest':'abgeloest','abgelöst':'abgeloest'})[s] || 'unbekannt'; }
function buildNav(filter){
filter = (filter||'').toLowerCase();
const nav = document.getElementById('nav');
let h = '';
h += '<div class="special" onclick="showDashboard()">&#9632; Dashboard</div>';
h += '<div class="special" onclick="showPendenzen()">&#9888; Pendenzen';
if (D.stats.openPendenzen) h += ' <span class="badge-od">'+D.stats.openPendenzen+'</span>';
h += '</div>';
D.chapters.forEach(ch => {
const items = D.docs.filter(d => d.chapter === ch.key && (!filter || (d.title.toLowerCase().includes(filter) || d.text.includes(filter))));
if (!items.length) return;
h += '<div class="chapter"><div class="ctitle">'+ch.label+'</div>';
items.forEach(d => {
h += '<div class="item" data-id="'+encodeURIComponent(d.id)+'" onclick="showDoc(\''+encodeURIComponent(d.id)+'\')">'
+ '<span class="dot '+statusClass(d.meta.status)+'"></span>'
+ '<span>'+d.title+'</span>'
+ (d.overdueReview ? '<span class="badge-od">Review</span>' : '')
+ '</div>';
});
h += '</div>';
});
nav.innerHTML = h;
}
function setActive(id){
document.querySelectorAll('.nav .item').forEach(el=>el.classList.toggle('active', el.dataset.id===encodeURIComponent(id)));
}
function runMermaid(scope){
if(!hasMermaid) return;
const nodes = scope.querySelectorAll('.mermaid');
if(nodes.length){ try{ mermaid.run({nodes}); }catch(e){ console.warn(e); } }
}
function showDoc(encId){
const id = decodeURIComponent(encId);
const d = byId[id]; if(!d) return;
const m = d.meta || {};
const od = d.overdueReview;
let chips = '<span class="chip s-'+statusClass(m.status)+'">'+(m.status||'unbekannt')+'</span>';
if(m.version) chips += '<span class="chip">v<b>'+m.version+'</b></span>';
if(m.owner) chips += '<span class="chip">Owner: <b>'+m.owner+'</b></span>';
if(m.classification) chips += '<span class="chip">'+m.classification+'</span>';
if(d.nextReview) chips += '<span class="chip '+(od?'od':'')+'">Review: <b>'+d.nextReview+'</b>'+(od?' (überfällig)':'')+'</span>';
if(m.isoRefs) chips += '<span class="chip">ISO: <b>'+m.isoRefs+'</b></span>';
let warn = '';
if(d.zuPruefen && d.zuPruefen.length){
warn = '<div class="metabar" style="border-color:var(--amber)"><span class="chip od">&#9888; '+d.zuPruefen.length+' offene Punkte ([ZU PRÜFEN]) in diesem Dokument</span></div>';
}
document.getElementById('crumbs').textContent = d.path;
const c = document.getElementById('content');
c.innerHTML = '<div class="metabar">'+chips+'</div>'+warn+'<div class="doc">'+d.html+'</div>';
setActive(id); window.scrollTo(0,0); runMermaid(c);
}
function showDashboard(){
document.getElementById('crumbs').textContent = 'Dashboard';
setActive('__none__');
const s = D.stats;
let sc = '';
Object.keys(s.statusCounts).forEach(k=>{ sc += '<span class="chip s-'+statusClass(k)+'">'+k+': <b>'+s.statusCounts[k]+'</b></span> '; });
let h = '<div class="doc"><h1>IMS Management Cockpit</h1></div>';
h += '<div class="cards">';
h += '<div class="card"><div class="num">'+s.docs+'</div><div class="lbl">Dokumente</div></div>';
h += '<div class="card '+(s.openPendenzen?'':'ok')+'"><div class="num">'+s.openPendenzen+'</div><div class="lbl">Offene Pendenzen</div></div>';
h += '<div class="card '+(s.overduePendenzen?'alert':'ok')+'"><div class="num">'+s.overduePendenzen+'</div><div class="lbl">Überfällige Pendenzen</div></div>';
h += '<div class="card '+(s.overdueReviews?'alert':'ok')+'"><div class="num">'+s.overdueReviews+'</div><div class="lbl">Überfällige Reviews</div></div>';
h += '</div>';
h += '<div class="metabar">'+sc+'</div>';
h += '<div class="section-h">Nächste Schritte</div>';
h += '<p style="color:var(--muted)">Öffne die Seite <a href="#" onclick="showPendenzen();return false;">Pendenzen</a> für die zusammengeführte Aufgabenliste, oder wähle links ein Dokument.</p>';
document.getElementById('content').innerHTML = h;
window.scrollTo(0,0);
}
let pFilter = {quelle:'', overdue:false};
function showPendenzen(){
document.getElementById('crumbs').textContent = 'Pendenzen';
setActive('__none__');
const today = D.today;
// register
const reg = D.pendenzenReg.filter(p=>p.status.toLowerCase()!=='erledigt');
const quellen = Array.from(new Set(D.pendenzenReg.map(p=>p.quelle).filter(Boolean)));
let h = '<div class="doc"><h1>Pendenzen</h1><p>Zusammengeführt aus Massnahmenregister, überfälligen Dokumenten-Reviews und [ZU PRÜFEN]-Markern.</p></div>';
// filters
h += '<div class="filters"><select id="fq" onchange="applyP()"><option value="">Alle Quellen</option>';
quellen.forEach(q=>{ h += '<option value="'+q+'"'+(pFilter.quelle===q?' selected':'')+'>'+q+'</option>'; });
h += '</select><button onclick="toggleOd()">'+(pFilter.overdue?'Nur überfällige: AN':'Nur überfällige: AUS')+'</button></div>';
// register table
h += '<div class="section-h">Massnahmenregister ('+reg.length+' offen)</div>';
h += '<table class="grid"><thead><tr><th>ID</th><th>Titel</th><th>Owner</th><th>Quelle</th><th>Fällig</th><th>Status</th></tr></thead><tbody>';
reg.forEach(p=>{
const od = p.faellig && p.faellig < today;
if(pFilter.quelle && p.quelle!==pFilter.quelle) return;
if(pFilter.overdue && !od) return;
const stcl = p.status.toLowerCase()==='in arbeit'?'inArbeit':p.status.toLowerCase();
h += '<tr class="'+(od?'od':'')+'"><td>'+p.id+'</td><td>'+p.titel+'</td><td>'+p.owner+'</td>'
+ '<td><span class="tag q-'+p.quelle+'">'+p.quelle+'</span></td>'
+ '<td>'+p.faellig+(od?' &#9888;':'')+'</td><td><span class="pill '+stcl+'">'+p.status+'</span></td></tr>';
});
h += '</tbody></table>';
// overdue reviews
h += '<div class="section-h">Überfällige Dokumenten-Reviews ('+D.overdueReviews.length+')</div>';
if(D.overdueReviews.length){
h += '<table class="grid"><thead><tr><th>Dokument</th><th>Owner</th><th>Review fällig</th></tr></thead><tbody>';
D.overdueReviews.forEach(r=>{ h += '<tr class="od"><td><a href="#" onclick="showDoc(\''+encodeURIComponent(r.id)+'\');return false;">'+r.title+'</a></td><td>'+r.owner+'</td><td>'+r.nextReview+'</td></tr>'; });
h += '</tbody></table>';
} else { h += '<p style="color:var(--muted)">Keine überfälligen Reviews.</p>'; }
// zu pruefen
h += '<div class="section-h">[ZU PRÜFEN]-Marker ('+D.zuPruefen.length+')</div>';
if(D.zuPruefen.length){
h += '<table class="grid"><thead><tr><th>Dokument</th><th>Abschnitt</th></tr></thead><tbody>';
D.zuPruefen.forEach(z=>{ h += '<tr><td><a href="#" onclick="showDoc(\''+encodeURIComponent(z.id)+'\');return false;">'+z.title+'</a></td><td>'+z.section+'</td></tr>'; });
h += '</tbody></table>';
} else { h += '<p style="color:var(--muted)">Keine offenen Marker.</p>'; }
document.getElementById('content').innerHTML = h;
window.scrollTo(0,0);
}
function applyP(){ pFilter.quelle = document.getElementById('fq').value; showPendenzen(); }
function toggleOd(){ pFilter.overdue = !pFilter.overdue; showPendenzen(); }
document.getElementById('q').addEventListener('input', e=>buildNav(e.target.value));
buildNav('');
showDashboard();
</script>
</body>
</html>
"""
if __name__ == "__main__":
build()

View file

@ -1,56 +1,53 @@
# E-Compliance Prozessübersicht — PowerOn / PORTA
<!-- docId: IMS-MAP-CACC -->
<!-- status: entwurf -->
<!-- version: 1.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 27001:AnnexA; 9001:8 -->
**Zweck:** Dieses Verzeichnis enthält die dokumentierten Prozesse und Konzepte der PowerOn AG zum Nachweis der Anforderungen aus dem **GLKB Cloud Assessment Criteria Catalogue (CACC)** sowie den FINMA-Rundschreiben 2018/3 und 2023/1.
# CACC / FINMA <-> ISO-Crosswalk
**Stand:** 02.06.2026
**Geltungsbereich:** PORTA Enterprise KI-Plattform (`api.poweron.swiss`)
**Hinweis:** `[ZU PRÜFEN]` markiert Stellen, an denen ein Fakt vor Einreichung verifiziert oder ergänzt werden muss.
**Zweck:** Verknüpft die bestehenden Prozessdokumente (ursprünglich für **GLKB Cloud Assessment Criteria Catalogue (CACC)** und FINMA-Rundschreiben 2018/3 & 2023/1 erstellt) mit ihren neuen Speicherorten im IMS sowie den abgedeckten CACC-Punkten. Das Annex-A-Mapping für ISO 27001 ist das [SoA](../03_planung/statement-of-applicability-soa.md).
---
**Stand:** 2026-06-03
**Hinweis:** `[ZU PRÜFEN]` markiert Stellen, die vor einer Einreichung verifiziert werden müssen.
## Rahmenbedingungen (gelten für alle Dokumente)
## Rahmenbedingungen
- **Hosting & Datenspeicherung:** Infomaniak Public Cloud, Schweiz (`api.poweron.swiss`, `db.poweron.swiss`).
- **Datenverarbeitung KI:** Inhaltsdaten werden zur KI-Verarbeitung an externe LLM-Provider übermittelt. **Primärprovider ist OpenAI (USA).** Diese Übermittlung verlässt die Schweiz und ist über AVV/DPA + EU-SCC abgesichert (siehe Drittanbieter-Inventar und Verschlüsselungskonzept).
- **Team:** Sehr kleines Team (25 Personen). Wo Katalogpunkte eine grössere Organisation voraussetzen (24/7-SOC, vollständige Funktionstrennung), werden **kompensierende Massnahmen** beschrieben.
- **Hosting:** Infomaniak Public Cloud, Schweiz (`api.poweron.swiss`, `db.poweron.swiss`).
- **KI-Verarbeitung:** Inhaltsdaten gehen an externe LLM-Provider (Primär OpenAI/USA); abgesichert via AVV/DPA + EU-SCC + Neutralisierung.
- **Team:** 2-5 Personen; wo Katalogpunkte grössere Organisationen voraussetzen, greifen kompensierende Massnahmen.
---
## Dokumentenkarte -> neuer Ort + CACC-Punkte
## Dokumentenkarte → CACC-Punkte
| Dokument | Abgedeckte CACC-Punkte |
| Dokument (neuer Ort in `ims/`) | CACC-Punkte |
|---|---|
| `01_Informationssicherheitsrichtlinie.md` | 49, 52, 56 |
| `02_Zugriffsmanagement_IAM_PAM.md` | 25, 36, 37, 66, 67, 68, 69 |
| `03_Mitarbeitersicherheit_und_Screening.md` | 23, 35, 37 |
| `04_Verschluesselung_und_Schluesselmanagement.md` | 43, 44, 45, 46, 70, 71, 72 |
| `05_Backup_und_Wiederherstellung.md` | 75, 87 |
| `06_Business_Continuity_und_Disaster_Recovery.md` | 3, 79, 87 |
| `07_Incident_Response_und_Meldewesen.md` | 19, 20, 27, 86 |
| `08_Change_Management.md` | 81, 82, 83 |
| `09_Patch_Management.md` | 78 |
| `10_Schwachstellenmanagement.md` | 54, 59, 63, 84 |
| `11_Logging_und_Monitoring.md` | 88, 89, 90, 91, 92, 93, 94 |
| `12_Netzwerk_und_Infrastruktursicherheit.md` | 95, 96, 97, 98, 99 |
| `13_Datenaufbewahrung_Loeschung_LegalHold.md` | 1, 2, 38, 72 |
| `14_Exit_und_Transition.md` | 4, 5, 6, 22 |
| `15_Sichere_Softwareentwicklung_SDLC.md` | 100, 101, 102 |
| `16_Kapazitaetsmanagement.md` | 80 |
| `17_Subunternehmer_Management.md` | 16, 31, 48, 53 |
| `18_Analyse_Recht_und_BestPractice.md` | Befundbericht (rechtlich / Best Practice, intern) |
| **Bestehend:** `drittanbieter-inventar.md` | 48, 53, 61 |
| **Bestehend:** `datenbank-handling.md` | 2, 38, 75 (teilw.) |
| **Bestehend:** `bcm_runbook.md` | 3, 87 (technisch) |
| **Bestehend:** `feature_release_bugfix.md` | 81, 100, 101 (teilw.) |
| `02_fuehrung/informationssicherheitspolitik.md` | 49, 52, 56 |
| `05_betrieb/02_Zugriffsmanagement_IAM_PAM.md` | 25, 36, 37, 66, 67, 68, 69 |
| `05_betrieb/03_Mitarbeitersicherheit_und_Screening.md` | 23, 35, 37 |
| `05_betrieb/04_Verschluesselung_und_Schluesselmanagement.md` | 43, 44, 45, 46, 70, 71, 72 |
| `05_betrieb/05_Backup_und_Wiederherstellung.md` | 75, 87 |
| `05_betrieb/06_Business_Continuity_und_Disaster_Recovery.md` | 3, 79, 87 |
| `05_betrieb/07_Incident_Response_und_Meldewesen.md` | 19, 20, 27, 86 |
| `05_betrieb/08_Change_Management.md` | 81, 82, 83 |
| `05_betrieb/09_Patch_Management.md` | 78 |
| `05_betrieb/10_Schwachstellenmanagement.md` | 54, 59, 63, 84 |
| `05_betrieb/11_Logging_und_Monitoring.md` | 88, 89, 90, 91, 92, 93, 94 |
| `05_betrieb/12_Netzwerk_und_Infrastruktursicherheit.md` | 95, 96, 97, 98, 99 |
| `05_betrieb/13_Datenaufbewahrung_Loeschung_LegalHold.md` | 1, 2, 38, 72 |
| `05_betrieb/14_Exit_und_Transition.md` | 4, 5, 6, 22 |
| `05_betrieb/15_Sichere_Softwareentwicklung_SDLC.md` | 100, 101, 102 |
| `05_betrieb/16_Kapazitaetsmanagement.md` | 80 |
| `05_betrieb/17_Subunternehmer_Management.md` | 16, 31, 48, 53 |
| `05_betrieb/18_Analyse_Recht_und_BestPractice.md` | Befundbericht (intern) |
| `05_betrieb/20260528_drittanbieter-inventar.md` | 48, 53, 61 |
| `05_betrieb/20260528_datenbank-handling.md` | 2, 38, 75 (teilw.) |
| `05_betrieb/20260528_bcm_runbook.md` | 3, 87 (technisch) |
| `05_betrieb/20260528_feature_release_bugfix.md` | 81, 100, 101 (teilw.) |
---
## Offene Punkte (in Massnahmenregister überführt)
## Offene Punkte vor Einreichung (Sammelliste)
- [ ] Verschlüsselung at-rest der Infomaniak-DB bestätigen (Konzept #04)
- [ ] MFA-Status auf Admin-/Server-Zugängen bestätigen (#02)
- [ ] Hintergrundprüfungen bei Einstellung klären (#03)
- [ ] Log-Aufbewahrungsdauer und Manipulationsschutz festlegen (#11)
- [ ] Restore-Test-Protokoll erstmalig durchführen und ablegen (#05)
- [ ] AVV/Zero-Retention-Verträge mit OpenAI & weiteren LLM-Providern ablegen (#17)
- [ ] Entscheidung zu produktiven Daten in Testumgebung (#15)
Die frühere Sammelliste offener Punkte wird jetzt zentral im [Massnahmenregister](../07_verbesserung/massnahmen-register.md) geführt (M-01 bis M-07 u. a.: at-rest-Verschlüsselung, MFA, Hintergrundprüfungen, Log-Retention, Restore-Test, AVVs, Testdaten).

View file

@ -0,0 +1,17 @@
<!-- docId: IMS-MAP-27001 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 27001:AnnexA -->
# Mapping ISO/IEC 27001:2022 Annex A
Das massgebliche Mapping aller 93 Annex-A-Controls (Anwendbarkeit, Status, umsetzendes Dokument) ist das **Statement of Applicability**:
-> [Statement of Applicability (SoA)](../03_planung/statement-of-applicability-soa.md)
Die ISO-27001-Hauptklauseln 4-10 werden durch das Managementsystem-Geruest abgedeckt; siehe [iso9001-klausel-mapping.md](iso9001-klausel-mapping.md) (strukturgleich, Annex SL) sowie die `isoRefs`-Header der einzelnen Dokumente.

View file

@ -0,0 +1,34 @@
<!-- docId: IMS-MAP-9001 -->
<!-- status: entwurf -->
<!-- version: 0.1 -->
<!-- owner: Patrick Motsch -->
<!-- approver: Geschäftsführung PowerOn AG -->
<!-- approvedDate: -->
<!-- nextReview: 2027-06-03 -->
<!-- classification: intern -->
<!-- isoRefs: 9001:4-10 -->
# Mapping ISO 9001:2015 -- Klauseln zu IMS-Dokumenten
Nachweis, welches Dokument welche ISO-9001-Anforderung abdeckt.
| Klausel | Anforderung | Dokument |
|---|---|---|
| 4.1/4.2 | Kontext, interessierte Parteien | [kontext-und-interessierte-parteien.md](../01_kontext/kontext-und-interessierte-parteien.md) |
| 4.3/4.4 | Geltungsbereich, QMS & Prozesse | [geltungsbereich-scope.md](../01_kontext/geltungsbereich-scope.md) |
| 5.1/5.2 | Führung, Qualitätspolitik | [qm-politik.md](../02_fuehrung/qm-politik.md), [00_IMS-Handbuch.md](../00_IMS-Handbuch.md) |
| 5.3 | Rollen & Verantwortlichkeiten | [rollen-verantwortlichkeiten.md](../02_fuehrung/rollen-verantwortlichkeiten.md) |
| 6.1 | Risiken & Chancen | [risikomanagement-methodik.md](../03_planung/risikomanagement-methodik.md), [risikoregister.md](../03_planung/risikoregister.md) |
| 6.2 | Qualitätsziele | [ziele-und-kennzahlen.md](../03_planung/ziele-und-kennzahlen.md) |
| 7.1-7.3 | Ressourcen, Kompetenz, Awareness | [ressourcen-kompetenz-schulung.md](../04_unterstuetzung/ressourcen-kompetenz-schulung.md) |
| 7.4 | Kommunikation | [kommunikation.md](../04_unterstuetzung/kommunikation.md) |
| 7.5 | Dokumentierte Information | [dokumentenlenkung.md](../04_unterstuetzung/dokumentenlenkung.md), [dokumentenregister.md](../04_unterstuetzung/dokumentenregister.md) |
| 8.1-8.6 | Betrieb, Anforderungen, Entwicklung, Realisierung | [feature_release_bugfix.md](../05_betrieb/20260528_feature_release_bugfix.md), [SDLC](../05_betrieb/15_Sichere_Softwareentwicklung_SDLC.md), [Change](../05_betrieb/08_Change_Management.md) |
| 9.1 | Monitoring, Messung, Analyse | [monitoring-messung.md](../06_bewertung/monitoring-messung.md) |
| 9.2 | Internes Audit | [internes-audit.md](../06_bewertung/internes-audit.md) |
| 9.3 | Management-Review | [management-review.md](../06_bewertung/management-review.md) |
| 10.1-10.3 | Verbesserung, Nichtkonformität, KVP | [korrekturmassnahmen-und-kvp.md](../07_verbesserung/korrekturmassnahmen-und-kvp.md), [massnahmen-register.md](../07_verbesserung/massnahmen-register.md) |
## ISO/IEC 27001 Annex A
Das Mapping der ISO-27001-Annex-A-Controls ist das [Statement of Applicability (SoA)](../03_planung/statement-of-applicability-soa.md). Die ISO-27001-Klauseln 4-10 sind strukturgleich zu ISO 9001 (Annex SL) und werden durch dieselben oben gelisteten Dokumente abgedeckt (vgl. `isoRefs`-Header je Dokument).

View file

@ -1,203 +0,0 @@
# Neutralisierung
**Stand:** 2026-04-16
---
## 1. Grundidee
Neutralisierung passiert dort, wo **Content entsteht oder ins System einfliesst** — nicht als nachgelagerter Filter vor dem Modell-Call. Wenn Content einmal neutralisiert ist (z. B. im RAG), bleibt er neutralisiert. Kein doppeltes Verarbeiten.
---
## 2. Wer fordert Neutralisierung?
Drei Quellen, von breit nach spezifisch:
| Quelle | Flag im Code | Bedeutung |
|--------|-------------|-----------|
| **Feature-Instanz** | `DataNeutraliserConfig.enabled` (hat `featureInstanceId` + `mandateId`) | Alle Daten in dieser Feature-Instanz werden neutralisiert. Betrifft jeden Content-Einstieg innerhalb dieser Instanz. |
| **Chat-Workflow / Session** | `ServiceCenterContext.requireNeutralization` (gesetzt z. B. vom AI-Workspace oder Automation) | Dieser Workflow/Turn: jeder Content, der hier verarbeitet wird, wird neutralisiert. |
| **Dokument oder Quelle** | `FileItem.neutralize`, `FileFolder.neutralize`, `DataSource.neutralize`, `FeatureDataSource.neutralize`, `FeatureDataSource.neutralizeFields` | Dieses konkrete Objekt: Content daraus wird neutralisiert, egal ob die Feature-Instanz oder der Workflow es sonst fordern würden. `FileFolder.neutralize` propagiert auf alle enthaltenen Dateien. `neutralizeFields` ermoeglicht Feld-Level-Maskierung bei DB-Queries. |
**Auswertung:** Irgendeine Quelle sagt `True` → neutralisieren. Keine Quelle kann eine andere aufheben. Es gibt kein `False`-Override, das ein `True` von woanders aushebelt.
---
## 3. Wo passiert die Neutralisierung?
Am **Punkt der Content-Einspeisung** — dort wo Rohdaten zu verarbeitbarem Content werden:
| Content-Einstieg | Was passiert | Wer prüft das Flag |
|------------------|-------------|---------------------|
| **Datei-Indexierung** (RAG) | Text-Chunks werden über `processText` neutralisiert, bevor sie ins Embedding gehen. Medien: nur internes Modell oder nicht indexieren. Ergebnis: RAG enthält nur neutralisierten Content. | `mainServiceKnowledge.indexFile` liest `FileItem.neutralize` |
| **Content-Extraktion** (Dokumente für KI-Verarbeitung) | Extrahierter Text/Tabellen werden neutralisiert. PDF, DOCX, XLSX, PPTX über `processFile` (Extract → neutralisieren → zurückschreiben). | Caller kennt die Quelle und deren Flag |
| **User-Prompt** (Chat-Eingabe) | Prompt-Text wird durch `processText` neutralisiert, wenn Feature-Instanz oder Workflow es fordern. | `mainServiceAi` prüft Context-Flag / Config |
| **DataSource-Download** | Flag wird auf erstellte `FileItem`s vererbt → bei Extraktion/Indexierung greift das File-Flag automatisch. | `mainServiceAgent._resolveDataSource` / `_downloadFromDataSource` |
| **FeatureDataSource-Abfrage (Tabelle)** | Wenn eine `FeatureDataSource.neutralize=True` hat → Content aus diesem Sub-Agent-Call wird neutralisiert. | `mainServiceAgent._queryFeatureInstance` setzt `requireNeutralization=True` |
| **FeatureDataSource-Abfrage (Feld/Typ, seit 2026-06)** | Typ- und vererbungsbewusst: **Strings** werden substring-neutralisiert sobald effektiv (explizit ODER geerbt, Feldname als Typ-Hint); **Binary** wird gedroppt; **andere Skalare** (number/date/bool) nur bei **explizitem** Feld-Flag als Ganzwert-Platzhalter `[NEUT.<field>.<hash>]`. Identifikatoren/System-Spalten ausgenommen, Engine-Ausfall = `[REDACTED]`. RAG-Bootstrap nutzt dieselbe Policy (Query- und Index-Pfad konsistent). | `featureDataProvider.finalizeRowsAsync` / `_neutralizeAndSerializeRows`; Policy aus `coreTools/_featureSubAgentTools` via `resolveEffectiveForFds` |
| **De-Neutralisierung für Download (seit 2026-06)** | Read-only Agent-Tool `revealDocument` löst Platzhalter **nur** über das lokale Mapping (`resolveText`, kein externes LLM) auf und liefert Klartext als transienten Einmal-Download (SSE `revealDownload`) — kein Save/Index/Historie. | `coreTools/_mediaTools._revealDocument` |
| **Ordner-Neutralisierung** | `FileFolder.neutralize=True` propagiert auf alle enthaltenen Dateien (rekursiv). Neue/verschobene Dateien erben das Flag. Index-Purge + Re-Index wie bei einzelnen Dateien. | `routeDataFiles.updateFolderNeutralize` |
| **Workflow-Aktion `neutralizeData`** | Expliziter Neutralisierungs-Schritt auf bereits extrahierten ContentParts. | Workflow-Config + `NeutralizationConfig.enabled` |
**Was NICHT nochmal neutralisiert werden muss:**
- RAG-Chunks, die bereits neutralisiert indexiert sind — die sind schon sauber.
- Web-Suchergebnisse — enthalten keine Mandantendaten, brauchen keine Neutralisierung.
**Flag-Änderung:** Ändert sich `FileItem.neutralize` (Toggle) → Index löschen → Re-Indexierung triggern → neuer Index ist im richtigen Zustand.
---
## 4. Engine: `NeutralizationService`
Eine Engine, drei Einstiege, aufgerufen an den Content-Einstiegspunkten aus Abschnitt 3.
| API | Eingabe | Status |
|-----|---------|--------|
| `processText(text)` | Rohtext (Prompt, Message, Text-ContentPart, Text-Chunk) | **Ist** |
| `processFile(fileId)` | Datei aus DB — wird nach MIME geroutet | **Ist** |
| `processBinaryBytes` / `Async` | Bytes + Dateiname + MIME | **Ist** |
| **`processImage(imageBytes, fileName)`** / `processImageAsync` | Bild-Datei oder Bild-ContentPart (image/png, image/jpeg, …) | **Ist** (seit ~2026 Q1) |
**Ist-Zustand Bilder (aktualisiert 2026-04-05):** `processImageAsync` ist implementiert und nutzt `NEUTRALIZATION_IMAGE` (Private LLM Vision). `_processBinaryFile` verarbeitet jetzt Bild-Parts ueber `processImageAsync`. **Einschraenkung:** Eigenstaendige Bild-Dateien (`image/*` MIME direkt an `processFile`) werden in `_isBinaryMimeType` weiterhin als Skip behandelt.
**Ist (aktualisiert):** `processImageAsync` existiert als Einstieg. Ruft internes Vision-Modell (`NEUTRALIZATION_IMAGE` → Private-LLM) auf, um sensible Inhalte in Bildern zu erkennen/entfernen. Kein externer Provider. Modell nicht verfügbar → Bild blockieren (nicht unbehandelt weiterreichen).
**Ablauf nach MIME:**
| MIME | Pfad |
|------|------|
| PDF, DOCX, XLSX, PPTX | `runExtraction` → Text/Table-Parts durch `_neutralizeText`, Bild-Parts durch `processImage` → PDF in-place oder Office-Renderer |
| Text, JSON, CSV, XML | `_neutralizeText` direkt (TextProcessor, ListProcessor, BinaryProcessor je nach Inhalt) |
| Bilder (image/*) | **`processImage`** → internes Vision-Modell (`NEUTRALIZATION_IMAGE`). Nicht verfügbar → blockieren. |
| Video, Audio | Nur internes Modell oder blockieren (analog Bilder, aber niedrigere Priorität) |
| Anderes Binary | Skip (nicht unterstützt) |
**Mapping:** Platzhalter `[typ.uuid]` → Attribute in DB. `resolveText(text)` für Rückübersetzung.
---
## 5. Modellauswahl
| Operation Type | Modelle | Zweck |
|----------------|---------|-------|
| `NEUTRALIZATION_TEXT` | `poweron-text-general` (Rating 9) | Falls Engine ein LLM für Text braucht |
| `NEUTRALIZATION_IMAGE` | `poweron-vision-general` (9), `poweron-vision-deep` (9) | Medien bei Neutralisierungspflicht: nur intern |
Registriert in `aicorePluginPrivateLlm.py`. Externe Provider haben keine `NEUTRALIZATION_*`-Ratings → werden nie für Neutralisierung gewählt.
---
## 6. Fail-safe
| Situation | Verhalten |
|-----------|-----------|
| Neutralisierung gefordert, Engine nicht verfügbar | Content **nicht** weiterverarbeiten (blockieren) |
| Neutralisierung eines Teils schlägt fehl | Teil entfernen, nicht im Rohzustand weiterleiten |
| Kein internes Modell für Medien verfügbar | Medien-Part entfernen |
---
## 7. Code-Karte
| Bereich | Pfad |
|---------|------|
| Engine | `features/neutralization/serviceNeutralization/mainServiceNeutralization.py` + `subProcess*.py` |
| Config + Attribute DB | `features/neutralization/datamodelFeatureNeutralizer.py`, `interfaceFeatureNeutralizer.py` |
| Index (Data-at-rest) | `serviceCenter/services/serviceKnowledge/mainServiceKnowledge.py` |
| Prompt-Neutralisierung | `serviceCenter/services/serviceAi/mainServiceAi.py` (`_shouldNeutralize`, `_neutralizeRequest`) |
| Agent / DataSource / Feature | `serviceCenter/services/serviceAgent/mainServiceAgent.py` |
| Workflow-Aktion | `workflows/methods/methodContext/actions/neutralizeData.py` |
| Modelle / Enums | `datamodels/datamodelAi.py`, `aicore/aicorePluginPrivateLlm.py` |
| Flags | `datamodelFiles.py` (`FileItem.neutralize`), `datamodelDataSource.py`, `datamodelFeatureDataSource.py` |
| Context | `serviceCenter/context.py` (`ServiceCenterContext.requireNeutralization`) |
---
## 8. Umsetzungsplan
### Schritt 1: `processImage` in Engine bauen
**Datei:** `mainServiceNeutralization.py`
**Was:** Neue Methode `processImage(imageBytes: bytes, fileName: str, mimeType: str) -> Dict` und `processImageAsync`.
**Wie:** Internes Vision-Modell aufrufen (`NEUTRALIZATION_IMAGE` via Model Selector / `aiObjects`). Prompt: sensible Inhalte im Bild erkennen und beschreiben, damit Caller entscheiden kann ob Bild blockiert wird. Kein internes Modell verfügbar → `{'status': 'blocked'}` zurückgeben.
**Abhängigkeit:** `OperationTypeEnum.NEUTRALIZATION_IMAGE` + Modell-Ratings in `aicorePluginPrivateLlm.py`**bereits erledigt**.
### Schritt 2: `_shouldNeutralize` vereinfachen
**Datei:** `mainServiceAi.py` (Zeile ~560)
**Ist:** Prüft `request.requireNeutralization``context.requireNeutralization``NeutralizationConfig.enabled` (Mandant-Level Config). `request.requireNeutralization=False` bricht sofort ab.
**Soll:** Drei Quellen gemäss Abschnitt 2, kein `False`-Override:
1. Feature-Instanz: `NeutralizationConfig.enabled` (hat `featureInstanceId`)
2. Workflow/Session: `context.requireNeutralization`
3. Request: `request.requireNeutralization`
Irgendein `True` → neutralisieren. `False` in einer Quelle hebt `True` in einer anderen **nicht** auf.
**Änderung:** `if request.requireNeutralization is False: return False` **entfernen**. Stattdessen OR-Verknüpfung aller drei Quellen.
### Schritt 3: `_neutralizeRequest` auf Prompt/Messages beschränken
**Datei:** `mainServiceAi.py` (Zeile ~592)
**Ist:** Neutralisiert `prompt`, `context`, `messages` (String-Content).
**Soll:** Zusätzlich Text in `contentParts` und Text-Teile in multimodalen Messages (content-Liste mit `type==text`). Bild-Teile in Messages: bei Neutralisierungspflicht über `processImage` prüfen oder entfernen.
**Wichtig:** Hier geht es nur um Prompt-/Sessiondaten. File-Content aus RAG ist bereits neutralisiert (Schritt 5), muss hier nicht nochmal durch.
### Schritt 4: `indexFile` — Bild-Chunks behandeln
**Datei:** `mainServiceKnowledge.py` (Zeile ~146 ff.)
**Ist:** Nur `textObjects` (contentType == "text") werden bei `_shouldNeutralize` durch `processText` geschickt. Bild-Chunks (`contentType == "image"`) werden unverändert indexiert.
**Soll:** Bild-Chunks bei `_shouldNeutralize` über `processImage` (Schritt 1) prüfen. Ergebnis `blocked` → Bild-Chunk nicht indexieren. Ergebnis OK → Bild-Chunk indexieren (internes Modell hat es gesehen, kein externer Provider nötig).
**Abhängigkeit:** Schritt 1.
### Schritt 5: Agent-Tool `readFile` — Content bei Extraktion neutralisieren
**Datei:** `mainServiceAgent.py`, Tool `_readFile` (Zeile ~540 ff.)
**Ist:** Liest aus Knowledge Store (bereits indexiert) oder extrahiert on-demand. Kein Neutralisierungs-Check.
**Soll:**
- **Knowledge Store Pfad (Zeile ~548):** RAG-Chunks sind bereits neutralisiert wenn `FileItem.neutralize=True` war (Schritt 4) → nichts zu tun.
- **On-Demand Extraktion (Zeile ~630 ff.):** Nach `runExtraction` und vor Rückgabe der Text-Objekte: `FileItem.neutralize` laden. Wenn `True` → Text-Objekte durch `processText`, Bild-Objekte durch `processImage`.
### Schritt 6: Agent-Tool `summarizeContent` — File-Flag prüfen
**Datei:** `mainServiceAgent.py`, Tool `_summarizeContent` (Zeile ~1921 ff.)
**Ist:** Liest Content-Objects aus Knowledge Store, baut `combinedText` und ruft `callAi` auf. Kein Neutralisierungs-Check.
**Soll:** Content aus Knowledge Store ist bereits neutralisiert (Schritt 4) → nichts zu tun, **sofern** File indexiert war. Wenn nicht indexiert: File-Flag prüfen, Text vor `callAi` durch `processText`.
**Hinweis:** Durch Schritt 4 ist der Regelfall abgedeckt.
### Schritt 7: Agent-Tool `describeImage` — File-Flag prüfen
**Datei:** `mainServiceAgent.py`, Tool `_describeImage` (Zeile ~2015 ff.)
**Ist:** Lädt Bild-Chunk oder Rohdaten, sendet per `callAi` mit `IMAGE_ANALYSE` an **beliebigen** Provider (inkl. extern). Kein Neutralisierungs-Check.
**Soll:** `FileItem.neutralize` laden (fileId ist bekannt). Wenn `True`:
- `operationType` auf `NEUTRALIZATION_IMAGE` statt `IMAGE_ANALYSE` → Model Selector wählt nur internes Modell.
- Kein internes Modell → Tool gibt Fehler zurück statt Bild an externen Provider zu senden.
### Schritt 8: `_processBinaryFile` — Bild-Parts nicht mehr überspringen
**Datei:** `mainServiceNeutralization.py` (Zeile ~298)
**Ist:** `if type_group in ('binary', 'image'): neutralized_parts.append(part); continue` — Bild-Parts werden übersprungen.
**Soll:** `binary` weiterhin skip. `image` → durch `processImage` (Schritt 1). Ergebnis `blocked` → Part entfernen. Ergebnis OK → Part behalten.
**Abhängigkeit:** Schritt 1.
### Schritt 9: Workflow-Aktion `neutralizeData` — Bild-Parts
**Datei:** `neutralizeData.py` (Zeile ~130 ff.)
**Ist:** Iteriert über ContentParts, neutralisiert nur Parts mit `part.data` (Text). `typeGroup != text/table` → unverändert durchgereicht.
**Soll:** Bild-Parts durch `processImage`. Ergebnis `blocked` → Part entfernen.
**Abhängigkeit:** Schritt 1.
### Schritt 10: Tests
| Test | Was |
|------|-----|
| T1 | `FileItem.neutralize=True``indexFile` → Text-Chunks neutralisiert, Bild-Chunks geprüft/blockiert |
| T2 | `readFile` on-demand auf File mit `neutralize=True` → Text neutralisiert |
| T3 | `describeImage` auf File mit `neutralize=True` → nur internes Modell |
| T4 | Feature-Instanz Config `enabled=True` → Prompt in `callAi` neutralisiert |
| T5 | Workflow `requireNeutralization=True` → Prompt neutralisiert |
| T6 | `processFile` auf PDF mit Bildern → Text neutralisiert, Bild-Parts durch `processImage` |
| T7 | Flag-Toggle → Index gelöscht → Re-Index im richtigen Zustand |
### Schritt 11: Logging
**Alle Stellen (Schritte 29):** Bei Neutralisierung loggen: welche Quelle (Feature-Instanz / Workflow / File-Flag), welche `fileId` falls vorhanden, Ergebnis (OK / Part entfernt / blockiert). **Kein Klartext** in Logs.

View file

@ -1,369 +0,0 @@
# PowerOn Plattform -- Sicherheit und Compliance
**Stand:** Februar 2026
**Zielgruppe:** Entscheidungsträger, Einkauf, Rechtsabteilung, Datenschutzbeauftragte
**Klassifizierung:** Kundeninformation
---
## 1. Management Summary
PowerOn ist eine **Multi-Mandanten-KI-Plattform für Unternehmen**, die es Organisationen ermöglicht, KI-gestützte Geschäftsprozesse sicher, datenschutzkonform und mandantengetrennt zu betreiben. Die Plattform richtet sich an mittlere bis grosse Unternehmen in datenschutzsensiblen Branchen wie Finanzwesen, Treuhand, Immobilien und Beratung.
Dieses Dokument beschreibt die in PowerOn implementierten Sicherheits- und Datenschutzmassnahmen, ordnet diese gängigen Standards zu und benennt transparent bestehende Einschränkungen.
**Kernaussagen:**
- **DSGVO-Betroffenenrechte** (Auskunft, Löschung, Datenübertragbarkeit, Berichtigung) sind als Self-Service-Funktionen direkt in der Plattform implementiert.
- **Vollständige Mandantentrennung:** Daten eines Mandanten sind unter keinen Umständen für andere Mandanten einsehbar oder zugänglich.
- **Rollenbasierte Zugriffskontrolle (RBAC):** Jeder Datenzugriff wird gegen ein mehrstufiges Berechtigungssystem geprüft -- konfigurierbar pro Mandant und Funktionsmodul.
- **Verschlüsselung:** Sensible Konfigurationsdaten sind nach Industriestandard verschlüsselt, sämtliche Kommunikation erfolgt über verschlüsselte Verbindungen.
- **Audit-Trail:** Alle sicherheitsrelevanten Aktionen werden lückenlos protokolliert und stehen für Compliance-Nachweise zur Verfügung.
- **Transparenz bei KI-Nutzung:** Die Plattform dokumentiert offen, welche Daten an KI-Dienste übermittelt werden, und bietet Konfigurationsoptionen für höchste Datenschutzanforderungen.
---
## 2. DSGVO-Konformität
PowerOn implementiert die zentralen Betroffenenrechte der Datenschutz-Grundverordnung (DSGVO/GDPR) direkt als Plattformfunktionen. Im Folgenden wird für jeden relevanten Artikel beschrieben, was implementiert ist und wo Einschränkungen bestehen.
### 2.1 Auskunftsrecht (Art. 15 DSGVO)
Nutzer können über eine Self-Service-Funktion sämtliche über sie gespeicherten Daten exportieren:
- Persönliche Profildaten (Name, E-Mail, Spracheinstellungen)
- Mandatszugehörigkeiten und zugewiesene Rollen
- Zugriffsrechte auf Funktionsmodule
- Erstellte und eingelöste Einladungen
- Zeitpunkte der Kontoerstellung und letzten Anmeldung
Der Export umfasst alle auf Plattformebene gespeicherten Daten. Feature-spezifische Daten (z.B. Chat-Verläufe, Treuhandpositionen) können über die jeweiligen Funktionsmodule eingesehen werden.
**Status: Implementiert.**
### 2.2 Recht auf Löschung (Art. 17 DSGVO)
Nutzer können ihr Konto und alle zugehörigen Daten eigenständig und unwiderruflich löschen. Dabei gilt:
- Das System durchsucht automatisch alle Datenbanken (Plattform, Verwaltung, Chat, alle Funktionsmodule) nach Einträgen, die dem Nutzer zugeordnet sind.
- Nutzerbezogene Daten werden vollständig gelöscht.
- Audit-Logs werden anonymisiert statt gelöscht -- dies gewährleistet die Einhaltung gesetzlicher Aufbewahrungspflichten bei gleichzeitiger Wahrung der Betroffenenrechte.
- Die Löschung erfordert eine explizite Bestätigung durch den Nutzer.
- Systemadministratoren sind von der Selbstlöschung ausgenommen (Vier-Augen-Prinzip).
**Status: Implementiert.**
### 2.3 Recht auf Datenübertragbarkeit (Art. 20 DSGVO)
Nutzerdaten können in einem maschinenlesbaren, standardisierten Format (JSON-LD nach schema.org) exportiert werden. Dieses Format ermöglicht die Übertragung der Daten an einen anderen Dienstleister.
**Status: Implementiert.**
### 2.4 Berichtigungsrecht (Art. 16 DSGVO)
Nutzer können ihre Profildaten (Name, E-Mail, Spracheinstellungen) jederzeit selbst korrigieren.
**Status: Implementiert.**
### 2.5 Transparenz und Informationspflicht
Die Plattform stellt Nutzern aktiv Informationen über die Datenverarbeitung bereit:
- Welche Daten erhoben werden
- Zu welchem Zweck die Verarbeitung erfolgt
- Auf welcher Rechtsgrundlage die Verarbeitung basiert
- Welche Aufbewahrungsfristen gelten
- Welche Betroffenenrechte bestehen und wie sie ausgeübt werden können
**Status: Implementiert.**
### 2.6 Bekannte Einschränkungen
Die folgenden Punkte sind transparent zu benennen:
- **Consent-Management:** Die Plattform verfügt derzeit über kein granulares Einwilligungsmanagement mit individuellen Zustimmungs-Toggles. Die Einwilligung zur Datenverarbeitung erfolgt über die Nutzungsbedingungen und, bei Drittanbieter-Authentifizierung (Microsoft, Google), über die jeweiligen OAuth-Einwilligungsflüsse.
- **Datenschutz-Kontaktadresse:** Die Kontaktadresse für Datenschutzanfragen ist pro Deployment konfigurierbar und muss vom jeweiligen Betreiber hinterlegt werden.
---
## 3. Mandantenmodell und Datenisolation
### 3.1 Grundprinzip
PowerOn ist als Multi-Mandanten-Plattform konzipiert. Jede Organisation, Abteilung oder jeder Kunde wird als eigenständiger **Mandant** abgebildet. Das zentrale Sicherheitsversprechen:
> **Daten eines Mandanten sind unter keinen Umständen für Nutzer anderer Mandanten sichtbar oder zugänglich.**
### 3.2 Wie die Trennung funktioniert
- **Zugehörigkeitsprüfung bei jedem Zugriff:** Bevor ein Nutzer auf Mandantendaten zugreifen kann, prüft die Plattform, ob eine aktive Mitgliedschaft des Nutzers in diesem Mandanten besteht. Ohne nachgewiesene Mitgliedschaft wird der Zugriff verweigert.
- **Kein mandantenübergreifender Datenfluss:** Datenbankabfragen werden automatisch auf den Mandantenkontext gefiltert. Es gibt keinen Mechanismus, der Daten mandantenübergreifend zusammenführt oder exponiert.
- **Feature-Isolation:** Innerhalb eines Mandanten werden Funktionsmodule (z.B. CommCoach, Treuhand, Immobilien) zusätzlich isoliert. Nutzer benötigen für jedes Funktionsmodul eine explizite Zugriffsberechtigung.
### 3.3 Mehrfachmandanten
Nutzer können gleichzeitig in mehreren Mandanten arbeiten -- ein häufiges Szenario bei Beratern, Treuhändern oder Dienstleistern mit mehreren Kunden. Die Plattform stellt sicher:
- Der Mandantenkontext wird pro Anfrage bestimmt, nicht pro Sitzung. Ein Wechsel zwischen Mandanten ist jederzeit möglich, ohne dass Daten vermischt werden.
- Es findet keine Übertragung von Daten, Berechtigungen oder Einstellungen zwischen Mandanten statt.
### 3.4 Schutz vor Manipulation
Auch bei technischem Wissen über die Plattformarchitektur ist ein unbefugter Zugriff auf fremde Mandantendaten nicht möglich: Die Zugehörigkeitsprüfung erfolgt serverseitig und kann nicht durch Manipulation von Anfrageparametern umgangen werden.
---
## 4. Rollenbasierte Zugriffskontrolle (RBAC)
### 4.1 Berechtigungsmodell
PowerOn verfügt über ein feingliedriges, rollenbasiertes Berechtigungssystem. Für jede Aktion (Lesen, Erstellen, Bearbeiten, Löschen) können individuelle Berechtigungsstufen vergeben werden:
| Berechtigungsstufe | Beschreibung |
|---|---|
| Kein Zugriff | Funktion ist nicht verfügbar |
| Eigene Daten | Zugriff nur auf selbst erstellte Einträge |
| Mandantendaten | Zugriff auf alle Daten innerhalb des eigenen Mandanten |
| Alle Daten | Vollzugriff (typischerweise für Administratoren) |
### 4.2 Konfigurierbarkeit
- Rollen können **pro Mandant** und **pro Funktionsmodul** definiert und zugewiesen werden.
- Es gibt keine fest verdrahteten Berechtigungen -- jede Organisation kann das Rollenmodell an ihre Bedürfnisse anpassen.
- Berechtigungsänderungen werden im Audit-Trail protokolliert.
### 4.3 Administratoren
Systemadministratoren verfügen über erweiterte Rechte, unterliegen jedoch ebenfalls dem RBAC-System. Alle Administratoraktionen werden gesondert im Audit-Log festgehalten. Es gibt kein unkontrolliertes "Superuser"-Konto ohne Nachvollziehbarkeit.
---
## 5. Verschlüsselung und Datensicherheit
### 5.1 Verschlüsselung ruhender Daten
Alle sensiblen Konfigurationsdaten werden verschlüsselt gespeichert:
- **Verschlüsselungsverfahren:** AES-Verschlüsselung (Fernet)
- **Schlüsselableitung:** PBKDF2-HMAC-SHA256 nach aktuellem Industriestandard
- **Umfang:** Datenbankpasswörter, API-Schlüssel für KI-Dienste, OAuth-Geheimnisse, JWT-Schlüssel und alle weiteren als "SECRET" gekennzeichneten Konfigurationswerte
Sensible Konfigurationsdaten liegen zu keinem Zeitpunkt im Klartext in der Konfiguration oder im Quellcode vor.
### 5.2 Verschlüsselung in Übertragung
- Sämtliche Kommunikation zwischen Client und Server erfolgt über HTTPS/TLS.
- Verbindungen zu Drittdiensten (KI-Anbieter, Authentifizierungsdienste, E-Mail-Dienste) nutzen ebenfalls ausschliesslich verschlüsselte Verbindungen.
- Die TLS-Konfiguration erfolgt auf Infrastruktur-Ebene (Azure / Reverse Proxy) -- dies entspricht dem Branchenstandard bei Cloud-Deployments und ermöglicht zentrale Verwaltung und Aktualisierung der Zertifikate.
### 5.3 Zugriffskontrolle auf Verschlüsselungsschlüssel
- Der Zugriff auf Verschlüsselungsschlüssel ist auf das Minimum beschränkt.
- Jeder Zugriff auf Verschlüsselungsfunktionen (Entschlüsselung, Neuverschlüsselung) wird im Audit-Trail protokolliert.
- Eine Ratenbegrenzung schützt vor automatisierten Entschlüsselungsversuchen.
---
## 6. Schutzmassnahmen gegen Angriffe
PowerOn implementiert Schutzmassnahmen gegen die gängigsten Angriffsvektoren für Webanwendungen:
### 6.1 Cross-Site Request Forgery (CSRF)
Alle datenverändernden Operationen (POST, PUT, DELETE, PATCH) erfordern einen `X-CSRF-Token` Header. Die aktuelle Implementierung validiert das Tokenformat (16-64 Zeichen Hex-String); es gibt kein serverseitiges Session-Binding (kein klassisches Double-Submit oder Synchronizer Token). In Kombination mit `SameSite=Strict` Cookies und CORS bietet dies Basisschutz gegen CSRF.
### 6.2 Ratenbegrenzung (Rate Limiting)
Jede API-Funktion ist mit individuellen Zugriffslimits versehen, die automatisierte Angriffe und Missbrauch unterbinden:
| Funktion | Limit |
|---|---|
| Anmeldung | 30 Versuche pro Minute |
| Datenexport (DSGVO) | 5 Anfragen pro Minute |
| Kontolöschung | 1 Anfrage pro Stunde |
| KI-Anfragen | 120 Anfragen pro Minute |
| Datei-Upload | 10 Uploads pro Minute |
### 6.3 Eingabebereinigung
Nutzereingaben werden bereinigt und validiert, bevor sie an KI-Modelle oder Datenbanken weitergeleitet werden. Dies schützt vor Prompt-Injection-Angriffen und anderen Manipulationsversuchen.
### 6.4 SQL-Injection-Schutz
- Alle Datenbankabfragen der Plattform verwenden parametrisierte Abfragen -- der Industriestandard zur Vermeidung von SQL-Injection.
- Der KI-gestützte Datenbankzugriff ist zusätzlich auf reine Leseabfragen (SELECT) beschränkt. Schreibende, ändernde oder löschende Operationen sind auf Systemebene blockiert.
### 6.5 Cross-Origin Resource Sharing (CORS)
Nur definierte und verifizierte Quelldomains erhalten Zugriff auf die Plattform-API. Anfragen von nicht autorisierten Quellen werden automatisch abgelehnt.
---
## 7. KI-Dienste und Datenverarbeitung
Transparenz im Umgang mit KI-Diensten ist für datenschutzbewusste Organisationen entscheidend. PowerOn legt offen, wie Daten im Kontext der KI-Nutzung verarbeitet werden.
### 7.1 Welche Daten werden verarbeitet
Im Rahmen der KI-gestützten Funktionen (KI-Assistent, Workflow-Verarbeitung, Dokumentenanalyse) können folgende Daten an KI-Dienste übermittelt werden:
- Nutzeranfragen und -eingaben
- Dokumentinhalte (bei Dokumentenanalyse)
- Gesprächsverläufe (bei Chat-Funktionen)
### 7.2 Welche KI-Anbieter werden genutzt
PowerOn unterstützt mehrere KI-Anbieter, die je nach Bedarf und Konfiguration eingesetzt werden:
- **OpenAI** (GPT-4o und weitere Modelle)
- **Anthropic** (Claude-Modelle)
- **Tavily** (Websuche)
- **Private LLM** (lokale/eigene Modelle -- kein externer Datenabfluss)
Die Auswahl des Anbieters ist konfigurierbar und kann an die Datenschutzanforderungen des Kunden angepasst werden.
### 7.3 Mandantentrennung bei KI-Anfragen
Jede KI-Anfrage erfolgt im Kontext des jeweiligen Mandanten. Es findet keine Vermischung von Daten verschiedener Mandanten in KI-Anfragen statt.
### 7.4 Kein Training mit Kundendaten
Bei Nutzung der Enterprise-API-Vereinbarungen der KI-Anbieter (OpenAI Enterprise API, Anthropic API) werden Kundendaten nicht für das Training der KI-Modelle verwendet. Dies ist vertraglich durch die Auftragsverarbeitungsvereinbarungen (AV-V / DPA) mit den jeweiligen Anbietern abgesichert.
### 7.5 Optionen für höchste Datenschutzanforderungen
Für Organisationen mit besonders hohen Datenschutzanforderungen bietet PowerOn:
- **Datenschutz-Neutralisierer:** Optionales Modul, das personenbezogene Daten vor der Übermittlung an externe KI-Dienste entfernt oder pseudonymisiert.
- **Private-LLM-Anbindung:** Möglichkeit, ein eigenes, lokal betriebenes Sprachmodell zu nutzen. In diesem Fall verlassen keine Daten die eigene Infrastruktur.
### 7.6 Bekannte Einschränkung
Die automatische Erkennung und Filterung personenbezogener Daten (PII) vor dem Versand an externe KI-Dienste ist **nicht standardmässig aktiviert**. Organisationen, die mit besonders sensiblen personenbezogenen Daten arbeiten, sollten den Datenschutz-Neutralisierer nutzen oder den Private-LLM-Connector einsetzen.
---
## 8. Audit-Trail und Nachvollziehbarkeit
### 8.1 Was wird protokolliert
Sämtliche sicherheitsrelevanten Aktionen werden automatisch und lückenlos in einem Audit-Log erfasst:
| Kategorie | Beispiele |
|---|---|
| Zugriff | Anmeldungen, fehlgeschlagene Anmeldeversuche, Abmeldungen |
| Sicherheit | Administratoraktionen, SysAdmin-Zugriffe, Sicherheitsereignisse |
| Datenschutz (DSGVO) | Datenexporte, Kontolöschungen, Portabilitätsanfragen |
| Berechtigungen | Rollenzuweisungen, Berechtigungsänderungen |
| Verschlüsselung | Zugriffe auf Verschlüsselungsfunktionen |
| Datenoperationen | Zugriffe auf sensible Geschäftsdaten |
### 8.2 Aufbewahrung und Bereinigung
- **Standard-Aufbewahrungsdauer:** 365 Tage (konfigurierbar)
- **Automatische Bereinigung:** Veraltete Einträge werden durch einen täglichen Prozess entfernt -- dies stellt sicher, dass Audit-Daten nicht unbefristet aufbewahrt werden (DSGVO-Konformität).
- **Anonymisierung:** Bei der Löschung eines Nutzerkontos werden zugehörige Audit-Einträge anonymisiert statt gelöscht. Die Nachvollziehbarkeit sicherheitsrelevanter Ereignisse bleibt gewahrt, ohne dass Rückschlüsse auf die gelöschte Person möglich sind.
### 8.3 Nutzung für Compliance-Nachweise
Die Audit-Daten können als Nachweis für interne und externe Audits herangezogen werden. Sie dokumentieren, wer wann welche sicherheitsrelevante Aktion durchgeführt hat, und unterstützen damit die Anforderungen an die Rechenschaftspflicht nach Art. 5 Abs. 2 DSGVO.
---
## 9. Einordnung in gängige Standards
PowerOn orientiert sich an anerkannten Standards und Rahmenwerken. Die folgende Einordnung beschreibt transparent, welche Anforderungen die Plattform bereits abdeckt und wo Ergänzungen erforderlich sind.
### 9.1 DSGVO / GDPR
| Anforderung | Status | Bemerkung |
|---|---|---|
| Betroffenenrechte (Art. 15--17, 20) | Implementiert | Auskunft, Löschung, Portabilität, Berichtigung als Self-Service |
| Rechenschaftspflicht (Art. 5 Abs. 2) | Implementiert | Lückenloser Audit-Trail |
| Verzeichnis der Verarbeitungstätigkeiten (Art. 30) | Unterstützt | Audit-Log liefert die Datenbasis; das formale Verzeichnis muss vom Betreiber geführt werden |
| Technische und organisatorische Massnahmen (Art. 32) | Implementiert | Verschlüsselung, Zugriffskontrolle, Mandantentrennung, Eingabevalidierung |
| Einwilligungsmanagement (Art. 7) | Teilweise | Über Nutzungsbedingungen und OAuth; kein granulares Consent-Tool |
### 9.2 Schweizer Datenschutzgesetz (nDSG / revDSG)
Die Anforderungen des revidierten Schweizer Datenschutzgesetzes sind mit den DSGVO-Massnahmen kompatibel. Insbesondere:
- Informationspflicht bei Datenerhebung: Transparenzfunktion implementiert
- Recht auf Datenherausgabe und -löschung: Self-Service-Funktionen vorhanden
- Pflicht zu angemessenen technischen Massnahmen: Verschlüsselung, RBAC, Mandantentrennung
### 9.3 OWASP Top 10
Die Plattform adressiert die häufigsten Web-Sicherheitsrisiken gemäss OWASP:
| OWASP-Risiko | Massnahme in PowerOn |
|---|---|
| Broken Access Control | Rollenbasierte Zugriffskontrolle, Mandantenprüfung bei jedem Zugriff |
| Cryptographic Failures | AES-Verschlüsselung, PBKDF2-Schlüsselableitung, HTTPS/TLS |
| Injection | Parametrisierte Datenbankabfragen, Eingabebereinigung, SQL-Leseeinschränkung |
| Security Misconfiguration | CORS-Einschränkungen, Rate Limiting, CSRF-Schutz |
| Identification and Authentication Failures | JWT-basierte Authentifizierung, Token-Widerruf, Ratenbegrenzung bei Anmeldung |
Es besteht **keine formale OWASP-Zertifizierung**. Die Massnahmen basieren auf den OWASP-Empfehlungen und sind als präventive Sicherheitsmassnahmen implementiert.
### 9.4 ISO 27001 / BSI IT-Grundschutz
Die implementierten technischen und organisatorischen Massnahmen (Zugriffskontrolle, Verschlüsselung, Audit-Logging, Eingabevalidierung, Mandantentrennung) bilden eine **solide Grundlage** für ein Informationssicherheits-Managementsystem (ISMS) nach ISO 27001 oder BSI IT-Grundschutz.
Es besteht **keine formale Zertifizierung**. Die vorhandene Infrastruktur ermöglicht es jedoch, eine Zertifizierung auf dieser Basis gezielt anzustreben.
---
## 10. Authentifizierung und Identitätsmanagement
### 10.1 Anmeldemethoden
PowerOn unterstützt mehrere Authentifizierungsverfahren:
- **Lokale Anmeldung:** Benutzername und Passwort mit JWT-basierter Sitzungsverwaltung
- **Microsoft-Anmeldung (Azure AD / Entra ID):** Single Sign-On über bestehende Microsoft-Konten
- **Google-Anmeldung:** Single Sign-On über Google Workspace
### 10.2 Sitzungssicherheit
- Authentifizierungstoken werden in sicheren, HTTP-only Cookies gespeichert (nicht im Browser-Speicher zugänglich)
- Tokens haben eine konfigurierbare Gültigkeitsdauer
- Token-Widerruf ist jederzeit möglich (z.B. bei Verdacht auf Kompromittierung)
- Bei lokaler Anmeldung wird die Gültigkeit des Tokens zusätzlich gegen die Datenbank geprüft
### 10.3 Automatische Token-Erneuerung
Authentifizierungstoken werden automatisch erneuert, bevor sie ablaufen. Dies gewährleistet eine unterbrechungsfreie Nutzung bei gleichzeitiger Begrenzung der Token-Gültigkeitsdauer.
---
## 11. Offene Punkte und Empfehlungen
Transparenz schafft Vertrauen. Die folgenden Punkte sind offen benannt, damit Kunden und Betreiber informierte Entscheidungen treffen können.
| Thema | Status | Empfehlung |
|---|---|---|
| Granulares Consent-Management | Nicht vorhanden | Falls regulatorisch erforderlich, als separates Modul ergänzen |
| PII-Filterung vor KI-Versand | Nicht standardmässig aktiv | Datenschutz-Neutralisierer aktivieren oder Private LLM einsetzen |
| Security-Header (CSP, HSTS) | Auf Infrastruktur-Ebene | Konfiguration auf Reverse-Proxy-Ebene dokumentieren und prüfen |
| Datenschutz-Kontaktadresse | Platzhalter | Pro Deployment mit tatsächlicher DSB-Kontaktadresse konfigurieren |
| Formale Zertifizierungen | Keine vorhanden | ISO 27001 / BSI auf Basis der vorhandenen Massnahmen anstrebbar |
---
## 12. Zusammenfassung
PowerOn vereint Enterprise-KI-Funktionalität mit einem umfassenden Sicherheits- und Datenschutzkonzept. Die Plattform bietet:
- **DSGVO-konforme Betroffenenrechte** als Self-Service-Funktionen
- **Vollständige Mandantentrennung** mit serverseitiger Zugehörigkeitsprüfung
- **Feingliedriges Berechtigungssystem** mit individuell konfigurierbaren Rollen
- **Verschlüsselung nach Industriestandard** für ruhende und übertragene Daten
- **Lückenlosen Audit-Trail** für Compliance-Nachweise
- **Transparente KI-Datenverarbeitung** mit Optionen für höchste Datenschutzanforderungen
Gleichzeitig werden bestehende Einschränkungen offen kommuniziert und Empfehlungen für ergänzende Massnahmen gegeben. Diese Kombination aus implementierter Sicherheit und transparenter Kommunikation bildet die Grundlage für eine vertrauensvolle Zusammenarbeit.
---
*Dieses Dokument basiert auf einer Analyse der PowerOn-Plattform (Stand Februar 2026). Alle beschriebenen Massnahmen sind in der Plattform implementiert und wurden anhand der Codebasis verifiziert. Angaben ohne Gewähr -- für verbindliche Zusicherungen gelten die jeweiligen Vertragsvereinbarungen.*