Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
# Branding-Umstellung auf Certvia — Inventar & Umsetzung
|
||||
|
||||
> Branch `dev-branding-certvia` (Basis `dev`) · Quelle: `Aufgabenpaket-Branding-Certvia.md` + `Certvia-Assets/`
|
||||
> Leitplanke: **GEFIM bleibt Dachmarke** („Ein Produkt von GEFIM"), nur die **Produktmarke** wird Certvia.
|
||||
> Reines Branding — **keine Funktionsänderung**, kein Umbau von Logik oder Datenmodell.
|
||||
|
||||
---
|
||||
|
||||
## 1. Design-Tokens (verbindliche Referenz)
|
||||
|
||||
**Markenfarben** (Logo, Print, Verläufe — `--brand-*`):
|
||||
|
||||
| Rolle | Token | Hex |
|
||||
|---|---|---|
|
||||
| Violett (Marke) | `--brand-violet` | `#5d52a3` |
|
||||
| Magenta (Akzent „via", Haken) | `--brand-magenta` | `#812d80` |
|
||||
| Hellblau | `--brand-blue` | `#8dc4e0` |
|
||||
| Anthrazit (Text/Headlines) | `--brand-anthracite` | `#3b3b3a` |
|
||||
| Violett auf Dunkel | `--brand-violet-on-dark` | `#7d6fd6` |
|
||||
| Magenta auf Dunkel | `--brand-magenta-on-dark` | `#d17bcf` |
|
||||
|
||||
**UI Dark-Theme** (unverändert — **ist** die Certvia-Produktpalette, nicht „korrigieren"):
|
||||
`--ui-primary #7d6fd6` · `--ui-primary-deep #5d52a3` · `--ui-blue #8dc4e0` · `--ui-magenta #b45bb0` ·
|
||||
`--bg-0 #0e1220` · `--bg-1 #141a2e` · `--elevated #1a2138` · `--panel rgba(30,38,64,.72)` ·
|
||||
`--panel-brd rgba(120,135,180,.18)` · `--foreground #e8ecf7` · `--muted-foreground #8b93ad` ·
|
||||
`--ok #39c07f` · `--warn #f0ad4e` · `--risk #ff6b6b` · Primär-Verlauf `linear-gradient(135deg,#5d52a3,#7d6fd6)`
|
||||
· Fokus-Ring `rgba(125,111,214,.35)`.
|
||||
|
||||
Single Source of Truth: **`src/app/globals.css`** (CSS) und **`src/lib/brand.ts`** (JS/TS — für alles,
|
||||
was CSS-Variablen nicht auflösen kann: Canvas-/PNG-Export, Metadaten, künftige Dokument-Exporte).
|
||||
|
||||
**Typografie:** Headlines/Wortmarke **Poppins**, Fließtext **Open Sans** — self-hosted (`src/app/fonts/`).
|
||||
|
||||
---
|
||||
|
||||
## 2. Inventar (Story S0)
|
||||
|
||||
### 2.1 Produktmarke → Certvia
|
||||
|
||||
| Datei | Fundstelle | Maßnahme | Story |
|
||||
|---|---|---|---|
|
||||
| `src/app/globals.css` | `--gefim-violet/-deep/-blue/-magenta`, Kommentare „GEFIM-Theme" | Umbenannt auf `--brand-*` / `--ui-*`, Kommentare auf Certvia | S1/S9 |
|
||||
| `src/app/globals.css` | Flächenfarben direkt als Hex (`#0e1220`, `#141a2e`, …) | Über `--bg-0`/`--bg-1`/`--elevated` geführt, semantische Tokens referenzieren sie | S1 |
|
||||
| `src/components/risk-modals.tsx` | `bg-[#0e1220]` (Rest-Risiko-Marker, Legende) | → `bg-[var(--bg-0)]` | S1 |
|
||||
| `src/app/(app)/risks/page.tsx` | `bg-[#0e1220]/75`, `hover:bg-[#0e1220]` (Heatmap-Chip) | → Token `--chip-overlay` / `var(--bg-0)` | S1 |
|
||||
| `src/components/dependency-graph.tsx` | `#8dc4e0`, `#ff6b6b`, `#141a2e`, `#0e1220`, `#4a5372`, `#8b93ad` | CSS-Vars wo möglich; PNG-Export nutzt `BRAND.ui` aus `src/lib/brand.ts` (html-to-image löst keine CSS-Vars auf) | S1 |
|
||||
| `public/gefim-logo.png` | Produktlogo in Sidebar + Login | Verschoben nach `public/assets/logo/gefim-logo.png`, dient nur noch der **Dachmarke** | S2 |
|
||||
| `src/app/(app)/layout.tsx` | Sidebar-Logo `/gefim-logo.png`, Alt-Text „GEFIM …" | `<CertviaLogo variant="lockup" theme="dark">` über den Branding-Resolver | S2/S8 |
|
||||
| `src/app/login/page.tsx` | Logo `/gefim-logo.png`, Alt-Text | Certvia-Lockup + Tagline + Dachmarken-Fußnote | S2/S7 |
|
||||
| `src/app/platform/login/page.tsx` | kein Logo | Certvia-Lockup + „Plattform-Administration" | S2/S7 |
|
||||
| `src/app/(platform)/layout.tsx` | `ShieldCheck` + „ISMS · Plattform-Administration" | Certvia-Mark + „Certvia · Plattform-Administration" | S2/S3 |
|
||||
| `src/app/layout.tsx` | `title: "ISMS-Tool"`, keine Icons/OG/Manifest | Vollständige Certvia-Metadaten inkl. Icons, Manifest, `themeColor` | S3 |
|
||||
| `src/app/favicon.ico` | Next-Default-Favicon | Entfernt; Icons laufen über `public/favicon/` + `metadata.icons` | S2 |
|
||||
| `messages/de.json`, `messages/en.json` | `common.appName` = „ISMS-Tool"/„ISMS Tool" | → „Certvia" (+ `appTagline`, `appByline`) | S3 |
|
||||
| `src/server/mfa.ts` | TOTP-Issuer `"ISMS-Tool · Plattform"` | → `"Certvia · Plattform"` | S3 |
|
||||
| `src/components/ui/button.tsx` | Kommentar „GEFIM-Verlauf" | → „Certvia-Verlauf" | S9 |
|
||||
| `src/components/mockup-ui.tsx` | Kommentar-Referenz auf Mockup-Datei | Formulierung entschärft (Dateiname bleibt, s. u.) | S9 |
|
||||
| `src/lib/control-titles.ts` | Kommentar „aus dem GEFIM-Mockup übernommen" | → neutral „aus dem UI-Mockup" | S9 |
|
||||
| `src/app/(app)/settings/page.tsx` | Hinweis „Logo-Upload folgt in Phase 2" | Ergänzt um Certvia-Default-Aussage | S8 |
|
||||
| `src/proxy.ts` | Matcher schloss `.webmanifest` nicht aus | `/site.webmanifest` lieferte die Login-HTML statt JSON → Endung ergänzt (siehe §5) | S3 |
|
||||
|
||||
### 2.2 Dachmarke GEFIM → bleibt bewusst erhalten
|
||||
|
||||
| Ort | Grund |
|
||||
|---|---|
|
||||
| `public/assets/logo/gefim-logo.png` | Dachmarken-Logo für „Ein Produkt von GEFIM" |
|
||||
| `src/components/brand/powered-by-gefim.tsx` | Neue Komponente, die genau diesen Hinweis rendert (Login, Plattform-Login, Print-/Export-Fußzeile, Mail-Footer) |
|
||||
| `docs/ISMS-*-GEFIM.html`, Verweise in `README.md`/`AGENTS.md`/`docs/SPEC.md` | Historische Mockups/Spezifikation — Projektartefakte, keine Produkt-UI |
|
||||
| `prisma/seed.ts` (`ORG_NAME` „GEFIM Demo GmbH") | **Demo-Mandantendaten** (fiktiver Kunde), nicht der Produktname |
|
||||
| `prisma/import-managed.ts` (`portal.gefim.example`) | Demo-Registerzeile, nicht der Produktname |
|
||||
|
||||
Nach der Umstellung liefert `rg -i "gefim"` ausschließlich diese Kategorien.
|
||||
|
||||
---
|
||||
|
||||
## 3. Umgesetzte Stories
|
||||
|
||||
| Story | Inhalt | Status |
|
||||
|---|---|---|
|
||||
| **S0** | Inventar (dieses Dokument) | ✅ |
|
||||
| **S1** | Token-Zentralisierung `--brand-*` / `--ui-*`, `src/lib/brand.ts`, hartkodierte Farben ersetzt | ✅ |
|
||||
| **S2** | Assets eingebunden, `<CertviaLogo>`, Favicon/PWA-Icons, Sidebar + beide Logins | ✅ |
|
||||
| **S3** | App-Name/Meta/OG/Manifest/i18n/MFA-Issuer auf Certvia | ✅ |
|
||||
| **S4** | Poppins + Open Sans self-hosted bestätigt (waren es bereits), Fallback-Stack + `swap` geprüft | ✅ |
|
||||
| **S7** | Login, Plattform-Login, Change-Password, Enroll-MFA, Konto-deaktiviert, 404, 500 gebranded | ✅ |
|
||||
| **S9** | Produkt-Referenzen bereinigt, Dachmarke belassen | ✅ |
|
||||
| **S5** | Branding-Layer für Dokument-/Export-CD (`src/lib/brand.ts` + Print-Stylesheet) | ✅ (Andockpunkt) |
|
||||
| **S8** | Branding-Resolver mit Certvia-Default, Custom überschreibt nur wenn gesetzt | ✅ |
|
||||
| **S6** | Brandfähige E-Mail-Template-Basis (SMTP selbst folgt in Paket 4) | ✅ (Basis) |
|
||||
|
||||
---
|
||||
|
||||
## 4. Wo liegt was (neu)
|
||||
|
||||
| Pfad | Inhalt |
|
||||
|---|---|
|
||||
| `src/lib/brand.ts` | Marken-/UI-Farben als JS-Konstanten, Produktname/Tagline/Byline, Asset-Pfade, `resolveTenantBranding()` |
|
||||
| `src/lib/document-brand.ts` | Dokument-CD (helles Theme, Kopf-/Fußzeilen-Bausteine) — Andockpunkt für DOCX/PDF |
|
||||
| `src/lib/email-brand.ts` | Brandfähige HTML-/Text-Mail-Basis für Paket 4 |
|
||||
| `src/components/brand/certvia-logo.tsx` | `<CertviaLogo variant="lockup\|mark" theme="light\|dark" />` als Inline-SVG |
|
||||
| `src/components/brand/tenant-brand.tsx` | Mandanten-Marke mit Certvia-Fallback |
|
||||
| `src/components/brand/powered-by-gefim.tsx` | Dachmarken-Hinweis inkl. GEFIM-Logo |
|
||||
| `public/assets/logo/` | Certvia-SVGs/PNGs + GEFIM-Dachmarkenlogo |
|
||||
| `public/favicon/`, `public/favicon.ico`, `public/site.webmanifest` | App-Icons und PWA-Manifest |
|
||||
| `docs/branding/` | Aufgabenpaket + Logo-README aus dem Design-Paket |
|
||||
| `src/app/globals.css` (`@media print`) | Druck-/Dokument-CD |
|
||||
|
||||
---
|
||||
|
||||
## 5. Beim Einbau aufgefallen (Abweichungen vom Aufgabenpaket)
|
||||
|
||||
- **Lockup-SVG trägt Poppins jetzt eingebettet.** `public/assets/logo/certvia-lockup-positiv.svg`
|
||||
enthält Poppins 300 + 700 als woff2-Data-URI (≈22 KB). Damit erscheint die Wortmarke auch
|
||||
außerhalb der App korrekt (Druck, Export, Mail) — der offene Punkt „Text in Pfade wandeln" aus
|
||||
`docs/branding/README-Logo.md` ist damit erledigt. Geometrie und Farben sind unverändert.
|
||||
In der App rendert `<CertviaLogo>` das Zeichen ohnehin inline und nutzt die App-Schrift direkt.
|
||||
- **`/site.webmanifest` war nicht erreichbar.** Der Route-Gate-Matcher in `src/proxy.ts` nahm nur
|
||||
`svg|png|jpg|ico` aus — für `.webmanifest` lieferte der Server die Login-Seite statt JSON, das
|
||||
PWA-Manifest wäre also wirkungslos geblieben. Endung ergänzt. Bewusst **keine** Verzeichnis-
|
||||
Ausnahme für `assets/`: das ist zugleich die App-Route des Asset-Inventars und bleibt hinter dem
|
||||
Gate (nachgeprüft: `/assets`, `/assets/xyz` → 307 auf `/login`).
|
||||
- **`src/app/favicon.ico` entfernt.** Die Datei-Konvention von Next.js und eine `public/favicon.ico`
|
||||
schließen sich gegenseitig aus; die Icons laufen jetzt vollständig über `metadata.icons`.
|
||||
- **404-/500-Seiten neu angelegt** (`src/app/not-found.tsx`, `src/app/error.tsx`) — es gab bisher
|
||||
keine. Sie erscheinen für angemeldete Nutzer; anonyme Aufrufe fängt weiterhin das Login-Gate ab.
|
||||
|
||||
### Kontrast (WCAG AA, geprüft)
|
||||
|
||||
| Kombination | Kontrast | Bewertung |
|
||||
|---|---|---|
|
||||
| Magenta `#812d80` auf Weiß (Wortmarke/Print) | 8,0 : 1 | AA + AAA |
|
||||
| Magenta `#d17bcf` auf Karte `#141a2e` | 6,1 : 1 | AA |
|
||||
| Magenta `#d17bcf` auf Seitengrund `#0e1220` | 6,6 : 1 | AA |
|
||||
|
||||
---
|
||||
|
||||
## 6. Bewusste Abgrenzungen
|
||||
|
||||
- **UI-Palette unverändert.** Die Dark-Theme-Farben wurden nur konsolidiert/umbenannt, nicht geändert.
|
||||
`--brand-violet` (`#5d52a3`) gilt für Logo/Print/Verläufe, `--ui-primary` (`#7d6fd6`) für Interaktion.
|
||||
- **Kein Light-Mode.** Die App ist bewusst dark-only; `<CertviaLogo theme="light">` existiert für
|
||||
Dokument-/Druck-/Mail-Kontexte, wird in der UI aber nicht verwendet.
|
||||
- **Poppins 400** ist nicht als woff2 im Repo (vorhanden: 300/500/600/700). Aktuell nutzt nichts
|
||||
Poppins 400 — Headlines laufen auf 600/700, die Wortmarke auf 300/700. Sollte 400 gebraucht werden,
|
||||
muss die woff2 ergänzt werden; ein CDN-Fetch bleibt ausgeschlossen.
|
||||
- **Logo-Upload je Mandant** braucht Objektspeicher (Admin Phase 2). Der Resolver ist bereits darauf
|
||||
vorbereitet (`logoUrl` optional), das Feld existiert im Schema noch nicht — bewusst keine Migration.
|
||||
- **DOCX/PDF-Export** existiert noch nicht. S5 liefert den Branding-Layer (Konstanten + Kopf-/Fußzeile
|
||||
+ Print-CSS), an den das Export-Feature andockt.
|
||||
@@ -0,0 +1,123 @@
|
||||
# Deployment: Testserver via Coolify (intern)
|
||||
|
||||
> Zielumgebung: interner Coolify-Host (`192.168.1.207`), Docker-Compose-Stack,
|
||||
> HTTP über eine `*.sslip.io`-Domain (kein öffentliches TLS).
|
||||
> Ergänzt `docs/HANDOVER-DEVOPS.md`. Deploy-Datei: `docker-compose.coolify.yml`.
|
||||
|
||||
## Architekturüberblick (Coolify)
|
||||
|
||||
- Coolify deployt den **Compose-Stack** aus diesem Repo und übernimmt **Reverse-Proxy + Routing** — die App wird **nicht** per Host-Port exponiert.
|
||||
- Services: `migrate` (Init-Job) → `app` (Next.js standalone) + `postgres` (pgvector), `redis`, `garage` (Objektspeicher) + `garage-provision` (Init-Job).
|
||||
- **Migrationen** laufen als eigener Init-Job `migrate` (`prisma migrate deploy`, schlanke **`migrate`-Stage** ohne `next build`) **vor** `app` — der App-Container migriert selbst nicht.
|
||||
- **Objektspeicher Garage** (ersetzt MinIO, Community EOL): S3-kompatibel, Single-Node. Buckets/Keys legt NICHT die S3-API an, sondern der Init-Job `garage-provision` (Admin-API, idempotent) **vor** `app`. Details/Cutover: eigener Abschnitt unten.
|
||||
- **Redis** läuft mit `requirepass` (F-18): `REDIS_PASSWORD` als Coolify-Env setzen und in die `REDIS_URL` einsetzen (`redis://:<pw>@redis:6379`).
|
||||
- **Netzsegmentierung** (F-18): `postgres`/`redis`/`garage`/`migrate` liegen im internen Netz (`internal: true`, kein Egress); nur `app` ist zusätzlich im default-Netz (Coolify-Proxy). Garage wird nicht per Traefik/Host-Port exponiert.
|
||||
- **Secrets/Config** kommen aus den **Coolify-Env-Variablen** (Referenz: `.env.coolify.example`), nicht aus einer committeten `.env`.
|
||||
|
||||
## 1. Gitea mit Coolify verbinden (Deploy Key)
|
||||
|
||||
SSH ist erreichbar (`git@…sslip.io:22`), daher Deploy-Key:
|
||||
|
||||
1. **Coolify → Keys & Tokens → Private Keys**: SSH-Key generieren (oder beim Anlegen der Ressource „Private Repository (deploy key)“ automatisch). Öffentlichen Key kopieren.
|
||||
2. **Gitea → Repo `msolarczek/ISMS-Tool` → Settings → Deploy Keys → Add Deploy Key**: Key einfügen, nur Lesezugriff.
|
||||
3. Repo-URL in Coolify (SSH):
|
||||
`git@gitea-vkbhbn2qdkz5ppk9q4qgb0tn.192.168.1.207.sslip.io:msolarczek/ISMS-Tool.git`
|
||||
|
||||
## 2. Ressource anlegen
|
||||
|
||||
1. Projekt/Environment wählen → **+ New → Private Repository (deploy key)**.
|
||||
2. Repo `ISMS-Tool`, **Branch `devops/coolify-testserver`** (nach erfolgreichem Test → `main`).
|
||||
3. **Build Pack: Docker Compose**, **Compose Location: `docker-compose.coolify.yml`**.
|
||||
|
||||
## 3. Environment-Variablen
|
||||
|
||||
Werte aus `.env.coolify.example` in Coolify eintragen. Kritisch:
|
||||
|
||||
- Hostnamen = Compose-Service-Namen: `postgres`, `redis`, `garage` (nicht `localhost`); `S3_ENDPOINT=http://garage:3900`.
|
||||
- `AUTH_SECRET` frisch: `openssl rand -base64 32`.
|
||||
- `AUTH_URL` = exakt die in Schritt 4 vergebene App-Domain (`http://…`).
|
||||
- **Garage** (siehe Abschnitt unten): `GARAGE_RPC_SECRET` + `GARAGE_ADMIN_TOKEN` (je `openssl rand -hex 32`), sowie `S3_ACCESS_KEY` = `GK`+24 Hex (`echo "GK$(openssl rand -hex 12)"`) und `S3_SECRET_KEY` = `openssl rand -hex 32`. Alle **literal** setzen (nicht via `${…}` — Coolify-Interpolationsfalle).
|
||||
|
||||
## 4. Domain & HTTP
|
||||
|
||||
- Beim Service `app` unter **Domains** die `*.sslip.io`-Domain übernehmen, Schema **`http://`**.
|
||||
- Dieselbe Domain als `AUTH_URL` setzen (sonst schlägt der NextAuth-Login fehl).
|
||||
|
||||
## 5. Persistenz
|
||||
|
||||
Named Volumes müssen als Persistent Storage erkannt sein — v. a. **`pgdata`** (sonst Datenverlust bei Redeploy) und **`garage_meta`** (Bucket-/Key-/Layout-Definitionen — ohne meta sind die Objektdaten in `garage_data` nicht adressierbar). Ebenso `garage_data`, `redisdata`, `backups`. **`garage_meta` in die Host-Backup-Strategie aufnehmen** (analog `pgdata`).
|
||||
|
||||
## 6. Deploy
|
||||
|
||||
**Deploy** starten. Reihenfolge: `postgres` (healthy) → `migrate` (läuft einmalig durch) → `app` (startet erst nach erfolgreichem Migrate). Logs von `migrate`/`app` bei Fehlern prüfen.
|
||||
|
||||
## 7. Demo-Admin anlegen (einmalig, Testserver)
|
||||
|
||||
Der Demo-Seed läuft nicht automatisch. Im Coolify-**Terminal** des `migrate`-Containers (builder-Image, hat `tsx`):
|
||||
|
||||
```
|
||||
npx tsx prisma/seed.ts
|
||||
```
|
||||
|
||||
Login danach: `admin@demo.example` / `Demo1234!`.
|
||||
|
||||
> Produktiv: **kein** Demo-Seed. Stattdessen einmaliger Bootstrap des Plattform-Admins
|
||||
> (`provisionTenant({ admin.isPlatformAdmin: true })`) — Skript noch zu erstellen
|
||||
> (siehe `docs/HANDOVER-DEVOPS.md` §4).
|
||||
|
||||
## 8. Smoke-Test
|
||||
|
||||
Über die App-Domain: Login, Admin-Konsole, eine Modul-Seite.
|
||||
|
||||
## Redeploy / Migrationen-Nachziehen
|
||||
|
||||
Jeder Coolify-Redeploy baut neu und lässt `migrate` erneut laufen (`migrate deploy` ist idempotent — nur neue Migrationen werden angewandt). App startet erst nach erfolgreichem Migrate.
|
||||
|
||||
## Von Test zu Produktiv (Delta)
|
||||
|
||||
- `AUTH_SECRET`, DB-Passwörter und die **Garage-Secrets** (`GARAGE_RPC_SECRET`, `GARAGE_ADMIN_TOKEN`, `S3_ACCESS_KEY`/`S3_SECRET_KEY`) neu/aus Secret-Store; eigene Domain + gültiges TLS.
|
||||
- **Kein** Demo-Seed; Erst-Superadmin per Bootstrap-Skript.
|
||||
- Backups (`pg_dump`/Volume-Snapshots inkl. **`garage_meta`**) + Restore-Test, Monitoring/Alerting.
|
||||
- Ggf. ≥ 2 `app`-Replicas hinter dem Coolify-Proxy.
|
||||
|
||||
## Objektspeicher (Garage) — Cutover, Provisioning & Rollback
|
||||
|
||||
Ablösung von MinIO (Community EOL) durch **Garage** (S3-kompatibel, aktiv gepflegt,
|
||||
Single-Node). Konzept: `docs/KONZEPT-garage-migration.md`. Es gibt **keine produktiven
|
||||
Daten** → **Neu-Deploy statt Datenmigration** (kein rclone, kein Wartungsfenster).
|
||||
|
||||
**Konfig-Bausteine**
|
||||
- `deploy/garage.toml` (eingecheckt, **secret-frei**): `replication_factor=1`,
|
||||
`s3_region=us-east-1`, S3-API `:3900`, Admin-API `:3903`. `rpc_secret`/`admin_token`
|
||||
liest der Daemon aus der Env (`GARAGE_RPC_SECRET`/`GARAGE_ADMIN_TOKEN`).
|
||||
- Volumes: `garage_meta` (**kritisch**, ins Host-Backup) + `garage_data`.
|
||||
- Init-Job `garage-provision` (`scripts/garage-provision.ts`, Admin-API, **idempotent**):
|
||||
Layout → Bucket `isms-documents` → Access-Key **importieren** (aus `S3_ACCESS_KEY/…`)
|
||||
→ Rechte read/write. Läuft bei jedem Deploy; „already exists“ = Erfolg. Ohne
|
||||
`GARAGE_ADMIN_TOKEN` No-op. Loggt **keine** Secrets.
|
||||
|
||||
**Cutover-Runbook (Test-Instanz)**
|
||||
1. Compose enthält bereits `garage` + `garage-provision`; der alte `minio`-Service ist
|
||||
auskommentiert (Rollback-Netz) und wird erst nach Abnahme entfernt.
|
||||
2. Coolify-Env **literal** setzen (nicht `${…}`): `S3_ENDPOINT=http://garage:3900`,
|
||||
`S3_REGION=us-east-1`, `S3_BUCKET=isms-documents`, `GARAGE_RPC_SECRET`,
|
||||
`GARAGE_ADMIN_TOKEN`, `S3_ACCESS_KEY` (`GK`+24 Hex), `S3_SECRET_KEY` (64 Hex).
|
||||
3. Deploy. Reihenfolge: `garage` (healthy: `/garage status`) → `garage-provision`
|
||||
(legt Layout/Bucket/Key/Rechte an) → `app`. Optionaler DB-Reset nur, falls alte
|
||||
Objekt-Referenzen stören (bei frischer/geseedeter Instanz unnötig).
|
||||
4. Abnahme (§ KONZEPT §9): Upload → Download (`/files/[...key]`) → Backup-Export `.cvb`
|
||||
+ Download → DSGVO-ZIP → Restore mit Mandanten-Isolation → Backup-Historie List/
|
||||
Aufräumen → Negativfall „fehlender Bucket“ = sprechender Fehler.
|
||||
5. **`garage_meta`** in der Host-Backup-Strategie bestätigen. Erst danach den
|
||||
`minio`-Block **und** das Volume `miniodata` aus `docker-compose.coolify.yml` entfernen.
|
||||
|
||||
**Rollback** (unkritisch, keine Prod-Daten): `garage`/`garage-provision` wieder aus-,
|
||||
den auskommentierten `minio`-Block wieder einkommentieren und die alten `S3_*`/
|
||||
`MINIO_*`-Env setzen; neu deployen. Solange `minio` + `miniodata` noch existieren, ist
|
||||
das ein reiner Compose-/Env-Wechsel.
|
||||
|
||||
**Provisioning erneut anstoßen / debuggen**: Im Coolify-Terminal eines Containers mit
|
||||
`tsx` (`migrate`-Image) `npx tsx scripts/garage-provision.ts` erneut laufen lassen
|
||||
(idempotent). „Container weg ohne Logs“ (Coolify entfernt fehlgeschlagene Container
|
||||
sofort): Provisioning-Ausgabe zusätzlich in eine Datei spiegeln, z. B.
|
||||
`npx tsx scripts/garage-provision.ts 2>&1 | tee /tmp/garage-provision.log`.
|
||||
@@ -0,0 +1,485 @@
|
||||
# Deployment: Produktivserver (Contabo-VPS via Coolify)
|
||||
|
||||
> Zielumgebung: öffentlicher Contabo-VPS, eigene Coolify-Instanz, Git (Gitea) auf
|
||||
> demselben VPS, Domain **app.certvia.de** mit echtem Let's-Encrypt-TLS.
|
||||
> Ergänzt `docs/DEPLOY-COOLIFY.md` (Testserver). Deploy-Datei: `docker-compose.coolify.yml`.
|
||||
|
||||
## Unterschiede zum Testserver
|
||||
|
||||
| Aspekt | Test (intern) | Produktiv (Contabo) |
|
||||
|--------|---------------|---------------------|
|
||||
| Erreichbarkeit | intern, HTTP, sslip.io | öffentlich, **HTTPS**, `app.certvia.de` |
|
||||
| Git-Quelle | internes Gitea | **Gitea auf dem VPS** (Release-Push) |
|
||||
| Erst-Admin | Demo-Seed (`RUN_DEMO_SEED=true`) | **Bootstrap-Admin** (`BOOTSTRAP_ADMIN=true`), **kein** Demo-Seed |
|
||||
| Secrets | Testwerte | **frische, starke** Secrets |
|
||||
| Backups | optional | **Pflicht** (pg_dump + Restore-Test) |
|
||||
| Branch | `dev` | `main` |
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — VPS-Grundlage
|
||||
|
||||
1. **Contabo-VPS** bereitstellen — **≥ 8 GB RAM** empfohlen (Next-Build ~1 GB + Stack). Bei weniger RAM zwingend Swap:
|
||||
```bash
|
||||
fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
|
||||
echo '/swapfile none swap sw 0 0' >> /etc/fstab
|
||||
free -h
|
||||
```
|
||||
2. **Grundhärtung**: System aktualisieren, SSH-Key-Login (Passwort-Login aus), unattended-upgrades.
|
||||
3. **Firewall** (ufw): nur benötigte Ports offen — `80`, `443`, SSH, sowie der Gitea-SSH-Port (s. Phase 2).
|
||||
4. **Coolify installieren** (offizielles Installskript) — eigene, unabhängige Instanz.
|
||||
|
||||
## Phase 2 — Gitea auf dem VPS
|
||||
|
||||
5. Gitea als **Coolify-Ressource** (One-Click/Compose) aufsetzen, eigene Subdomain (z. B. `git.certvia.de`), TLS via Coolify.
|
||||
6. Repo `ISMS-Tool` in diesem Gitea anlegen.
|
||||
7. Lokal ein **zweites Remote** hinzufügen und beim Release `main` dorthin pushen:
|
||||
```bash
|
||||
git remote add prod https://git.certvia.de/<org>/ISMS-Tool.git
|
||||
git push prod main
|
||||
```
|
||||
(Das ist der bewusste „Release-Push" — Prod deployt nur, was hier landet.)
|
||||
|
||||
## Phase 3 — DNS & Domain
|
||||
|
||||
8. Bei eurem DNS für `certvia.de` einen **A-Record** `app.certvia.de` → Contabo-IP anlegen (ebenso `git.certvia.de`).
|
||||
9. Coolify vergibt/prüft danach automatisch das Let's-Encrypt-Zertifikat (VPS ist öffentlich erreichbar).
|
||||
|
||||
## Phase 4 — App-Ressource (Prod) in Coolify
|
||||
|
||||
10. **+ New Resource** → Git-Quelle = das **VPS-Gitea** (Deploy-Key), Repo `ISMS-Tool`, **Branch `main`**.
|
||||
11. **Build Pack: Docker Compose**, **Compose Location: `docker-compose.coolify.yml`**.
|
||||
12. **Domain** beim Service `app` = `https://app.certvia.de:3000` (Port 3000), Schema **https**.
|
||||
13. **Environment-Variablen** aus `.env.prod.example` setzen (Runtime-Variablen). Kritisch:
|
||||
- Alle Secrets **frisch** (`AUTH_SECRET` neu: `openssl rand -base64 32`; neue DB-/MinIO-Passwörter).
|
||||
- `AUTH_URL=https://app.certvia.de` (exakt die App-Domain).
|
||||
- `RUN_DEMO_SEED=false` (bzw. weglassen).
|
||||
- **Bootstrap** (erster Deploy): `BOOTSTRAP_ADMIN=true` + `BOOTSTRAP_ADMIN_EMAIL/PASSWORD/NAME` + `BOOTSTRAP_TENANT_NAME/SLUG`.
|
||||
14. **Persistent Storage** prüfen — v. a. `pgdata` (sonst Datenverlust bei Redeploy).
|
||||
|
||||
## Phase 5 — Erster Deploy & Bootstrap
|
||||
|
||||
15. **Deploy**. Ablauf: `postgres` (healthy) → `migrate` (migriert **und** legt via `BOOTSTRAP_ADMIN=true` den Erst-Admin an) → `app`.
|
||||
16. In den **`migrate`-Logs** prüfen: `>> Bootstrap-Admin läuft…` → `✔ Bootstrap fertig: Mandant … + Plattform-Admin … angelegt.`
|
||||
17. **Login** unter `https://app.certvia.de` mit den `BOOTSTRAP_ADMIN_*`-Zugangsdaten → **Passwort sofort ändern**.
|
||||
18. Optional danach `BOOTSTRAP_ADMIN` auf `false` (das Skript ist idempotent, es schadet aber nicht, es an zu lassen).
|
||||
|
||||
## Phase 6 — Backups & Betrieb (vor „echtem" Go-Live)
|
||||
|
||||
19. **Postgres-Backups**: regelmäßiger `pg_dump` (oder Coolify-DB-Backup nach S3) + **Restore-Test** dokumentieren. `pgdata` ist das kritische Volume.
|
||||
20. **MinIO-Backup**, sobald Datei-/Logo-Upload aktiv ist.
|
||||
21. **Monitoring/Alerting**: App-Healthcheck ist im Compose vorhanden; zusätzlich Uptime-Check auf `https://app.certvia.de` und Log-Aggregation einrichten.
|
||||
22. **Updates**: Betriebssystem/Coolify/Images regelmäßig aktualisieren.
|
||||
|
||||
## Phase 7 — Auto-Deploy (optional)
|
||||
|
||||
23. Gitea-Webhook (VPS-Gitea → Coolify) mit **Branch-Filter `main`**. Da Gitea und Coolify auf demselben Host sind, ggf. `GITEA__webhook__ALLOWED_HOST_LIST` weit genug setzen (vgl. Testserver-Erfahrung).
|
||||
|
||||
---
|
||||
|
||||
## Release-Fluss (Zusammenfassung)
|
||||
|
||||
```
|
||||
Feature-Branch → dev # Entwicklung, Auto-Deploy Testserver
|
||||
dev → main # Release-Merge (nach Test-Freigabe)
|
||||
git push prod main # Release-Push ins VPS-Gitea → Prod-Deploy
|
||||
```
|
||||
|
||||
## Row Level Security scharfschalten (F-04)
|
||||
|
||||
Postgres RLS ist als zweite Verteidigungslinie definiert (Policy `tenant_isolation`
|
||||
je Mandanten-Tabelle) und mit der Migration `rls_enforce` unter
|
||||
`FORCE ROW LEVEL SECURITY` + `WITH CHECK` scharf gestellt. Sie wird **env-gesteuert**
|
||||
aktiviert (`RLS_ENFORCED`), Default ist **aus** (Owner-Betrieb wie bisher).
|
||||
|
||||
**Wie es funktioniert:** Bei `RLS_ENFORCED=true` verbindet sich der App-Prozess als
|
||||
eingeschränkte Rolle `isms_app` (NOBYPASSRLS) über `RLS_DATABASE_URL` und setzt
|
||||
`app.tenant_id` transaktionslokal pro Operation. Für diese Rolle greifen die
|
||||
Policies. Migrationen, Seed/Bootstrap und der mandantenübergreifende Login-Lookup
|
||||
laufen weiter über die **Owner-`DATABASE_URL`**.
|
||||
|
||||
**Scharfschalten (einmalig):**
|
||||
|
||||
1. App-Rolle mit LOGIN + starkem Passwort versehen (nur einmal, kein Secret ins Repo):
|
||||
```bash
|
||||
docker exec -it <postgres-container> psql -U isms -d isms \
|
||||
-c "ALTER ROLE isms_app WITH LOGIN PASSWORD '<STARKES_PASSWORT>';"
|
||||
```
|
||||
2. In Coolify die Env-Variablen setzen:
|
||||
- `RLS_ENFORCED=true`
|
||||
- `RLS_DATABASE_URL=postgresql://isms_app:<STARKES_PASSWORT>@postgres:5432/isms?schema=public`
|
||||
3. App-Service neu deployen. Fehlt `RLS_DATABASE_URL` bei aktivem Flag, bricht die
|
||||
App bewusst beim Start ab (fail secure).
|
||||
|
||||
> **Warnung — Owner-Rolle muss BYPASSRLS/Superuser sein.** Die in `DATABASE_URL`
|
||||
> genutzte Owner-/Migrate-Rolle (`isms`) MUSS `BYPASSRLS` bzw. Superuser sein,
|
||||
> sonst sähe der Login (mandantenübergreifend) **keine** Nutzer und Migrationen
|
||||
> könnten fehlschlagen. FORCE ist für diese Rolle unschädlich, weil BYPASSRLS die
|
||||
> RLS auch unter FORCE umgeht.
|
||||
>
|
||||
> **Warnung — ohne Kontext = null Zeilen.** `RLS_ENFORCED=true` NIE ohne korrektes
|
||||
> `RLS_DATABASE_URL` setzen: eine RLS-Rolle ohne gesetzten `app.tenant_id` sieht
|
||||
> gar keine Zeilen. Das Setzen des Kontexts übernimmt `dbForTenant` automatisch.
|
||||
|
||||
Nachweis der Korrektheit lokal: `npx tsx scripts/test-rls-enforcement.ts`.
|
||||
|
||||
## Host-Encryption at-rest — Daten-Volume (`pgdata` + MinIO)
|
||||
|
||||
> Umsetzung der Härtung §2 (`docs/KONZEPT-haertung.md`). **Ops-Runbook, kein App-Code.**
|
||||
> Schützt gegen **physischen Plattendiebstahl / VPS-Decommission** — die Volumes liegen
|
||||
> sonst im Klartext auf der Contabo-Platte (`pgvector`-Community-Postgres hat **kein TDE**).
|
||||
> **Kein** Schutz gegen Live-Kompromittierung des laufenden Servers (dafür greifen
|
||||
> App-Feld-Encryption, RLS, Zugriffskontrollen) — im Betrieb ist das Volume im RAM entschlüsselt.
|
||||
|
||||
**Prinzip:** Ein **LUKS/dm-crypt**-Container (dm-crypt/`cryptsetup`) bzw. ein
|
||||
**provider-verschlüsseltes Block-Volume** trägt das gesamte Daten-Volume. Coolifys
|
||||
Persistent-Storage (`pgdata`, MinIO-Daten, ggf. Redis-AOF) wird auf dieses
|
||||
verschlüsselte Volume gelegt — damit sind `pgdata` **und** MinIO in einem Rutsch gedeckt.
|
||||
|
||||
**Einrichtung (einmalig, vor dem ersten Deploy mit echten Daten):**
|
||||
|
||||
1. Separates Block-Volume/Partition bereitstellen (z. B. `/dev/sdb`) — **nicht** das Root-FS.
|
||||
2. LUKS-Container anlegen und öffnen:
|
||||
```bash
|
||||
cryptsetup luksFormat --type luks2 /dev/sdb # Passphrase vergeben (s. u.)
|
||||
cryptsetup open /dev/sdb cryptdata # -> /dev/mapper/cryptdata
|
||||
mkfs.ext4 /dev/mapper/cryptdata
|
||||
mkdir -p /srv/cryptdata && mount /dev/mapper/cryptdata /srv/cryptdata
|
||||
```
|
||||
3. Coolifys Datenwurzel (bzw. die betroffenen Named-Volumes/Bind-Mounts für `pgdata`
|
||||
und MinIO) auf `/srv/cryptdata/...` legen und die Compose-`volumes` dorthin zeigen lassen.
|
||||
4. **Passphrase / Key-File** ausschließlich im **Org-Passwortmanager** hinterlegen
|
||||
(Eintrag im `docs/SECRETS-REGISTER.md` führen) + versiegelte Offline-Kopie. **Nie** ins Repo,
|
||||
nie ins Backup-Bucket.
|
||||
|
||||
**Boot-Unlock (dokumentierte Entscheidung nötig — Betreiber wählt):**
|
||||
|
||||
- **A) Manuelles Unlock (empfohlen für Einzel-VPS, höchster Schutz):** Nach jedem Reboot
|
||||
meldet sich ein Operator per SSH an und führt `cryptsetup open` + `mount` (bzw. ein
|
||||
`systemd`-Gate vor den Docker-/Coolify-Start) aus. Kein Key auf der Platte → Diebstahl
|
||||
der Platte nützt nichts. Nachteil: **kein unbeaufsichtigter Reboot** (Downtime bis Unlock).
|
||||
- **B) Key-File auf getrenntem Medium / Netz-Unlock:** `crypttab`-Key-File auf einem separaten,
|
||||
nicht mit der Platte gestohlenen Träger, oder **dracut/clevis + Tang** (Network-Bound Disk
|
||||
Encryption) für auto-unlock, solange der Tang-Server erreichbar ist. Komfortabler,
|
||||
aber der Angreifer, der Platte **und** Key/Tang-Zugang hat, gewinnt.
|
||||
|
||||
> **Betreiber-Entscheidung dokumentieren:** A oder B, wer die Passphrase hält, und wie der
|
||||
> Reboot-Ablauf aussieht (Runbook-Schritt „Nach Reboot: Volume entsperren, dann Coolify starten").
|
||||
> Ohne Unlock startet Postgres/MinIO nicht — das ist beabsichtigt (fail-secure).
|
||||
|
||||
## Verschlüsselte Backups — pgBackRest / age / restic
|
||||
|
||||
> Umsetzung der Härtung §3 + Backup-Konzept §9 (`docs/KONZEPT-backup-restore.md`).
|
||||
> **Entscheidung:** **client-seitige AES-256-Verschlüsselung mit einem Schlüssel pro Umgebung**
|
||||
> — das Artefakt ist verschlüsselt, **bevor** es S3/MinIO erreicht (at-rest + in-transit +
|
||||
> zero-knowledge vom Speicher). **Nicht** allein auf Storage-SSE verlassen (SSE gern zusätzlich).
|
||||
> Konsistent zur bestehenden App-Verschlüsselung (TOTP AES-256-GCM, Backup-Export AES-256-GCM).
|
||||
|
||||
**Schichten (je Umgebung getrennte Schlüssel):**
|
||||
|
||||
| Schutzobjekt | Werkzeug | Schlüssel |
|
||||
|---|---|---|
|
||||
| Cluster-Backup (Postgres, WAL/Base) | **pgBackRest** `repo-cipher-type=aes-256-cbc` + `repo-cipher-pass` → S3/MinIO | pgBackRest-Repo-Key je Umgebung |
|
||||
| Per-Tenant-Export + DSGVO-Pakete | **`age`** (X25519, encrypt-then-upload) | `age`-Keypair je Umgebung |
|
||||
| MinIO-Dateien (Uploads/Logos) | **restic** (eingebaute AES-256-Verschlüsselung) | restic-Repo-Passwort je Umgebung |
|
||||
|
||||
**pgBackRest (Beispiel `pgbackrest.conf`, Repo auf MinIO/S3):**
|
||||
```ini
|
||||
[global]
|
||||
repo1-type=s3
|
||||
repo1-s3-endpoint=<minio-oder-s3-endpoint>
|
||||
repo1-s3-bucket=certvia-pgbackrest-prod # eigener Bucket, NICHT der App-Bucket
|
||||
repo1-s3-key=<zugang> # nur Backup-Zugang, getrennt vom App-MinIO-User
|
||||
repo1-s3-key-secret=<zugang-secret>
|
||||
repo1-cipher-type=aes-256-cbc
|
||||
repo1-cipher-pass=<PGBACKREST_REPO_KEY> # aus Passwortmanager, NIE im Bucket
|
||||
repo1-retention-full=4 # Retention: s. u.
|
||||
[certvia]
|
||||
pg1-path=/srv/cryptdata/pgdata
|
||||
```
|
||||
|
||||
**age (Per-Tenant-/DSGVO-Artefakte):**
|
||||
```bash
|
||||
age-keygen -o /root/age-prod.key # Private Key -> Passwortmanager + offline
|
||||
# Public Recipient (age1...) als Env/Config für die Backup-Jobs:
|
||||
age -r age1<recipient-prod> -o export.tenant.age export.tenant.tar
|
||||
```
|
||||
|
||||
**restic (MinIO-Objektdaten):**
|
||||
```bash
|
||||
export RESTIC_REPOSITORY=s3:<endpoint>/certvia-restic-prod
|
||||
export RESTIC_PASSWORD=<RESTIC_REPO_KEY> # aus Passwortmanager
|
||||
restic backup /srv/cryptdata/minio
|
||||
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
|
||||
```
|
||||
|
||||
**Verdrahtung in Coolify / Betrieb:**
|
||||
|
||||
- **Scheduling:** Coolify-**Scheduled Task / Cron** je Job (pgBackRest full+incr, `age`-Export,
|
||||
restic) — Zugangsdaten als Coolify-Env-Secrets, **nicht** im Compose committen.
|
||||
- **Retention je Schicht dokumentieren** (DR-WAL/Base, Per-Tenant-Snapshots, DSGVO-Exporte)
|
||||
und dem **DSB** vorlegen — Löschfristen ergeben sich aus der DSGVO-Aufbewahrung.
|
||||
- **Getrennte Buckets/Zugänge:** Backup-Repos liegen in **eigenen** Buckets mit **eigenem**
|
||||
Zugang, nie im App-MinIO-Bucket und nie zusammen mit den Schlüsseln.
|
||||
- **Restore-Test regelmäßig + dokumentiert** (der Prod-Runbook fordert das bereits für `pgdata`,
|
||||
Phase 6): mindestens quartalsweise eine Wiederherstellung in eine Wegwerf-Umgebung, Ergebnis
|
||||
protokollieren. Ein ungetestetes Backup gilt als kein Backup.
|
||||
|
||||
**Bezug zur App-Backup-Engine:** Der in `dev` integrierte App-Export/Restore verschlüsselt
|
||||
Artefakte bereits **client-seitig mit AES-256-GCM** über `BACKUP_ENC_KEY` (Fallback `AUTH_SECRET`),
|
||||
**ein Key pro Umgebung** (Backup-Konzept §9). Umgebungs-Secrets (Pepper/`MFA_ENC_KEY`/`BACKUP_ENC_KEY`)
|
||||
liegen **nicht** im Artefakt; der Restore setzt Owner=Superuser voraus (`session_replication_role`).
|
||||
pgBackRest/`age`/restic sind die **Ops-Ebene darunter** (Cluster/Host/Objektspeicher) —
|
||||
dieselbe Grundregel „ein Schlüssel pro Umgebung, getrennt vom Artefakt" gilt durchgängig.
|
||||
|
||||
## Schicht A — Cluster-Disaster-Recovery mit PITR (Go-Live-Runbook)
|
||||
|
||||
> Umsetzung Backup-Konzept §2 (`docs/KONZEPT-backup-restore.md`). **Ops-Runbook, kein App-Code.**
|
||||
> Schicht A deckt den **gesamten** Cluster ab — auch die **globalen** Tabellen (`Identity`/
|
||||
> Credentials, Kataloge, `PlatformAdmin`), die die mandanten-scoped App-Engine (Schicht B)
|
||||
> bewusst NICHT anfasst. Zweck: Totalausfall / Ransomware / menschlicher Massenfehler →
|
||||
> „DB auf Zeitpunkt T" (Point-in-Time-Recovery).
|
||||
|
||||
**Bausteine:** **pgBackRest** (empfohlen) oder **wal-g** — periodisches **Voll-/Inkrement-Backup**
|
||||
plus kontinuierliches **WAL-Archiving** nach S3/MinIO, verschlüsselt (`repo-cipher`). Erst das
|
||||
WAL-Archiv macht PITR möglich (Replay bis zu einem Zeitpunkt zwischen zwei Base-Backups).
|
||||
|
||||
### A.1 Repo-Config (Ergänzung zu `pgbackrest.conf` oben)
|
||||
|
||||
```ini
|
||||
[global]
|
||||
# ... (repo1-* wie im Abschnitt „Verschlüsselte Backups" oben) ...
|
||||
repo1-retention-full=4 # 4 Voll-Backups vorhalten (s. Retention-Tabelle)
|
||||
repo1-retention-archive=8 # WAL für so viele Full-Sets behalten (PITR-Fenster)
|
||||
repo1-retention-archive-type=full
|
||||
start-fast=y
|
||||
archive-async=y # asynchrones Archiving (Durchsatz/latenztolerant)
|
||||
spool-path=/var/spool/pgbackrest
|
||||
|
||||
[certvia]
|
||||
pg1-path=/srv/cryptdata/pgdata
|
||||
```
|
||||
|
||||
### A.2 WAL-Archiving in Postgres aktivieren (`postgresql.conf`)
|
||||
|
||||
```ini
|
||||
archive_mode = on
|
||||
archive_command = 'pgbackrest --stanza=certvia archive-push %p'
|
||||
wal_level = replica
|
||||
max_wal_senders = 3
|
||||
```
|
||||
|
||||
```bash
|
||||
# Stanza einmalig anlegen + prüfen, dann erstes Voll-Backup:
|
||||
pgbackrest --stanza=certvia stanza-create
|
||||
pgbackrest --stanza=certvia check
|
||||
pgbackrest --stanza=certvia --type=full backup
|
||||
# Zeitplan (Coolify Scheduled Task / cron):
|
||||
# full wöchentlich pgbackrest --stanza=certvia --type=full backup
|
||||
# diff/inc täglich pgbackrest --stanza=certvia --type=incr backup
|
||||
```
|
||||
|
||||
### A.3 Restore / PITR-Prozedur (dokumentierter Ablauf)
|
||||
|
||||
> **Achtung:** Cluster-weit — ersetzt den GESAMTEN Datenbestand aller Mandanten. Für einen
|
||||
> **einzelnen** Kunden ist der **Portal-Restore** (Schicht B, `/admin/[id]?restore=1`) das
|
||||
> richtige Werkzeug, nicht PITR.
|
||||
|
||||
```bash
|
||||
# 1. App + Postgres stoppen (kein Schreibzugriff während des Restore).
|
||||
docker compose stop app && systemctl stop postgresql # bzw. Coolify-Dienst anhalten
|
||||
|
||||
# 2a. Vollständiger Restore auf den neuesten konsistenten Stand:
|
||||
pgbackrest --stanza=certvia --delta restore
|
||||
|
||||
# 2b. ODER Point-in-Time-Recovery auf einen Zeitpunkt T:
|
||||
pgbackrest --stanza=certvia --delta \
|
||||
--type=time --target="2026-08-11 14:30:00+02" \
|
||||
--target-action=promote restore
|
||||
|
||||
# 3. Postgres starten — spielt WAL bis zum Target und promotet dann.
|
||||
systemctl start postgresql
|
||||
# Recovery-Fortschritt in den Postgres-Logs verfolgen (…"recovery stopping before"…).
|
||||
|
||||
# 4. Kohärenz prüfen (s. Restore-Kohärenz unten): Secrets der Zielumgebung müssen
|
||||
# zu den Daten passen (Pepper/MFA_ENC_KEY), sonst Login/MFA planmäßig zurücksetzen.
|
||||
# 5. App wieder starten, Smoke-Test (Login, ein Mandant, ein Upload).
|
||||
```
|
||||
|
||||
- **Quartalsweiser Restore-Test PFLICHT:** PITR in eine **Wegwerf-Umgebung** wiederherstellen,
|
||||
Ergebnis protokollieren (der Go-Live fordert das ohnehin für `pgdata`). Ungetestetes Backup = kein Backup.
|
||||
- **Retention/PITR-Fenster** dem DSB vorlegen (s. Retention-Tabelle unten).
|
||||
|
||||
## MinIO-Objekt-Backup mit restic (vollwertig, Go-Live-Runbook)
|
||||
|
||||
> Ersetzt das frühere „Best-Effort-Key-Kopieren" durch ein **vollwertiges, versioniertes,
|
||||
> verschlüsseltes** Objekt-Backup. MinIO hält Uploads/Logos **und** die App-Backup-Artefakte
|
||||
> (`<tenantId>/backups/…`) sowie die DSGVO-Pakete (`<tenantId>/dsgvo-exports/…`); ein
|
||||
> DB-Backup allein genügt nicht (Backup-Konzept §1/§3).
|
||||
|
||||
```bash
|
||||
export RESTIC_REPOSITORY=s3:<endpoint>/certvia-restic-prod # eigener Bucket, eigener Zugang
|
||||
export RESTIC_PASSWORD=<RESTIC_REPO_KEY> # aus Passwortmanager, NIE ins Repo/Bucket
|
||||
export AWS_ACCESS_KEY_ID=<restic-zugang> AWS_SECRET_ACCESS_KEY=<restic-secret>
|
||||
|
||||
restic snapshots || restic init # einmalig initialisieren
|
||||
# Zeitplan (Coolify Scheduled Task / cron), täglich:
|
||||
restic backup /srv/cryptdata/minio --tag minio --host certvia-prod
|
||||
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
|
||||
restic check --read-data-subset=5% # Integrität stichprobenweise prüfen
|
||||
|
||||
# Restore (ganzes Repo oder gezielt ein Prefix):
|
||||
restic restore latest --target /srv/cryptdata/minio
|
||||
restic restore latest --target /tmp/recover --include '/srv/cryptdata/minio/<tenantId>/uploads'
|
||||
```
|
||||
|
||||
- **Getrennte Buckets/Zugänge:** restic-Repo **nicht** im App-MinIO-Bucket, Schlüssel **nie**
|
||||
zusammen mit den Artefakten.
|
||||
- **Konsistenz:** MinIO-Snapshot und DB-Backup laufen zeitnah; die App-Restore-Engine (Schicht B)
|
||||
stellt DB **und** den Mandanten-Prefix wieder her — beide Ebenen müssen vorhanden sein.
|
||||
|
||||
### Retention je Schicht (dem DSB vorzulegen — Platzhalter, DSB bestätigt)
|
||||
|
||||
| Schicht | Objekt | Vorschlag |
|
||||
|---|---|---|
|
||||
| A (pgBackRest) | Voll-Backups | 4 Wochen (`repo1-retention-full=4`) |
|
||||
| A (pgBackRest) | WAL-Archiv / PITR-Fenster | bis zu 8 Full-Sets (`repo1-retention-archive`) |
|
||||
| B (App-Export) | Per-Tenant-Snapshots | 30–90 Tage (DSB) |
|
||||
| DSGVO | Zustellpakete (`dsgvo-exports/`) | Download-Link **1 h TTL**; ZIP kurzlebig, danach löschen |
|
||||
|
||||
### ⚠ Restore-Kohärenz (Vorbedingung im Restore-Runbook)
|
||||
|
||||
> **`PASSWORD_PEPPER`, `MFA_ENC_KEY` und `BACKUP_ENC_KEY` sind Umgebungs-Secrets und stehen
|
||||
> NICHT im Backup-Artefakt.** Ein Restore in eine Umgebung mit **anderen** Secrets bricht:
|
||||
> - **anderer `PASSWORD_PEPPER`** → **alle** Passwort-Prüfungen schlagen fehl (kein Login).
|
||||
> - **anderes `MFA_ENC_KEY`** → TOTP-Secrets nicht entschlüsselbar → MFA-Prüfung bricht.
|
||||
> - **anderes `BACKUP_ENC_KEY`** → das AES-256-GCM-Artefakt lässt sich gar nicht entschlüsseln.
|
||||
>
|
||||
> **Vorbedingung vor jedem Restore:** Zielumgebung hält **exakt die Secrets, mit denen das
|
||||
> Backup erzeugt wurde**, oder es wird ein **Passwort-/MFA-Reset** (bzw. Neuverschlüsselung)
|
||||
> eingeplant. Deshalb: Secrets je Umgebung getrennt führen (`docs/SECRETS-REGISTER.md`) und die
|
||||
> passende Kopie **vor** dem Restore bereitstellen. Cross-Environment-Restore (prod→staging) ist
|
||||
> nur mit den prod-Secrets **oder** anschließendem Reset lauffähig.
|
||||
|
||||
## Sicherheits-Checkliste Go-Live
|
||||
|
||||
- [ ] Frische, starke Secrets (nicht aus Test übernommen)
|
||||
- [ ] `RUN_DEMO_SEED` aus, **keine** Demo-Daten in Prod
|
||||
- [ ] Bootstrap-Admin-Passwort nach erstem Login geändert
|
||||
- [ ] HTTPS erzwungen, gültiges Zertifikat
|
||||
- [ ] `pgdata` persistent + Backup + Restore-Test
|
||||
- [ ] Firewall aktiv, SSH gehärtet
|
||||
- [ ] Gitea-Repo privat, Zugriff nur für das Team
|
||||
- [ ] `REDIS_PASSWORD` gesetzt und in `REDIS_URL` eingetragen (F-18)
|
||||
- [ ] Alle Images auf konkrete Tags gepinnt (kein `:latest`), CI grün (F-11)
|
||||
- [ ] **Host-Encryption** aktiv: Daten-Volume (`pgdata` + MinIO) auf LUKS/verschlüsseltem Volume, Boot-Unlock-Verfahren dokumentiert (A oder B)
|
||||
- [ ] **Verschlüsselte Backups**: pgBackRest (`aes-256-cbc`) + `age` + restic eingerichtet, Retention dem DSB vorgelegt, **Restore-Test** dokumentiert
|
||||
- [ ] **Secrets-Register** (`docs/SECRETS-REGISTER.md`) gepflegt: Ownership + Rotationsregel je Umgebung, Keys nie im Artefakt-Bucket, versiegelte Offline-Kopie
|
||||
- [ ] **Restore-Kohärenz** geprüft: Zielumgebung hält die zum Backup passenden `PASSWORD_PEPPER`/`MFA_ENC_KEY`/`BACKUP_ENC_KEY` (sonst Reset einplanen)
|
||||
|
||||
---
|
||||
|
||||
## Supply-Chain & Container-Härtung (F-11 / F-18)
|
||||
|
||||
Diese Maßnahmen sind in `Dockerfile`, `docker-compose*.yml`, `.gitea/workflows/ci.yml`
|
||||
und `renovate.json` umgesetzt.
|
||||
|
||||
### F-11 — Supply Chain
|
||||
|
||||
- **`npm ci` statt `npm install`** (Lockfile bindend, reproduzierbar). Base-Image ist
|
||||
**`node:22-slim`** (Debian/glibc) statt Alpine/musl — damit greifen die im Lockfile
|
||||
hinterlegten glibc-Optional-Deps (lightningcss/oxide/argon2/sharp) zuverlässig.
|
||||
- **npm 11 im Build gepinnt.** Das committete `package-lock.json` wurde mit npm 11
|
||||
erzeugt; das in `node:22.14.0` gebündelte npm 10.9.2 löst `next@16.2.12 → @swc/helpers`
|
||||
anders auf und würde `npm ci` mit *„out of sync"* abbrechen. `RUN npm i -g npm@11.19.0`
|
||||
stellt den Resolver-Gleichstand her — **ohne** Lockfile-Änderung.
|
||||
> **Offene Folgeänderung (Dependency-Lane / F-12):** Sauberer wäre, das Lockfile mit
|
||||
> npm 10 neu zu erzeugen (`rm -rf node_modules package-lock.json && npm install` unter
|
||||
> Node 22), damit die npm-Pinnung entfallen kann. Das ist eine `package-lock.json`-Änderung
|
||||
> und gehört **nicht** in diese Infra-Lane.
|
||||
- **Image-Pins** (keine rollenden Tags):
|
||||
`node:22.14.0-slim`, `pgvector/pgvector:0.8.0-pg16`, `redis:7.4.2-alpine`,
|
||||
`minio/minio:RELEASE.2025-04-22T22-12-26Z`, `mailhog/mailhog:v1.0.1`.
|
||||
- **Schlanke `migrate`-Stage** statt `builder` für den Migrations-/Seed-Job: kein
|
||||
`next build`, kein Build-Cache. Sie enthält weiterhin devDeps (tsx/Prisma-CLI) + `src`,
|
||||
weil `prisma/seed.ts` und `scripts/bootstrap-admin.ts` aus `../src`/`@/server` importieren.
|
||||
Ein reiner Prisma-CLI-Container würde diese Jobs brechen — die Entkopplung von Seed/Bootstrap
|
||||
vom App-Code ist als App-seitige Folgeänderung empfohlen.
|
||||
|
||||
### SBOM
|
||||
|
||||
Zwei Wege (der CI-Weg ist optional/nicht-blockierend hinterlegt):
|
||||
|
||||
```bash
|
||||
# a) aus dem npm-Baum (CycloneDX) — braucht ein valides Lockfile (s. F-12-Hinweis):
|
||||
npm ci --include=optional && npm sbom --sbom-format cyclonedx --omit dev > sbom.cyclonedx.json
|
||||
|
||||
# b) aus dem gebauten Image (unabhängig vom npm-Baum), z. B. mit Syft:
|
||||
docker build -t isms:sbom .
|
||||
syft isms:sbom -o cyclonedx-json > sbom.image.cyclonedx.json
|
||||
```
|
||||
|
||||
### F-18 — Härtung & Netzsegmentierung
|
||||
|
||||
- **Redis mit `requirepass`** (`REDIS_PASSWORD`, in `REDIS_URL` eingesetzt).
|
||||
- **Internes Netz** (`internal: true`) für `postgres`/`redis`/`minio`/`migrate` — kein
|
||||
Egress, kein Host-Exposure; nur `app` zusätzlich im default-Netz (Coolify-Proxy).
|
||||
- **`security_opt: no-new-privileges`, `cap_drop: [ALL]`** (gezielte `cap_add` nur für die
|
||||
Entrypoints von postgres/redis, die intern per gosu den Benutzer wechseln), sowie
|
||||
**`deploy.resources.limits`** (CPU/RAM) je Dienst.
|
||||
- **Dev-Compose**: Host-Ports nur noch auf `127.0.0.1` gebunden (Postgres/Redis/MinIO/Mailhog).
|
||||
|
||||
### CI & Renovate
|
||||
|
||||
- **CI**: `.gitea/workflows/ci.yml` (Spiegel `.github/workflows/ci.yml`) fährt
|
||||
`npm ci → tsc --noEmit → lint → build`, dazu ein **`npm audit`-Gate**
|
||||
(`--omit=dev --audit-level=high`, hart) plus einen informativen Volllauf.
|
||||
> **Braucht einen aktivierten Gitea-Actions-Runner** — ohne registrierten Runner läuft
|
||||
> die Pipeline nicht an.
|
||||
- **Renovate** (`renovate.json`): wöchentliche, gruppierte Updates; Sicherheits-/OSV-Alerts
|
||||
sofort und priorisiert. **`next-auth`/`@auth/core` (Beta 5.x)** sind bewusst auf
|
||||
manuelles Review gesetzt (kein Auto-Merge) — Auth-Regressionen können „fail open" bedeuten (F-01).
|
||||
|
||||
### IM-D — E-Mail-Eingang für Vorfälle (Inbound / E-Mail-to-Ticket)
|
||||
|
||||
Vorfälle können per E-Mail gemeldet werden. Kunden leiten Meldungen an eine
|
||||
kundenindividuelle **Intake-Adresse** `vorfall-<token>@in.certvia.de` weiter; der
|
||||
`incident-inbound-worker` holt die Mails per IMAP ab und legt daraus Vorfälle an
|
||||
(bzw. reiht unklare Mails in die Betreiber-Review). Der Token trägt die
|
||||
Mandantenzuordnung (global eindeutig, nicht erratbar) — es gibt **kein Postfach je
|
||||
Kunde**, sondern ein Catch-all.
|
||||
|
||||
**Globaler Setup (einmalig, DNS + Postfach):**
|
||||
|
||||
1. **Subdomain `in.certvia.de`** anlegen und als Mail-Domain einrichten.
|
||||
2. **Catch-all-Postfach** für `*@in.certvia.de` → ein einzelnes IMAP-Postfach
|
||||
(alle `vorfall-<token>@…` landen darin). MX-Record auf den Mailhost setzen.
|
||||
3. **DKIM/SPF/DMARC** für `in.certvia.de` veröffentlichen (Empfang; die
|
||||
Absender-Authentizität der weitergeleiteten Kundenmails wird über deren DKIM +
|
||||
die pro Kunde gepflegte Absender-Allowlist geprüft — SPF bricht bei Weiterleitung
|
||||
und ist bewusst nur ein Signal).
|
||||
4. **IMAP-Zugang** des Catch-all-Postfachs als Secrets hinterlegen (siehe unten).
|
||||
|
||||
**Env (Dienst `incident-inbound-worker` in `docker-compose.coolify.yml`):**
|
||||
|
||||
| Variable | Zweck |
|
||||
| --- | --- |
|
||||
| `INCIDENT_IMAP_HOST` / `INCIDENT_IMAP_PORT` | IMAP-Server des Catch-all-Postfachs (Default-Port 993) |
|
||||
| `INCIDENT_IMAP_USER` / `INCIDENT_IMAP_PASSWORD` | Zugangsdaten des Catch-all-Postfachs |
|
||||
| `INCIDENT_IMAP_TLS` | `true` (Default) für IMAPS; `false` nur für STARTTLS/Plain |
|
||||
| `INCIDENT_IMAP_MAILBOX` | Postfach/Ordner (Default `INBOX`) |
|
||||
| `INCIDENT_IMAP_POLL_MS` | Abholintervall in ms (Default 60000, min. 15000) |
|
||||
| `INCIDENT_INTAKE_DOMAIN` | Muss zur Catch-all-Subdomain passen (Default `in.certvia.de`) |
|
||||
|
||||
Ohne `INCIDENT_IMAP_*` beendet sich der Worker **sauber** mit einer Meldung
|
||||
(kein Crash) — der übrige Betrieb ist davon unberührt. Verarbeitete Mails werden
|
||||
als `\Seen` markiert; zusätzlich schützt die **Message-ID-Dedupe** gegen
|
||||
Doppel-Tickets beim erneuten Abholen.
|
||||
|
||||
**Provisionierung je Kunde (Betreiber-Portal):** Beim Onboarding (oder später) im
|
||||
Mandanten unter **E-Mail-Eingang** die Absender-Domänen (Allowlist) hinterlegen —
|
||||
die Intake-Adresse wird automatisch erzeugt und angezeigt. Der Kunde richtet die
|
||||
Weiterleitung ein; sobald die **erste Test-Mail** als Vorfall ankommt, springt der
|
||||
Status von *Weiterleitung ausstehend* auf *verifiziert* (manueller Override im
|
||||
Portal möglich). Offene Verifizierungen und zu prüfende Eingänge (kein/unbekannter
|
||||
Token, Allowlist-/DKIM-Fehlschlag) listet das Betreiber-Dashboard.
|
||||
@@ -0,0 +1,82 @@
|
||||
# Prod-Deploy via vorgebaute Images (Plan B) — Runbook
|
||||
|
||||
> **Warum:** Der direkte Build auf dem Prod-Coolify läuft in den Deployment-Timeout
|
||||
> (~1 h; Ursache ist Coolifys Build-Pfad — u. a. die ~265-ARG-Injektion, die den
|
||||
> Layer-Cache bei jedem Deploy bricht → Kaltbau). Lösung: Images **einmal auf einem
|
||||
> leistungsfähigen Host bauen**, in die Registry pushen, und der Prod-Host **zieht nur**.
|
||||
> Ergebnis: Prod-Deploy = Pull + Migrate = Minuten statt Stunde.
|
||||
|
||||
## Topologie (Stand 2026-09-10)
|
||||
|
||||
| Rolle | Host |
|
||||
|---|---|
|
||||
| **Build-Host** (baut + pusht) | `192.168.1.155` — lokales Coolify (= local-gitea-Host), amd64, Docker |
|
||||
| **Registry** | **git.certvia.de** (Gitea Container Registry), Namespace `msolarczek` |
|
||||
| **Prod** (`certvia_prod`, GEFIM live) | **coolify.certvia.de** (eigener Server, ≠ 192.168) |
|
||||
| Quelle | git.certvia.de/msolarczek/certvia, Branch `main` |
|
||||
|
||||
Beteiligte Dateien im Repo:
|
||||
- `docker-compose.coolify.prebuilt.yml` — wie `docker-compose.coolify.yml`, aber die App-Services ziehen `${REGISTRY:-git.certvia.de/msolarczek}/certvia-*:${IMAGE_TAG:-main}` statt zu bauen (`postgres`/`redis` unverändert).
|
||||
- `scripts/build-and-push-images.sh` — baut + pusht die drei Images.
|
||||
|
||||
Service → Image (Dockerfile-Target):
|
||||
- `app` → **certvia-app** (`runner`)
|
||||
- `migrate`, `worker`, `backup-worker`, `incident-inbound-worker`, `garage-provision` → **certvia-migrate** (`migrate`)
|
||||
- `garage` → **certvia-garage** (`garage`)
|
||||
|
||||
## Voraussetzung: Gitea-Token
|
||||
Token in git.certvia.de → Settings → Applications mit Scopes:
|
||||
`read:repository` (Klonen) + `read:package` + `write:package` (Image Push/Pull).
|
||||
|
||||
## Ablauf je Release
|
||||
|
||||
### 1. Auf dem Build-Host (192.168.1.155)
|
||||
```bash
|
||||
docker login git.certvia.de -u msolarczek # Passwort = Token
|
||||
git clone https://msolarczek:<TOKEN>@git.certvia.de/msolarczek/certvia.git cv-build # oder: cd cv-build && git fetch && git pull
|
||||
cd cv-build && git checkout main && git pull
|
||||
ALSO_MAIN=true ./scripts/build-and-push-images.sh # baut+pusht Tag <SHA> UND :main
|
||||
```
|
||||
> **Wichtig:** `ALSO_MAIN=true` setzen → es wird zusätzlich das bewegliche Tag `:main`
|
||||
> gepusht. Coolify zieht per Default `:main` (siehe Gotcha IMAGE_TAG unten).
|
||||
|
||||
### 2. Prod-Host (coolify.certvia.de) einmalig am Registry anmelden
|
||||
```bash
|
||||
docker login git.certvia.de -u msolarczek # Passwort = Token
|
||||
```
|
||||
(oder in der Coolify-UI unter Settings → Docker Registries hinterlegen). Nur beim
|
||||
ersten Mal / nach Token-Wechsel nötig.
|
||||
|
||||
### 3. Coolify (certvia_prod, coolify.certvia.de)
|
||||
- **Configuration → „Docker Compose Location"** = `docker-compose.coolify.prebuilt.yml` (einmalig).
|
||||
- Env unverändert: `RUN_DEMO_SEED=false`, `BOOTSTRAP_ADMIN=false`.
|
||||
- **Redeploy.** Log zeigt Pull der `certvia-*:main` → `migrate` (achte auf neue Migration) → `garage`/`garage-provision` → `app` healthy.
|
||||
|
||||
### 4. Nach dem Deploy — Bestandsmandanten-Migrationen der Fachdaten
|
||||
Nur nötig, wenn eine Änderung Bestandsmandanten betrifft (z. B. der 5×5-Backfill). In
|
||||
Coolify → certvia_prod → Service `backup-worker`/`worker` → Terminal (oder per SSH
|
||||
`docker exec`):
|
||||
```bash
|
||||
npx tsx scripts/backfill-risk-5x5.ts # idempotent, alle Mandanten
|
||||
```
|
||||
|
||||
### 5. Smoke-Test
|
||||
Login → betroffene Modulseiten prüfen (z. B. `/processes`, `/dependencies`).
|
||||
|
||||
## Gotchas (aus dem ersten Live-Lauf gelernt)
|
||||
|
||||
- **`IMAGE_TAG` wird von Coolify NICHT in die Compose-Interpolation gereicht** → die
|
||||
Datei fällt auf `:main` zurück. Deshalb `:main` immer mitpushen (`ALSO_MAIN=true`).
|
||||
SHA-genaues Pinning müsste erst geklärt werden (dann `IMAGE_TAG=<sha>` in Coolify-Env).
|
||||
- **Coolify entfernt die alten Container VOR dem Pull.** Fehlt der Ziel-Tag in der
|
||||
Registry, schlägt der Pull fehl und **prod ist unten**. Also *immer erst* Images
|
||||
(inkl. `:main`) pushen, *dann* Redeploy.
|
||||
- **Klon-403:** Ein reiner Package-Token darf nicht klonen — `read:repository` fehlt.
|
||||
- **Migration-Drift ungefährlich:** `prisma migrate deploy` läuft auch dann sauber (Exit 0),
|
||||
wenn die DB eine angewandte Migration hat, die lokal nicht mehr existiert (empirisch geprüft).
|
||||
- Nach Nutzung Token, der im Klartext (URL/History) auftauchte, **widerrufen**.
|
||||
|
||||
## Rollback
|
||||
Alten Stand deployen: früheres Image-Tag als `:main` retaggen+pushen (auf dem Build-Host)
|
||||
und Redeploy — oder Compose-Location zurück auf `docker-compose.coolify.yml` (Host-Build,
|
||||
langsam) als Notnagel.
|
||||
@@ -0,0 +1,119 @@
|
||||
# DevOps-Integrations-Runbook — 2-Lane-Entwicklung (Onboarding-Wizard)
|
||||
|
||||
> Zweck: **DevOps übernimmt das Integrieren** der Feature-Branches nach `dev` (Merge,
|
||||
> Validierung, Doku-Pflege, Push). **Entwickler committen nur auf ihren Feature-Branches**
|
||||
> und müssen sich um Merge/Konsolidierung nicht mehr kümmern.
|
||||
> Basis-Doku: `docs/STAND-dev-branch.md` (Single Source of Truth), `docs/HANDOVER-DEV.md`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Setup (Ist-Zustand)
|
||||
|
||||
- **Zwei Git-Worktrees** desselben Repos, die sich **eine** lokale Postgres-DB teilen:
|
||||
- `~/Projects/ISMS-Tool` → Integrations-Branch **`dev`** (hier arbeitet DevOps).
|
||||
- `~/Projects/ISMS-Tool-devB` → Dev-B-Worktree (Feature-Branch).
|
||||
- **Branch-Modell:** Integrationsbranch **`dev`**; Feature-Branches mit **Bindestrich**
|
||||
(`dev-a1-wizard-shell`, `dev-b1-tasks-erweiterung`, `dev-b2-regel-engine`, …).
|
||||
⚠️ **Nicht** `dev/x` verwenden: Git kann nicht gleichzeitig Branch `dev` **und** `dev/x`
|
||||
führen (D/F-Konflikt) — deshalb Bindestrich.
|
||||
- **`main`** ist das spätere Merge-Ziel (hier nicht angefasst).
|
||||
- **Gitea (Remote)** ist aktuell zeitweise offline → Pushes erst, wenn erreichbar.
|
||||
Durch das geteilte Repo sehen alle Worktrees ein aktualisiertes `dev` sofort (ohne Push).
|
||||
|
||||
## 2. Verantwortungs-Split (neu)
|
||||
|
||||
| Rolle | macht | macht **nicht** |
|
||||
|-------|-------|------------------|
|
||||
| **Entwickler (A/B)** | Feature-Branch, kleine Commits je Story, Rebase auf `dev` **vor** dem Erzeugen einer Migration | Merge nach `dev`, Doku-Pflege, Push |
|
||||
| **DevOps** | Merge Feature-Branch → `dev`, Validierungs-Gate, `STAND-dev-branch.md` pflegen, Push (wenn Gitea da) | Fachlogik implementieren |
|
||||
|
||||
## 3. Integrations-Ablauf (pro fertigem Feature-Branch)
|
||||
|
||||
```bash
|
||||
# 0) Im Entwickler-Worktree: sauber & auf dev rebased?
|
||||
git -C ~/Projects/ISMS-Tool-devB status --porcelain # leer = sauber
|
||||
|
||||
# 1) Ins Integrations-Worktree, auf dev, sauberer Tree
|
||||
cd ~/Projects/ISMS-Tool
|
||||
git checkout dev
|
||||
git status --porcelain # leer = sauber
|
||||
|
||||
# 2) Konfliktvorschau (optional)
|
||||
git merge-tree $(git merge-base dev <feature-branch>) dev <feature-branch> | grep -i "changed in both" || echo "keine Konflikte"
|
||||
|
||||
# 3) Nicht-destruktiv mergen (Entwickler-Branch bleibt unangetastet)
|
||||
git merge --no-ff <feature-branch> -m "Merge <lane>: <Stories> in dev"
|
||||
```
|
||||
|
||||
**Konflikte** treten fast nur in den **Naht-Dateien** auf — **additiv** auflösen, nie die
|
||||
Ergänzungen der anderen Lane löschen:
|
||||
`prisma/schema.prisma` · `scripts/check-module-guards.ts` · `messages/de.json`/`en.json` ·
|
||||
`seed/isms-vorlagenpaket-v2/variables.schema.json`.
|
||||
|
||||
## 4. Validierungs-Gate (muss komplett grün sein)
|
||||
|
||||
```bash
|
||||
npx prisma generate \
|
||||
&& npx prisma migrate status \
|
||||
&& npx tsc --noEmit \
|
||||
&& npm run lint \
|
||||
&& npm run build \
|
||||
&& python3 seed/isms-vorlagenpaket-v2/_verify.py # nur nötig, wenn seed/variables geändert
|
||||
```
|
||||
- `migrate status` muss **„Database schema is up to date!"** melden (sonst → §6).
|
||||
- `build` führt den **Modul-Guard-Vollständigkeitscheck** als `prebuild` aus.
|
||||
|
||||
## 5. Doku + Branch-Sync + Push
|
||||
|
||||
```bash
|
||||
# STAND aktualisieren (Executive-Summary-Lane-Zeilen, Migrations-Liste, Commit-Übersicht)
|
||||
$EDITOR docs/STAND-dev-branch.md
|
||||
git add docs/STAND-dev-branch.md
|
||||
git commit -m "Doku: STAND — <Story> integriert"
|
||||
|
||||
# Aktive Feature-Branch-Zeiger auf dev nachziehen (optional, Komfort)
|
||||
git branch -f dev-a1-wizard-shell dev
|
||||
|
||||
# Push NUR wenn Gitea erreichbar:
|
||||
git fetch # prüfen, ob origin/dev jemand vorausgezogen hat
|
||||
git push origin dev # bei Divergenz NICHT force-pushen — abstimmen
|
||||
```
|
||||
Commit-Konvention: deutsch, granular, Trailer `Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>`.
|
||||
|
||||
## 6. Bekannte Stolpersteine (durch die geteilte DB)
|
||||
|
||||
- **Migrations-Timestamp-Diskrepanz nach Rebase:** Wird eine Migration im Branch neu erzeugt
|
||||
(neuer Timestamp) und die geteilte DB hat noch die alte angewandt, meldet `migrate status`
|
||||
„applied ≠ lokal". **Fix ohne Datenverlust** (kein SQL läuft neu):
|
||||
```bash
|
||||
# stalen DB-Eintrag entfernen …
|
||||
npx prisma db execute --schema prisma/schema.prisma --stdin <<< \
|
||||
"DELETE FROM \"_prisma_migrations\" WHERE migration_name='<ALT_TIMESTAMP>_<name>';"
|
||||
# … und die committete Migration als angewandt markieren
|
||||
npx prisma migrate resolve --applied <NEU_TIMESTAMP>_<name>
|
||||
```
|
||||
- **`migrate diff --from-config-datasource` zeigt Fremd-Änderungen:** Da beide Lanes dieselbe
|
||||
DB teilen, will der Diff die Spalten/Objekte der **anderen** Lane droppen. Beim Erzeugen einer
|
||||
Migration nur die **eigenen** DDL-Blöcke übernehmen (Entwickler-Aufgabe; DevOps sollte es kennen).
|
||||
- **Neue RBAC-Rechte/Rollen wirken erst nach DB-Grant:** Permissions werden beim **Login** aus der
|
||||
DB aufgelöst. Neue Einträge in `ROLE_DEFS` brauchen für **bestehende** Mandanten einen Grant
|
||||
(Re-Seed/Re-Provisioning oder gezieltes SQL). Neue Mandanten bekommen sie automatisch.
|
||||
- **Veraltetes JWT nach Re-Seed:** Nach einem Re-Seed zeigen offene Sessions auf alte User-IDs →
|
||||
Screen „Konto deaktiviert". **Fix:** ab-/neu anmelden (`/api/auth/signout`) — das JWT wird neu aufgelöst.
|
||||
- **Turbopack-Cache:** Nach Rewrites von Server-Actions kann die Browser-Konsole veraltete
|
||||
HMR-Fehler zeigen. Maßgeblich sind `tsc`/`build` + `preview_logs` (Server) — bei Zweifel Dev-Server neu starten.
|
||||
|
||||
## 7. Nicht-destruktive Regeln
|
||||
|
||||
- Feature-Branches **in `dev` mergen** (`--no-ff`) — **nie** die Entwickler-Branches rebasen/umschreiben.
|
||||
- Einen in einem Worktree ausgecheckten Branch **nicht** löschen.
|
||||
- Vollständig gemergte Branches (z. B. `dev-b1`, sobald `dev-b2` gelandet ist) dürfen aufgeräumt
|
||||
(gelöscht) werden — nur wenn nicht ausgecheckt.
|
||||
- Bei `origin/dev`-Divergenz **kein** `--force` — abstimmen und mergen.
|
||||
|
||||
## 8. Aktueller Stand (zum Zeitpunkt der Runbook-Erstellung)
|
||||
|
||||
- `dev` enthält beide Lanes bis: **A1-1, F2, A1-2** (Dev A) und **F1, B1, F4** (Dev B), konsolidiert.
|
||||
- Feature-Branches: `dev-a1-wizard-shell` (= `dev`), `dev-b2-regel-engine` (Dev B, offene Stories).
|
||||
- Offene Stories: A2 (Scoping + AL zentral), A3, F3+B2 (Regel-Engine), B3 (Fragebogen), B4 (Richtlinien).
|
||||
- Migrationen auf `dev`: siehe `docs/STAND-dev-branch.md` (Liste + Reihenfolge).
|
||||
@@ -0,0 +1,290 @@
|
||||
# Feindesign B1 — Assessment und Readiness für zwei Frameworks
|
||||
|
||||
**Stand:** 2026-08-27 · **Branch:** `feature/iso27001-framework-mapping` · **Status:** Entwurf zur Abnahme
|
||||
|
||||
> **Ausgangslage:** AP1–AP5 sind umgesetzt. Ein ISO-Mandant hat Dokumente, SoA-Modell, Kennzahlen,
|
||||
> Managementbewertung und Korrekturmaßnahmen. Was fehlt, ist die **Bewertungs- und Readiness-Sicht**:
|
||||
> `maturity.ts`, `scope-filter.ts`, `assessment-level.ts` und `readiness.ts` kennen kein Framework und
|
||||
> rechnen durchgängig VDA ISA — AL2/AL3, Prüfziele, Reifegrad 0–3, MUSS/SOLL.
|
||||
>
|
||||
> **Belegter Bruch:** `soa-context.ts:151` und `export-context.ts:49` lesen `controlAssessment`.
|
||||
> **Keine einzige Stelle liest `soaEntry`.** Das in AP3 gebaute SoA-Modul ist von der Auswertung
|
||||
> abgekoppelt — die Daten liegen da, die Readiness greift nicht darauf zu.
|
||||
|
||||
Grundlage: `docs/KONZEPT-framework-iso27001.md` (Lane 3), `docs/FRAMEWORK-MAPPING-ISO27001.md`,
|
||||
`docs/UEBERGABE-framework-iso27001.md`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Leitentscheidung: die Belegbasis liegt **unterhalb** der Framework-Strategie
|
||||
|
||||
Es werden **nicht zwei Engines** gebaut. Der Belegstatus eines Controls — ist die zuständige Richtlinie
|
||||
freigegeben, existiert das Verfahren, hängt ein Asset dran, gibt es einen Wirksamkeitsnachweis — ist
|
||||
eine **Tatsache über die Organisation**, keine Frage der Norm. Ob R08 freigegeben ist, ändert sich
|
||||
nicht dadurch, ob ISO oder VDA ISA danach fragt.
|
||||
|
||||
Würde man die Belegbasis mitparallelisieren, entstünden zwei Bewertungen derselben Realität, die
|
||||
auseinanderlaufen können. Im Audit steht dann „Berechtigungsvergabe: TISAX Reifegrad 3" neben
|
||||
„ISO: teilweise umgesetzt" — ein Widerspruch über denselben Sachverhalt.
|
||||
|
||||
**Regel: eine Belegbasis, zwei Bewertungen.**
|
||||
|
||||
```
|
||||
Schicht 3 Sichten /soa · /audit-readiness · Exporte · Wizard-Schritte → Reiter je Framework
|
||||
Schicht 2 Strategie Scope · Zielwert · Bewertung · Vokabular → je Framework
|
||||
Schicht 1 Belegbasis loadEvidenceResolver → ControlEvidence → GETEILT
|
||||
Schicht 0 Fachdaten PolicyDocument · Evidence · Asset · Risk · Measure → GETEILT
|
||||
```
|
||||
|
||||
Das ist derselbe Schnitt wie bei den Richtlinien: ein Umsetzungstext, zwei Anforderungssichten.
|
||||
|
||||
---
|
||||
|
||||
## 2. Was generalisiert wird (Schicht 1)
|
||||
|
||||
`ControlEvidence` (`src/lib/maturity.ts:54`) ist bereits **framework-neutral** — Richtlinienstatus,
|
||||
Verfahrensstatus, Asset-/Risiko-Verknüpfung, operativer Wirksamkeitsnachweis. Nur der *Eingabetyp* des
|
||||
Resolvers ist TISAX-spezifisch.
|
||||
|
||||
**Änderung:** `C5ControlSpec` (`maturity.ts:16`) wird auf ein neutrales `ControlSpec` reduziert:
|
||||
|
||||
```ts
|
||||
export interface ControlSpec {
|
||||
control: string; // "4.1.2" | "A.8.5"
|
||||
title: string;
|
||||
policy: string[]; // ["R08"]
|
||||
verfahren: string[]; // ["VA-03"]
|
||||
needsAsset: boolean;
|
||||
needsRisk: boolean;
|
||||
}
|
||||
// C5ControlSpec extends ControlSpec { target: number } — TISAX-Zusatzfeld bleibt dort
|
||||
```
|
||||
|
||||
`loadEvidenceResolver(db, completeControls)` nimmt künftig `ControlSpec`. **Für TISAX ändert sich
|
||||
nichts** — `C5ControlSpec` erfüllt das Interface.
|
||||
|
||||
### ISO-Specs kommen aus dem Mapping, nicht von Hand
|
||||
|
||||
`mapping-iso.json` trägt je Anforderung bereits `policy` (R-Code) und `verfahren` (VA-Codes). Daraus
|
||||
lässt sich der ISO-`ControlSpec` erzeugen. `needsAsset`/`needsRisk` werden über den vorhandenen
|
||||
Crosswalk `ISO_TO_ISA` (`src/lib/iso-isa-crosswalk.ts`, 87 der 120) vom ISA-Spec **geerbt**; für die
|
||||
33 ISO-eigenen Abschnitte werden sie explizit gesetzt — sinnvoll nur bei A.5.9 (`needsAsset`) sowie
|
||||
6.1.2/6.1.3/8.2/8.3 (`needsRisk`).
|
||||
|
||||
**Umsetzung:** `_generate_iso.py` erzeugt zusätzlich `src/lib/control-specs-iso.ts` — analog zu
|
||||
`control-titles-iso.ts` und `iso-isa-crosswalk.ts`. Damit bleibt das Mapping die einzige Quelle und
|
||||
niemand pflegt eine zweite Liste.
|
||||
|
||||
---
|
||||
|
||||
## 3. Die Strategie-Schnittstelle (Schicht 2)
|
||||
|
||||
```ts
|
||||
export type FrameworkKey = "TISAX" | "ISO_27001";
|
||||
|
||||
/** Bewertung eines Controls — je Framework ein eigener Typ, nie gemischt. */
|
||||
export type Verdict =
|
||||
| { kind: "maturity"; suggested: 0 | 1 | 2 | 3; confirmed: number | null; target: 2 | 3 }
|
||||
| { kind: "status"; applicable: boolean; suggested: ImplStatus; confirmed: ImplStatus | null };
|
||||
|
||||
export type ImplStatus = "umgesetzt" | "teilweise" | "geplant";
|
||||
|
||||
export interface AssessmentRow {
|
||||
control: string;
|
||||
title: string;
|
||||
spec: ControlSpec;
|
||||
evidence: ControlEvidence; // aus Schicht 1, identisch für beide Frameworks
|
||||
verdict: Verdict; // je Framework interpretiert
|
||||
gaps: OpenPoint[];
|
||||
}
|
||||
|
||||
export interface FrameworkStrategy {
|
||||
key: FrameworkKey;
|
||||
/** Anzeigename für Reiter und Berichte. */
|
||||
label: string; // "TISAX / VDA ISA 2027" | "ISO/IEC 27001:2022"
|
||||
/** Datei im Vorlagenpaket. */
|
||||
mappingFile: string; // "mapping.json" | "mapping-iso.json"
|
||||
/** Controls im Geltungsbereich — TISAX: AL + Prüfziele · ISO: Anwendbarkeit aus der SoA. */
|
||||
controlsInScope(db: TenantDb): Promise<ControlSpec[]>;
|
||||
/** Bewertung eines Controls aus geteiltem Beleg + framework-eigener Regel. */
|
||||
evaluate(spec: ControlSpec, ev: ControlEvidence, ctx: EvalContext): Verdict;
|
||||
/** Offene Punkte, die aus der Lücke zum Zielwert folgen. */
|
||||
gaps(spec: ControlSpec, ev: ControlEvidence, v: Verdict): OpenPoint[];
|
||||
/** Kennzahl und Textband — framework-eigenes Vokabular, kein gemeinsamer Nenner. */
|
||||
summarise(rows: AssessmentRow[]): ReadinessSummary;
|
||||
}
|
||||
```
|
||||
|
||||
`buildControlRows` (`soa-context.ts:146`) wird zu `buildAssessment(db, tenantId, framework)` und
|
||||
delegiert an die Strategie. Die Belegauflösung bleibt, wo sie ist.
|
||||
|
||||
### TisaxStrategy — verhaltensgleich extrahieren
|
||||
|
||||
Reine Umverdrahtung, **kein** neues Verhalten: `loadScopeInput` + `controlsInScope` → `controlsInScope`,
|
||||
`suggestMaturity` + `targetMaturity` → `evaluate`, `openPoints` → `gaps`, `computeReadiness` →
|
||||
`summarise`. Regressionsschutz: Snapshot-Test gegen die heutige Ausgabe (siehe §7).
|
||||
|
||||
### IsoStrategy — neu
|
||||
|
||||
| Aspekt | Regel |
|
||||
|---|---|
|
||||
| **Scope** | `SoaEntry.applicable = true`. Kein AL, keine Prüfziele. Klauseln 4–10 sind **immer** im Scope (nicht Gegenstand der Anwendbarkeit). |
|
||||
| **Zielwert** | `implementationStatus = "umgesetzt"` für jedes anwendbare Control. Keine Stufung. |
|
||||
| **Vorschlag** | aus `ControlEvidence`: Richtlinie *und* Verfahren `validiert` + geforderte Verknüpfungen vorhanden → `umgesetzt`; teilweise belegt → `teilweise`; sonst `geplant`. |
|
||||
| **Bestätigung** | `SoaEntry.implementationStatus` ist der bestätigte Wert; der Vorschlag überschreibt ihn nie (Muster wie `ControlAssessment.suggested` / `confirmedValue`). |
|
||||
| **Lücken** | fehlende Begründung, fehlender Nachweis, Status ≠ „umgesetzt" bei anwendbarem Control. |
|
||||
|
||||
---
|
||||
|
||||
## 4. Vorbelegung bei Doppel-Framework — gegen Doppelerfassung
|
||||
|
||||
Führt ein Mandant beide Normen, darf der ISB **nicht zweimal dasselbe beantworten**. Über
|
||||
`ISO_TO_ISA` ist bekannt, welches ISA-Control denselben Bibliotheksabschnitt trägt.
|
||||
|
||||
**Regel:** Ist das zugehörige ISA-Control bestätigt und erreicht seinen Zielreifegrad, schlägt die
|
||||
ISO-Sicht `umgesetzt` vor — mit Verweis auf denselben Nachweis. Der ISB **bestätigt**, das System
|
||||
setzt nichts automatisch.
|
||||
|
||||
Für die 33 ISO-Anforderungen ohne ISA-Gegenstück (Managementsystem-Klauseln, Clear Desk, DLP,
|
||||
Kapazität, Zeitsynchronisation …) gibt es keine Vorbelegung — sie werden regulär bewertet. Das ist
|
||||
zugleich die ehrliche Aussage an den Kunden: **das ist die Delta-Arbeit, die ISO gegenüber TISAX
|
||||
zusätzlich verlangt.** Diese Liste ist ein verkaufbares Ergebnis für sich.
|
||||
|
||||
---
|
||||
|
||||
## 5. Sichten und Reiter (Schicht 3)
|
||||
|
||||
| Bereich | Reiter ISO / TISAX | Begründung |
|
||||
|---|:--:|---|
|
||||
| Controls- / SoA-Sicht (`/soa`) | **ja** | zwei Kataloge, zwei Zielsysteme |
|
||||
| Readiness (`/audit-readiness`) | **ja** | je Norm eine eigene Aussage und ein eigenes Vokabular |
|
||||
| Exporte | **ja** | VDA-ISA-Export bleibt TISAX; SoA und Annex-A-Gap sind ISO |
|
||||
| Richtlinien (`/policies`) | **nein** | ein Dokumentensatz; Parallelanzeige im Dokument ist gebaut |
|
||||
| Nachweise | **nein** | ein Beleg belegt eine Tatsache, unabhängig von der fragenden Norm |
|
||||
| Assets, Risiken, Vorfälle, Lieferanten, Aufgaben | **nein** | framework-neutral |
|
||||
|
||||
**Reiter-Verhalten:** ein aktives Framework → kein Reiter, direkte Anzeige. Zwei aktive Frameworks →
|
||||
Reiter, Vorauswahl `TenantFramework.isPrimary`. Die Auswahl gehört in die URL (`?fw=iso`), damit
|
||||
Deep-Links und Berichte reproduzierbar sind.
|
||||
|
||||
**Harte Regel: keine gemischte Gesamtzahl.** Ein „Erfüllungsgrad 87 %" über beide Normen ist fachlich
|
||||
sinnlos — ein Reifegrad 0–3 und ein Umsetzungsstatus lassen sich nicht mitteln. Je Norm eine Kennzahl,
|
||||
immer getrennt ausgewiesen.
|
||||
|
||||
---
|
||||
|
||||
## 6. Vokabular
|
||||
|
||||
`REIFEGRAD_BANDS` (`readiness.ts:16`) ist TISAX-Sprache („Assessment-reif", „AL-Ziel"). Für ISO
|
||||
gehören eigene Bänder auf Basis des Umsetzungsgrads — Vorschlag:
|
||||
|
||||
| Anteil „umgesetzt" | Band | Aussage |
|
||||
|---|---|---|
|
||||
| < 50 % | Aufbau | wesentliche Maßnahmen noch offen |
|
||||
| 50–79 % | In Umsetzung | Struktur steht, Nachweise fehlen |
|
||||
| 80–99 % | Zertifizierungsnah | wenige offene Punkte, Wirksamkeitsnachweise ergänzen |
|
||||
| 100 % | Zertifizierungsreif | alle anwendbaren Controls umgesetzt und belegt |
|
||||
|
||||
**Ein ISO-Auditbericht darf nicht mit „Reifegrad 2,4" argumentieren.** Der Nachweis lautet
|
||||
„umgesetzt, hier ist der Beleg". Der Reifegrad bleibt unter ISO ein optionales Beratungsinstrument —
|
||||
sichtbar als Zusatzspalte, nie als Erfüllungsaussage (Entscheidung aus dem Fachgespräch, Variante 3).
|
||||
|
||||
---
|
||||
|
||||
## 7. Regressionsschutz
|
||||
|
||||
Die Extraktion der `TisaxStrategy` ist der riskanteste Teil. Absicherung **vor** dem Umbau:
|
||||
|
||||
1. **Snapshot erzeugen:** `buildControlRows` für den Demo-Mandanten (321 Anforderungen, 45 Controls)
|
||||
als JSON festhalten — Reifegradvorschlag, Zielwert, Belegstatus und offene Punkte je Control.
|
||||
2. **Nach dem Umbau vergleichen:** `buildAssessment(db, tenantId, "TISAX")` muss denselben Snapshot
|
||||
liefern. Abweichung = Regression, kein „ist besser geworden".
|
||||
3. Als `scripts/test-framework-assessment.ts` in der Hausform der übrigen `test-*.ts` ablegen.
|
||||
|
||||
Ergänzend unverändert gültig: `_verify.py`, `_verify_iso.py --lang de|en`, `_render_diff.py HEAD`,
|
||||
`test-framework-dryrun.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 7a. Priorisierung nach Kundenlage (Nachtrag 2026-08-27)
|
||||
|
||||
**Ist-Lage:** Die Mehrzahl der Mandanten führt TISAX, **ein** Mandant ISO, **keiner beide**.
|
||||
|
||||
Daraus folgt zweierlei:
|
||||
|
||||
1. **Das Regressionsrisiko dominiert.** Der riskanteste Teil ist nicht die ISO-Logik, sondern die
|
||||
verhaltensgleiche Extraktion der `TisaxStrategy` — sie betrifft alle Bestandsmandanten. Schritt 1
|
||||
(Snapshot) ist damit nicht Kür, sondern die wichtigste Einzelmaßnahme des ganzen Pakets.
|
||||
2. **Zwei Themen lassen sich zurückstellen** — beide betreffen ausschließlich den Doppel-Mandanten,
|
||||
den es heute nicht gibt:
|
||||
|
||||
| Zurückgestellt | Was entfällt vorerst | Wieder aufnehmen, wenn |
|
||||
|---|---|---|
|
||||
| **Schritt 7** — Vorbelegung über `ISO_TO_ISA` | Übernahmevorschlag aus dem jeweils anderen Framework | ein Mandant beide Normen führt |
|
||||
| **Schritt 8b** — Reiter-UI | Umschalter in `/soa` und `/audit-readiness`; bei einem aktiven Framework wird direkt angezeigt | ein Mandant beide Normen führt |
|
||||
|
||||
**Was dabei nicht zurückgestellt werden darf:** die **Strategie-Schnittstelle** und der
|
||||
**Framework-Parameter** in `buildAssessment`. Beide kosten jetzt fast nichts und sind später teuer
|
||||
nachzurüsten, weil sonst 7 Aufrufstellen erneut angefasst werden müssen. Die Architektur bleibt
|
||||
zweigleisig, nur die Oberfläche zeigt vorerst ein Gleis.
|
||||
|
||||
Erwartete Wirkung auf den Aufwand: **5–8 PT → 4–6 PT.**
|
||||
|
||||
---
|
||||
|
||||
## 8. Arbeitsschritte
|
||||
|
||||
| # | Schritt | Ergebnis |
|
||||
|---|---|---|
|
||||
| **1** | Snapshot-Test der heutigen TISAX-Ausgabe | Regressionsnetz steht, **vor** jedem Umbau |
|
||||
| **2** | `ControlSpec` einführen, `loadEvidenceResolver` darauf umstellen | Belegbasis framework-neutral, TISAX unverändert |
|
||||
| **3** | `_generate_iso.py` erzeugt `control-specs-iso.ts` | ISO-Specs aus dem Mapping, keine Zweitpflege |
|
||||
| **4** | `FrameworkStrategy` + `TisaxStrategy` (reine Extraktion) | Snapshot grün |
|
||||
| **5** | `IsoStrategy` (Scope aus SoA, Status statt Reifegrad) | ISO-Bewertung rechnet |
|
||||
| **6** | `buildAssessment(db, tenantId, framework)` ersetzt `buildControlRows` | 7 Dateien rufen es direkt, 13 hängen an der Assessment-Logik insgesamt |
|
||||
| ~~**7**~~ | ~~Vorbelegung über `ISO_TO_ISA`~~ | **zurückgestellt** — betrifft nur Doppel-Mandanten (§7a) |
|
||||
| **8a** | ISO-Readiness-Bänder und framework-richtige Beschriftung | ISO-Mandant sieht ISO-Vokabular |
|
||||
| ~~**8b**~~ | ~~Reiter in `/soa` und `/audit-readiness`~~ | **zurückgestellt** (§7a) |
|
||||
| **9** | ISO-Exporte: SoA + Annex-A-Gap | Managementbewertung hat ihre Eingabe |
|
||||
|
||||
Schritte 1–4 sind Pflicht und hängen aneinander. 5–9 sind danach teilbar.
|
||||
|
||||
---
|
||||
|
||||
## 9. Definition of Done
|
||||
|
||||
| Prüfung | Erwartung |
|
||||
|---|---|
|
||||
| Snapshot-Test TISAX | 0 Abweichungen zur Ausgabe vor dem Umbau |
|
||||
| Reiner ISO-Mandant | Readiness und SoA rechnen; keine AL-, Prüfziel- oder Reifegrad-Begriffe in der Oberfläche |
|
||||
| Reiner TISAX-Mandant | Verhalten und Beschriftung unverändert |
|
||||
| Doppel-Mandant | *zurückgestellt* — Architektur trägt es, Oberfläche zeigt es noch nicht (§7a) |
|
||||
|
||||
| ISO-Delta | die 33 Anforderungen ohne ISA-Gegenstück sind als eigene Liste ausweisbar |
|
||||
| Gate | `tsc`, `lint`, `build`, `_verify*`, `_render_diff`, beide Testskripte grün |
|
||||
|
||||
---
|
||||
|
||||
## 10. Aufwand und Risiken
|
||||
|
||||
**Aufwand:** 4–6 PT im vorgezogenen Umfang (§7a), 5–8 PT vollständig. Schwerpunkt liegt auf Schritt 4 (verhaltensgleiche Extraktion) und Schritt 8
|
||||
(zwei Sichten statt einer), nicht auf der ISO-Logik selbst — die ist schlank.
|
||||
|
||||
| Risiko | Gegenmaßnahme |
|
||||
|---|---|
|
||||
| TISAX-Regression bei der Extraktion | Snapshot-Test **vor** Schritt 2 anlegen, als Merge-Gate setzen |
|
||||
| Belegbasis wandert versehentlich in die Strategie | Review-Kriterium: `loadEvidenceResolver` darf `FrameworkKey` nicht kennen |
|
||||
| Gemischte Kennzahlen schleichen sich in die UI | `ReadinessSummary` je Framework typisieren, keine Aggregation über beide |
|
||||
| ISO-Scope hängt an gepflegter SoA | leere SoA → Readiness meldet „Anwendbarkeit noch nicht erklärt" statt 0 % |
|
||||
| Doppelte Datenpflege beim Doppel-Mandanten | Schritt 7 ist nicht optional |
|
||||
|
||||
---
|
||||
|
||||
## 11. Was ausdrücklich **nicht** gebaut wird
|
||||
|
||||
- Kein Reiter über Richtlinien, Nachweisen, Assets, Risiken oder Aufgaben.
|
||||
- Keine gemeinsame Kennzahl über beide Frameworks.
|
||||
- Kein Reifegrad als ISO-Erfüllungsaussage (optionale Zusatzspalte ja, Bewertungsgrundlage nein).
|
||||
- Keine Änderung an der VDA-ISA-Logik über die reine Extraktion hinaus.
|
||||
- Kein Umbau von `readiness.ts`/`gap-consolidation.ts` — die Rechen-Engines sind numerisch
|
||||
standard-agnostisch und werden von beiden Strategien gefüttert.
|
||||
@@ -0,0 +1,219 @@
|
||||
# Feindesign & Implementierungsplan — Zentrale Identität + Mandanten-Mitgliedschaften (certvia)
|
||||
|
||||
> Produkt: **certvia** (ISMS-Tool). Grundlage: [KONZEPT-identity-mandanten.md](KONZEPT-identity-mandanten.md) (Option C, Entscheidungen A–E + Two-Step-Login + Passphrasen). Dieses Dokument ist der **umsetzbare Bauplan** für ein mehrköpfiges, noch zu onboardendes Entwicklerteam inkl. PM. Alle Datei:Zeile-Angaben beziehen sich auf Branch `dev`.
|
||||
|
||||
## 0. Wie dieses Dokument zu lesen ist
|
||||
- **PM:** §7 (Meilensteine), §8 (Risiken), §9 (DoD), §11 (Rollen/Cadence), §12 (Aufwand).
|
||||
- **Entwickler:** §1–§6 (Feindesign), §10 (Onboarding + „Goldene Regeln").
|
||||
- **Alle:** §1 ist die eine Leitentscheidung, aus der alles Weitere folgt.
|
||||
|
||||
---
|
||||
|
||||
## 1. Leitentscheidung (das Sicherheitsnetz): `User.id` bleibt stabil
|
||||
Wir führen **nicht** eine große Umverkabelung durch. Stattdessen:
|
||||
- **`User` bleibt** die per-Mandant-Zeile (jetzt gedanklich „Mitgliedschaft") mit **derselben `id`** und **derselben `tenantId`**.
|
||||
- Wir **schneiden nur die Auth-Felder heraus** in eine neue globale **`Identity`** und hängen `User.identityId → Identity.id` an.
|
||||
- In der Session bleibt **`session.user.tenantId`** erhalten — es zeigt künftig auf den **aktiven** Mandanten. Dadurch bleiben **~356 `dbForTenant(session.user.tenantId)`-Stellen, alle 6 Owner-FKs (`assets/processes/risks/measures.owner_id`, `user_roles`, `webauthn`) und das RLS-Modell unangetastet.**
|
||||
|
||||
**Folge:** Der Umbau konzentriert sich auf **Login, Session-Aufbau, Mandantenauswahl, Nutzer-Lifecycle** — nicht auf die 356 Fachstellen. Das ist die risikoärmste Schneise.
|
||||
|
||||
> **Zusatz-Vereinfachung (Entscheidung D):** Es gibt **keinen Produktivdatenbestand** (nur Testdaten). Deshalb **kein Backfill/Merge**, sondern **Schema-Neuschnitt + Reseed**. Der aufwändigste und riskanteste Teil eines solchen Umbaus entfällt komplett.
|
||||
|
||||
---
|
||||
|
||||
## 2. Zieldatenmodell (konkret)
|
||||
|
||||
**Neu — `Identity` (global, KEIN `tenantId`, NICHT in `TENANT_MODELS`):**
|
||||
`id, email @unique, passwordHash, mustChangePassword, mfaSecret, mfaEnrolledAt, recoveryCodes, lastTotpStep, failedLogins, lockedUntil, sessionsValidAfter, status, createdAt, updatedAt`.
|
||||
→ Übernimmt exakt die Felder, die heute in `User` (`schema.prisma:98-139`) und `PlatformAdmin` doppelt liegen.
|
||||
|
||||
**Geändert — `User` = Mitgliedschaft (bleibt in `TENANT_MODELS`, behält `tenantId`+`id`):**
|
||||
- **entfernt** (wandern zu Identity): `passwordHash, mfaSecret, mfaEnrolledAt, recoveryCodes, lastTotpStep, failedLogins, lockedUntil, mustChangePassword, sessionsValidAfter, isPlatformAdmin`.
|
||||
- **neu:** `identityId → Identity`.
|
||||
- **bleibt:** `tenantId, name, status: UserStatus, userRoles`, alle Ownership-Relationen. `@@unique([tenantId, email])` → ersetzt durch `@@unique([tenantId, identityId])` (eine Person max. 1 Mitgliedschaft je Mandant); `email` bleibt als Denormalisierung optional oder entfällt (Quelle = Identity).
|
||||
|
||||
**`WebAuthnCredential`** (`schema.prisma:143-160`): `userId → identityId`, `tenantId` entfällt → **raus aus `TENANT_MODELS`**, RLS-Policy der Tabelle entfernen (Passkeys sind identitäts-, nicht mandantengebunden).
|
||||
|
||||
**`AuthToken`** (`schema.prisma:1679-1700`): `principalType/principalId` → auf `identity` umstellen; neuer `TokenType: "invitation"` (heute wird `password_reset` mit 7-Tage-TTL zweckentfremdet).
|
||||
|
||||
**`PlatformAdmin`** (`schema.prisma:211-234`): **bleibt getrennt** (Entscheidung E). *Option (empfohlen, klein):* eine Identity kann zusätzlich Plattform-Admin sein → `PlatformAdmin.identityId` als Verweis, Store aber getrennt. Nicht zwingend für Phase 1.
|
||||
|
||||
**`TENANT_MODELS` (`db.ts:81-148`):** `Identity` **nicht** aufnehmen (globaler Lookup über Owner-`prisma`, wie heute der Login). `WebAuthnCredential` **entfernen**. `User` **bleibt** drin.
|
||||
|
||||
---
|
||||
|
||||
## 3. Session-/Token-Shape (neu)
|
||||
|
||||
**JWT/Session (`next-auth.d.ts` erweitern):**
|
||||
```
|
||||
identityId
|
||||
activeTenantId → gespiegelt als session.user.tenantId (⇒ 356 Call-Sites unverändert!)
|
||||
activeMembershipId (= User.id des aktiven Mandanten)
|
||||
memberships[] [{ tenantId, tenantSlug, membershipId, tenantName }] (schlanke Liste für den Switcher)
|
||||
permissions[] (des AKTIVEN Mandanten)
|
||||
tenantSlug (des aktiven Mandanten)
|
||||
isPlatformAdmin, mfaEnrolled, tokenIssuedAt
|
||||
```
|
||||
|
||||
**Kritische Regel:** `session.user.tenantId === activeTenantId`, immer **genau ein** aktiver Mandant. Kippt das (leer/mehrdeutig), kippt der RLS-Kontext → Fail-closed.
|
||||
|
||||
**Konsumenten anpassen (aber minimal):**
|
||||
- `auth.ts` jwt/session-Callbacks (`:276-299`): neue Felder setzen, `tenantId` = aktiver Mandant.
|
||||
- `action-guard.ts:29-84` und `(app)/layout.tsx:37-120`: `sessionsValidAfter` künftig aus **Identity** lesen; Permissions bei **Mandantenwechsel** neu auflösen (heute beim Login eingefroren).
|
||||
- `rbac.ts` (`hasPermission/requirePermission`, 43 Konsumenten): unverändert — liest weiter `session.user.permissions`, die aber pro aktivem Mandant befüllt werden.
|
||||
- `proxy.ts`: neuer Pfad `/select-tenant` in Post-Login-Gate; „angemeldet, aber kein aktiver Mandant → `/select-tenant`".
|
||||
|
||||
---
|
||||
|
||||
## 4. Die Flows (Feindesign)
|
||||
|
||||
### 4.1 Login (Two-Step, MFA beim Login) — `login/page.tsx`, `auth.ts`
|
||||
1. **Seite 1: E-Mail + Passwort** (Feld „Organisation" **entfällt**). `signIn` gegen **Identity** (`auth.ts:96` von `user.findMany` auf `identity.findUnique({email})` umstellen; Lockout/Dummy-Verify bleiben).
|
||||
2. **MFA-pending-Zustand:** kurzlebiger, signierter, einzweckiger Server-State (kein voller Session-Cookie). Realisierung: eigener NextAuth-Step oder ein `mfa_pending`-JWT mit 5 min TTL, das nur `/login/mfa` bedient.
|
||||
3. **Seite 2: MFA** — angezeigt, wenn Identity MFA hat **oder** ≥ 1 Mitgliedschaft in MFA-Pflicht-Mandant. TOTP/Passkey verifizieren (`mfa.ts:47`, Replay via Identity.`lastTotpStep`) oder Enroll erzwingen.
|
||||
4. **Volle Session** ausstellen (Identity + MFA erfüllt), `memberships[]` laden.
|
||||
5. **Weiterleitung:** 1 Mitgliedschaft → direkt `/dashboard` (activeTenant gesetzt); mehrere → `/select-tenant`; keine → Hinweisseite.
|
||||
|
||||
### 4.2 Mandantenauswahl & -Wechsel — neu: `/select-tenant` + Action `setActiveTenant`
|
||||
- Server Action `setActiveTenant(membershipId)`: **(1)** Membership gehört zur Session-Identity? **(2)** Mitgliedschaft+Mandant ACTIVE? **(3)** `sessionsValidAfter` ok? **(4)** MFA-Netz: verlangt Zielmandant MFA und nicht erfüllt → Enroll. Dann Token neu prägen: `activeTenantId/activeMembershipId/permissions/tenantSlug`.
|
||||
- **Sicherheitskontrollen (Pflicht):** aktiver `tenantId` **server-autoritativ** (nie Client-Input); Re-Validierung bei jedem Wechsel; **Audit** „Identity → Mandant". (Siehe §8.)
|
||||
- **Tenant-Switcher** in `(app)/layout.tsx` (Kopf/Sidebar) → ruft `setActiveTenant`.
|
||||
|
||||
### 4.3 Einladung (Standard-Anlageweg) — `auth-selfservice.ts`, `auth-token.ts`, neue Seite `/invite`
|
||||
- Neuer **`TokenType: "invitation"`** + Zielseite **`/invite?token=`** (Erst-Passwort + optional MFA **auf der Identity** setzen), statt Zweckentfremdung von `/reset`.
|
||||
- **Neutralität:** Der einladende Admin sieht **immer** „Einladung gesendet" — unabhängig davon, ob die Identity schon existierte (kein Cross-Tenant-Leak).
|
||||
- Existiert die Identity → Mail „Sie wurden zu Mandant X hinzugefügt" + **Bestätigungslink** (Beitritt annehmen). Existiert nicht → „Konto einrichten + beitreten".
|
||||
|
||||
### 4.4 Nutzeranlage
|
||||
- **Plattform** (`platform-users.ts:89`): `createTenantUser` → Identity finden/erstellen + Membership + Rollen; **`pwMode "set"` + Fallback-Passwort entfernen**; Betreiber darf direkt verknüpfen.
|
||||
- **Kunde** (`tenant-users.ts:139`): `createUser` → **immer Einladung**; „Passwort setzen"-Zweig raus.
|
||||
- **Onboarding-Wizard** (`onboarding-team.ts:166`): `inviteFunctionHolder` → Identity-Einladung statt User+Passwort.
|
||||
- **UI** (`user-forms.tsx`): pwMode-Auswahl entfällt → reines Einladungsformular (Name, E-Mail, Rollen).
|
||||
|
||||
### 4.5 MFA-Pflicht-Durchsetzung (Mandanten-Policy trifft Identity-MFA)
|
||||
- Gates umstellen: `(app)/layout.tsx:73-79`, `enroll-mfa/page.tsx:24-32`, `(platform)/layout.tsx:27` → prüfen **Identity.mfaEnrolledAt** statt `User`.
|
||||
- `mfa-policy.ts:7` (`resolveMfaRequired`, mandantenweit) bleibt. Regel: **strengster betretener Mandant gewinnt**; da MFA an der Identity hängt, deckt eine Einrichtung alle ab.
|
||||
|
||||
### 4.6 Passwort/MFA-Reset → Identity-Ebene, raus aus Mandantenverwaltung
|
||||
- **Entfernen:** `platform-users.ts:152` (`resetTenantUserPassword`), `tenant-users.ts:207` (`resetUserPassword`) + UI-Bindungen (`admin/[id]/page.tsx:205`, `settings/users/page.tsx:105`). Ersatz: Identity-Self-Service (Recovery-Codes) + Plattform-Ebene.
|
||||
- **Umleiten auf Identity:** `auth-recovery.ts` (gesamt), `account.ts:66` (`changeOwnPassword`), `sessions.ts:34/92` (`sessionsValidAfter` an Identity), `webauthn.ts:73` (Passkey an Identity), `secret-crypto.ts`-Nutzung unverändert (Schlüssel bleibt).
|
||||
|
||||
---
|
||||
|
||||
## 5. Migrationsstrategie (DB)
|
||||
Dank Entscheidung D **kein Backfill**. Ablauf:
|
||||
1. **Schema-Recut** in `schema.prisma`: `Identity` neu, `User` verschlanken (+`identityId`), `WebAuthnCredential`/`AuthToken` umhängen.
|
||||
2. **Forward-Migration(en):** `identities` (ohne RLS/Policy!), `users`-Spalten entfernen + `identity_id` FK, `webauthn_credentials` `tenant_id`/Policy entfernen + `identity_id`, `auth_tokens` principal-Umbau. RLS-Policies der betroffenen Tabellen anpassen (analog `rls_enforce`-Muster, `20260730160000`).
|
||||
3. **`db.ts`:** `TENANT_MODELS` anpassen (Identity raus lassen, WebAuthn entfernen).
|
||||
4. **Reseed:** `prisma/seed.ts`, `provision.ts`, `bootstrap-admin.ts`, `sync-role-permissions.ts` auf Identity+Membership. Testumgebung frisch aufsetzen.
|
||||
|
||||
> Für die Test-/Coolify-Instanz: einmalig **DB leeren** (nur Testdaten) → `migrate deploy` → Seed. Kein Sonderpfad nötig.
|
||||
|
||||
---
|
||||
|
||||
## 6. Arbeitspakete (Workstreams) für das Team
|
||||
|
||||
| WS | Inhalt | Kernfiles | Abhängig von |
|
||||
|---|---|---|---|
|
||||
| **WS0 Fundament** | `Identity`-Modell, Schema-Recut, Migrationen, `TENANT_MODELS`, RLS-Anpassung WebAuthn | `schema.prisma`, `prisma/migrations/*`, `db.ts` | — (Blocker) |
|
||||
| **WS1 Auth-Kern** | Login gegen Identity, Two-Step + MFA-pending, Token/Session-Shape, jwt/session-Callbacks | `auth.ts`, `next-auth.d.ts` | WS0 |
|
||||
| **WS2 Mandantenkontext** | `/select-tenant`, `setActiveTenant`, Tenant-Switcher, Guards + Permissions bei Wechsel, `proxy.ts` | `action-guard.ts`, `(app)/layout.tsx`, `proxy.ts`, `rbac.ts` | WS1 |
|
||||
| **WS3 Einladungs-Lifecycle** | `invitation`-Token, `/invite`-Seite, Anlage überall auf Einladung, „Passwort setzen" raus | `auth-token.ts`, `auth-selfservice.ts`, `platform-users.ts`, `tenant-users.ts`, `onboarding-team.ts`, `user-forms.tsx` | WS0 |
|
||||
| **WS4 Passwort/MFA an Identity** | Reset/Change/Email-Change, MFA/Passkey/Recovery, Sessions-Invalidierung, Reset raus aus Mgmt | `auth-recovery.ts`, `account.ts`, `sessions.ts`, `webauthn.ts`, `platform.ts` | WS0 |
|
||||
| **WS5 UI** | Login-Seiten (2-stufig), `/select-tenant`, Switcher, Einladungsformulare | `login/*`, neue Seiten, `(app)/layout.tsx` | WS1, WS2 |
|
||||
| **WS6 Seed/Provision/Bootstrap** | Reseed auf Identity, `provision.ts`, `bootstrap-admin.ts`, `sync-role-permissions.ts` | genannte | WS0 |
|
||||
| **WS7 Tests & Gate** | neue `scripts/test-*`: Identity-Login, Tenant-Switch-Isolation, MFA-Enforcement multi-tenant, Einladung, Two-Step-Bypass | `scripts/test-*.ts` | fortlaufend |
|
||||
|
||||
**Parallelisierung:** Nach **WS0** laufen **WS1, WS3, WS4, WS6** parallel. **WS2** setzt auf WS1, **WS5** auf WS1+WS2. **WS7** durchgehend (jede Story bringt ihren Test mit).
|
||||
|
||||
---
|
||||
|
||||
## 7. Meilensteine (PM-Sicht)
|
||||
| M | Ergebnis (Demo-fähig) | umfasst |
|
||||
|---|---|---|
|
||||
| **M0** | Onboarding abgeschlossen, Dev-Umgebungen laufen, Gate grün | §10 |
|
||||
| **M1** | Fundament: Schema+Migration+Reseed grün, RLS-Tests grün | WS0, WS6, WS7-Basis |
|
||||
| **M2** | Login gegen Identity (Two-Step) + Single-Membership-Nutzer landet im Dashboard | WS1, WS5-Login |
|
||||
| **M3** | Multi-Membership: Auswahl + Wechsel + MFA-Netz + Isolation nachgewiesen | WS2, WS5-Switcher, WS7-Isolation |
|
||||
| **M4** | Einladungs-Lifecycle (Plattform+Kunde+Wizard), „Passwort setzen" entfernt | WS3 |
|
||||
| **M5** | Passwort/MFA-Reset auf Identity, Reset raus aus Mandantenverwaltung | WS4 |
|
||||
| **M6** | Härtung, vollständige Test-Suite, Doku, STAND aktualisiert, Deploy | WS7, Doku |
|
||||
|
||||
---
|
||||
|
||||
## 8. Risiken & Gegenmaßnahmen
|
||||
| Risiko | Gegenmaßnahme |
|
||||
|---|---|
|
||||
| **RLS kippt**, wenn kein/mehrdeutiger aktiver Mandant | `session.user.tenantId` immer = genau **eine** validierte Membership; fail-closed; Guard wirft bei leer |
|
||||
| **356 Call-Sites** anfassen | Leitentscheidung §1: `User.id` + `session.user.tenantId`-Semantik erhalten → Call-Sites unverändert |
|
||||
| **Two-Step „halb angemeldet"-Bypass** | MFA-pending-State ist einzweckig + kurzlebig, **keine** App-Session vor MFA |
|
||||
| **Rechte veraltet** bei Wechsel ohne Re-Login | `setActiveTenant` löst Permissions **neu** auf (nicht Token-eingefroren) |
|
||||
| **Breiterer Blast-Radius** eines Credentials | starke Passphrase-Policy + MFA + kurze Session + globaler Kill-Switch (`Identity.sessionsValidAfter`) |
|
||||
| **Plattform/Tenant-Cookie-Kollision** | bereits gelöst (getrennte Cookie-Namen, `platform-auth.ts`) — beibehalten |
|
||||
| **Team nicht eingearbeitet** | M0-Onboarding als eigener Meilenstein, „Goldene Regeln" §10, Pair auf WS0 |
|
||||
|
||||
---
|
||||
|
||||
## 9. Definition of Done
|
||||
**Pro Story:** tsc + lint + build grün · zugehöriges `scripts/test-*.ts` grün · keine neuen `dbForTenant`-Regressionen · Doku-Schnipsel im PR.
|
||||
**Gesamt (M6):** alle `scripts/test-*` grün (inkl. **neuer** Isolations-/Enforcement-Tests) · Login/Auswahl/Wechsel/Einladung/Reset im Browser verifiziert · RLS-Test mit Multi-Membership-Nutzer nachweist, dass Wechsel **keine** Fremddaten sichtbar macht · `docs/STAND-dev-branch.md` + dieses Doc aktualisiert · sauber nach `dev` (beide Remotes) integriert.
|
||||
|
||||
---
|
||||
|
||||
## 10. Onboarding der neuen Entwickler (M0)
|
||||
**Pflichtlektüre (in dieser Reihenfolge):** `docs/HANDOVER-DEV.md` → `docs/SPEC.md` → `docs/STAND-dev-branch.md` → dieses Doc → [KONZEPT-identity-mandanten.md](KONZEPT-identity-mandanten.md).
|
||||
|
||||
**Dev-Setup:** Node + Postgres (pgvector-Image), `.env` aus `.env.example`, `npx prisma migrate deploy`, Demo-Seed (`RUN_DEMO_SEED`), `npm run dev`. Demo-Logins in `prisma/seed.ts`.
|
||||
|
||||
**Validierungs-Gate (vor jedem PR):** `npx tsc --noEmit` · `npm run lint` · `npm run build` · **alle 17 `scripts/test-*.ts`**.
|
||||
|
||||
**RLS-Mentalmodell (Pflichtverständnis):** `dbForTenant(tenantId)` setzt pro Transaktion `app.tenant_id`; `TENANT_MODELS` sagt, welche Modelle mandantengefiltert sind; globale Modelle (Kataloge, künftig `Identity`) laufen über den Owner-`prisma`. **Nie** ein globales Modell in `TENANT_MODELS` aufnehmen und **nie** ein tenant-Modell ohne Kontext lesen.
|
||||
|
||||
**DevOps-Workflow:** Feature-Branch → `git merge --no-ff` nach `dev` → Gate grün → Push auf **beide** Remotes (`origin` = git.certvia.de, `local-gitea`) → `docs/STAND-dev-branch.md` pflegen. (certvia ist strikt getrennt von anderen Produkten — nichts vermischen.)
|
||||
|
||||
**Goldene Regeln dieses Umbaus:**
|
||||
1. `User.id` = Mitgliedschaft, **stabil lassen**. Auth-Felder leben auf `Identity`.
|
||||
2. `Identity` ist **global**, **nicht** in `TENANT_MODELS`, kein `tenant_id`, keine RLS-Policy.
|
||||
3. Genau **ein** aktiver Mandant pro Session; server-autoritativ; bei Wechsel re-validieren.
|
||||
4. **Keine** „Passwort direkt setzen"-Anlage mehr — nur Einladung.
|
||||
5. MFA/Passwort gehören der Identity — **kein** Mandanten-Admin-Reset.
|
||||
|
||||
---
|
||||
|
||||
## 11. Rollen & Cadence (Beispielbesetzung: 1 Lead + 2 Devs + PM)
|
||||
| Rolle | Verantwortung |
|
||||
|---|---|
|
||||
| **Tech-Lead / Senior** | WS0 + WS1 (Fundament + Auth-Kern), Review aller Auth-/RLS-PRs, Sicherheitskontrollen §8 |
|
||||
| **Dev A** | WS2 (Mandantenkontext/Guards) + WS5 (UI) |
|
||||
| **Dev B** | WS3 (Einladung) + WS4 (Passwort/MFA an Identity) + WS6 (Seed) |
|
||||
| **alle** | WS7 (jede Story bringt ihren Test) |
|
||||
| **PM** | Meilenstein-Tracking (§7), Risiken (§8), DoD-Abnahme (§9), Entscheidungs-Eskalation (Phase-2-Punkte), Cadence |
|
||||
|
||||
**Cadence-Vorschlag:** WS0 als **Pairing** (Lead + je 1 Dev) — dient zugleich als Onboarding-Vehikel; danach 2-Wochen-Iterationen entlang M1–M6, Demo je Meilenstein, PR-Review verpflichtend für Auth/RLS.
|
||||
|
||||
---
|
||||
|
||||
## 12. Aufwandsschätzung (grob, Personentage)
|
||||
> Annahme: 3 Devs, noch nicht eingearbeitet → Ramp-up eingepreist. Ohne Produktivdaten-Migration (Entscheidung D).
|
||||
|
||||
| Block | PT (Bereich) |
|
||||
|---|---|
|
||||
| M0 Onboarding (3 Personen) | 6–9 |
|
||||
| WS0 Fundament + Migration + Reseed | 5–8 |
|
||||
| WS1 Auth-Kern (Two-Step, Session-Shape) | 8–12 |
|
||||
| WS2 Mandantenkontext + Guards + Switcher | 6–9 |
|
||||
| WS3 Einladungs-Lifecycle | 5–8 |
|
||||
| WS4 Passwort/MFA an Identity | 6–9 |
|
||||
| WS5 UI | 4–6 |
|
||||
| WS6 Seed/Provision/Bootstrap | 2–4 |
|
||||
| WS7 Tests & Härtung | 5–8 |
|
||||
| **Summe** | **≈ 47–73 PT** |
|
||||
|
||||
**Kalenderdauer** bei 3 Devs mit Parallelisierung (§6) + PM-Overhead: **≈ 5–7 Wochen** bis M6 (inkl. Onboarding-Woche). Kritischer Pfad: **WS0 → WS1 → WS2 → WS5**. WS3/WS4/WS6 laufen daneben.
|
||||
|
||||
---
|
||||
|
||||
## 13. Phase 2 (bewusst später, kein Blocker)
|
||||
- Per-Mandant-Schalter „bei jedem Betreten Step-up erzwingen" (Hochsicherheits-Kunden).
|
||||
- E-Mail-Änderung als Identity-Operation (Sonderfälle/Merge).
|
||||
- Optionale Konsolidierung `PlatformAdmin` in die `Identity` (Store getrennt lassen, nur Verweis).
|
||||
@@ -0,0 +1,150 @@
|
||||
# ISO/IEC 27001:2022 auf der gemeinsamen Dokumentenbibliothek (Variante A)
|
||||
|
||||
**Stand:** 2026-08-27 · **Paket:** `seed/isms-vorlagenpaket-v2` (+ `-en`) · **Status:** umgesetzt, ISB-Freigabe offen
|
||||
|
||||
> **Entscheidung:** Ein Dokumentensatz, zwei Framework-Mappings. Die bestehenden Richtlinien und
|
||||
> Verfahren bleiben die einzige Quelle; ISO/IEC 27001 wird als zweites Mapping darübergelegt.
|
||||
> Damit ersetzt diese Umsetzung die ursprüngliche Annahme aus `KONZEPT-framework-iso27001.md`
|
||||
> (D4: zweites Seed-Paket `seed/isms-iso27001-v1/`).
|
||||
|
||||
---
|
||||
|
||||
## 1. Warum nicht zwei Pakete
|
||||
|
||||
`PolicyDocument` ist über `@@unique([tenantId, code])` eindeutig. Zwei Pakete mit denselben
|
||||
Dokument-Codes (`L00`, `R01`…`R14`, `VA-01`…`VA-20`) können in einem Mandanten nicht nebeneinander
|
||||
existieren — der zweite Import überschreibt beim Upsert den Inhalt des ersten und archiviert die
|
||||
Dokumente, die im anderen Paket fehlen. Für einen Mandanten mit ISO **und** TISAX wäre das Ergebnis
|
||||
das Gegenteil der Absicht.
|
||||
|
||||
Hinzu kommt der fachliche Punkt: Die Umsetzungsbeschreibung („Umsetzung bei {{ORG_NAME}}") ist
|
||||
normunabhängig. Wie eine Organisation Berechtigungen vergibt, ändert sich nicht dadurch, ob ISO oder
|
||||
VDA ISA danach fragt. Sie zweimal zu pflegen erzeugt Widersprüche.
|
||||
|
||||
## 2. Aufbau
|
||||
|
||||
| Bestandteil | Rolle |
|
||||
|---|---|
|
||||
| `richtlinien/`, `verfahren/` | **gemeinsame** Dokumente — ein Umsetzungstext je Thema |
|
||||
| `mapping.json` | Framework-Mapping **VDA ISA 2027** (321 Anforderungen) |
|
||||
| `mapping-iso.json` | Framework-Mapping **ISO/IEC 27001:2022** (120 Anforderungen) |
|
||||
| `_iso_crosswalk.json` | fachliche Zuordnung ISO-Anforderung → Dokument + Abschnitt (redaktionell) |
|
||||
| `_iso_sections.json` / `_iso_sections_en.json` | Texte der ISO-only-Abschnitte (redaktionell, je Sprache) |
|
||||
| `_iso_texts_en.json` | englische Anforderungstexte (Struktur bleibt im Crosswalk) |
|
||||
| `_generate_iso.py` | erzeugt aus beidem die Dokument-Patches, `mapping-iso.json` und die SoA |
|
||||
| `_verify.py` / `_verify_iso.py` | prüfen je eine Framework-Sicht |
|
||||
| `Statement-of-Applicability-ISO.md` | SoA-Gerüst mit den Pflichtangaben aus 6.1.3 d) |
|
||||
|
||||
### Sichtbarkeitssteuerung über Platzhalter
|
||||
|
||||
Zwei neue Flags in `variables.schema.json` steuern, welche Anforderungssicht ein Mandant sieht:
|
||||
|
||||
| Flag | Default | Wirkung |
|
||||
|---|---|---|
|
||||
| `FLAG_FW_TISAX` | `true` | VDA-ISA-Anforderungsblöcke sichtbar |
|
||||
| `FLAG_FW_ISO27001` | `false` | ISO-Anforderungsblöcke und ISO-only-Abschnitte sichtbar |
|
||||
|
||||
Im Dokument sieht das so aus — der Umsetzungstext steht **einmal** und gilt für beide:
|
||||
|
||||
```markdown
|
||||
### 3.2 Sichere Anmeldung
|
||||
|
||||
*Anforderungsbezug:* {{#if FLAG_FW_TISAX}}VDA ISA 4.1.2{{/if}}{{#if FLAG_FW_ISO27001}}{{#if FLAG_FW_TISAX}} · {{/if}}ISO/IEC 27001 A.8.5{{/if}}
|
||||
|
||||
**Anforderung**
|
||||
|
||||
{{#if FLAG_FW_TISAX}}
|
||||
- **[MUSS]** Verfahren zur Benutzerauthentifizierung nach dem Stand der Technik werden angewandt.
|
||||
{{/if}}
|
||||
{{#if FLAG_FW_ISO27001}}
|
||||
- **[ISO A.8.5]** Sichere Authentisierungstechnologien und -verfahren sind einzusetzen.
|
||||
{{/if}}
|
||||
|
||||
**Umsetzung bei {{ORG_NAME}}**
|
||||
|
||||
<!-- IMPL 4.1.2 -->
|
||||
Die Authentifizierungsverfahren sind risikobasiert ausgewählt … Passwortvorgaben nach BL-IAM-01 …
|
||||
```
|
||||
|
||||
Beide Mappings zeigen mit `impl_anchor` auf denselben Block `IMPL 4.1.2`.
|
||||
|
||||
## 3. Abdeckung
|
||||
|
||||
- **120 ISO-Anforderungen:** 27 Klauseln (Kap. 4–10, inkl. 6.3 aus Amd 1:2024) + 93 Anhang-A-Controls
|
||||
in der Verteilung 37/8/14/34.
|
||||
- **43 Abschnitte** der Bibliothek werden von beiden Frameworks genutzt.
|
||||
- **19 ISO-only-Abschnitte** wurden ergänzt, wo VDA ISA kein Gegenstück hat:
|
||||
|
||||
| Dokument | Neue Abschnitte | ISO-Bezug |
|
||||
|---|---|---|
|
||||
| L00 | Politik, Ziele, Kommunikation | 5.2, 6.2, 7.4, A.5.1 |
|
||||
| R01 | Kontext/Scope · Änderungsplanung · Dokumentenlenkung · Behördenkontakte | 4.1–4.4, 6.3, 7.5.1–7.5.3, A.5.5, A.5.6 |
|
||||
| R02 | Datenmaskierung | A.8.11 |
|
||||
| R03 | SoA · Betriebliche Planung · Messung · Managementbewertung · CAPA | 6.1.3, 8.1, 9.1, 9.3, 10.1, 10.2 |
|
||||
| R05 | Vorgehen bei Verstößen | A.6.4 |
|
||||
| R07 | Umgebungsschutz/Versorgung/Verkabelung/Wartung · Clear Desk | A.7.5, A.7.7, A.7.8, A.7.11–A.7.13 |
|
||||
| R10 | Bedrohungsinformationen · Betriebsabläufe · Kapazität · Datenabfluss · Zeitsynchronisation | A.5.7, A.5.37, A.8.6, A.8.12, A.8.17 |
|
||||
|
||||
Die neuen Abschnitte sind ausschließlich über Platzhalter individualisierbar — wie die
|
||||
Bestandstexte. Dafür kamen elf Variablen und acht Baseline-Parameter hinzu
|
||||
(`BL-OPS-10/11/12`, `BL-NET-03`, `BL-PHY-03/04`, `BL-GOV-02/03`).
|
||||
|
||||
**Ohne ISO-Bezug** bleibt nur der Abschnitt „Nutzung von KI-/GenAI-Diensten" (eigene Ergänzung) sowie
|
||||
die Dokumente `P01` (Prototypenschutz) und `D01` (Datenschutz-Prüfziel) — beides TISAX-spezifisch.
|
||||
|
||||
## 4. Änderungen am Anwendungscode
|
||||
|
||||
Zwei Stellen, beide klein und rückwärtskompatibel:
|
||||
|
||||
1. **`prisma/import-policies.ts`** — der Umsetzungstext wird jetzt über `impl_anchor` aufgelöst
|
||||
(`IMPL 4.1.2`), mit Rückfall auf die Anforderungs-ID und auf ein `implementation`-Feld im Mapping.
|
||||
*Nebeneffekt:* Das behebt einen Bestandsfehler. Bisher wurde `implMap.get(a.id)` gesucht — die
|
||||
Anforderungs-IDs (`4.1.2-M1`) haben aber keinen eigenen IMPL-Block, sodass **alle 321**
|
||||
VDA-ISA-Anforderungen mit leerem Umsetzungstext importiert wurden. Sichtbar war das u. a. in der
|
||||
Spalte „Umsetzung" unter `/policies` und in der Plattform-Vorlagenverwaltung. Nach der Korrektur
|
||||
bleiben 12 leere Einträge (L00 — die Leitlinie hat bewusst keine IMPL-Blöcke).
|
||||
2. **`src/lib/policy-render.ts`** — `buildContext` belegt fehlende Framework-Flags vor
|
||||
(`FLAG_FW_TISAX = true`, `FLAG_FW_ISO27001 = false`). Ohne das würden Bestandsmandanten, deren
|
||||
Vorlagenpaket noch nicht neu importiert wurde, die VDA-ISA-Anforderungsblöcke leer sehen.
|
||||
|
||||
## 5. Prüfung
|
||||
|
||||
```bash
|
||||
cd seed/isms-vorlagenpaket-v2
|
||||
python3 _generate_iso.py # deutsche Fassung, idempotent
|
||||
python3 _generate_iso.py --lang en # englische Fassung
|
||||
python3 _verify.py # TISAX-Sicht → OK
|
||||
python3 _verify_iso.py # ISO-Sicht DE → OK
|
||||
python3 _verify_iso.py --lang en # ISO-Sicht EN → OK
|
||||
```
|
||||
|
||||
`_verify_iso.py` prüft Vollständigkeit (27 + 93), Auflösbarkeit aller Anker, nicht leere
|
||||
Umsetzungsblöcke, das Rendering **beider** Sichten ohne offene Platzhalter sowie die Verknüpfung zu
|
||||
den Verfahren.
|
||||
|
||||
## 6. Was noch fehlt (Anwendungsseite)
|
||||
|
||||
Das Paket ist fertig; die Anwendung kennt das zweite Mapping noch nicht. Offen bleibt aus
|
||||
`KONZEPT-framework-iso27001.md`:
|
||||
|
||||
- **Lane 1** — `Framework`-Enum, `TenantFramework`, `framework` an `PolicyTemplateVersion` und
|
||||
`PolicyPackageState`. Erst damit lässt sich `mapping-iso.json` überhaupt importieren; heute liest
|
||||
`parsePackageFiles` fest `mapping.json`.
|
||||
- **Lane 3/4** — ISO-Assessment (Applicability statt Reifegrad) und das **SoA-Modul**. Bis dahin wird
|
||||
die SoA als gelenktes Dokument geführt (`Statement-of-Applicability-ISO.md`).
|
||||
- **Setzen der Flags** — beim Provisionieren eines ISO-Mandanten müssen `FLAG_FW_ISO27001 = true`
|
||||
und, falls kein TISAX, `FLAG_FW_TISAX = false` gesetzt werden.
|
||||
|
||||
Ebenfalls offen und unabhängig davon: `REVIEW_CYCLE` wird weiterhin für fünf verschiedene Zyklen
|
||||
verwendet. Die neuen Abschnitte nutzen bereits die getrennten Variablen
|
||||
(`POLICY_REVIEW_CYCLE`, `MGMT_REVIEW_CYCLE`, `RISK_REVIEW_CYCLE`); die Bestandstexte umzustellen ist
|
||||
eine eigene, kleine Änderung.
|
||||
|
||||
## 7. Urheberrechtlicher Hinweis
|
||||
|
||||
Die ISO-Anforderungstexte in `mapping-iso.json` und in den Dokumenten sind **eigene Paraphrasen**;
|
||||
die Referenzen sind exakt, damit in der erworbenen Norm nachgeschlagen werden kann. Wörtliche
|
||||
Normzitate sind bewusst unterlassen. Das VDA-ISA-Mapping übernimmt die Anforderungen laut eigenem
|
||||
Hinweis in `mapping.json` „1:1 aus ISA" — auch dieser Katalog ist geschützt. Bei der weiteren Pflege
|
||||
der gemeinsamen Bibliothek sollte die vorsichtigere Linie des ISO-Mappings die gemeinsame werden
|
||||
(vgl. `SPEC.md` §12).
|
||||
@@ -0,0 +1,83 @@
|
||||
# Handbuch Kundenbetreuung — certvia (ISMS-Tool)
|
||||
|
||||
**Stand:** 2026-09-03 · **Zielgruppe:** Kundenbetreuung / Customer Success · **Zweck:** Schneller, praxisnaher Einstieg für die Betreuung von certvia-Kunden — was das Produkt kann, wie ein Kunde aufgesetzt/betreut wird und wie typische Support-Fälle gelöst werden.
|
||||
|
||||
> Dieses Handbuch ist bewusst **produkt- und supportorientiert**. Technische Tiefe steht in `docs/SPEC.md`, `docs/HANDOVER-PM.md` und den `docs/KONZEPT-*.md`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Was ist certvia (in einem Absatz)
|
||||
|
||||
certvia ist ein **Multi-Mandanten-ISMS-Tool** (Informationssicherheits-Managementsystem als SaaS). Jeder Kunde ist ein **Mandant** mit strikt getrennten Daten. Das Tool führt einen Kunden vom Onboarding über Strukturanalyse (Assets/Prozesse/Lieferanten), Risikomanagement, Richtlinien und Maßnahmen bis zur **Audit-Vorbereitung** — wahlweise nach **TISAX (VDA-ISA)** und/oder **ISO 27001**.
|
||||
|
||||
## 2. Zugang, Rollen, Anmeldung
|
||||
|
||||
- **Kunden-Login:** `https://<kunde-domain>/login` — E-Mail + Passwort, danach ggf. MFA (TOTP) und, bei mehreren Mandanten, Mandantenauswahl.
|
||||
- **Plattform-/Superadmin:** `…/platform/login` — **getrennter Login** für die Betreiber-Administration (Mandanten anlegen, Module, Stammdaten). MFA-Einrichtung beim ersten Login.
|
||||
- **Rollen (mandantenintern):** z. B. Mandanten-Admin, ISB (Informationssicherheitsbeauftragter), Auditor, Owner, User. Rechte hängen an Rollen; der **Mandanten-Admin** verwaltet Benutzer & Rollen unter **Einstellungen → Benutzer & Rollen**.
|
||||
- **Passwort/MFA:** Initial-/Reset-Passwörter erzwingen einen Wechsel beim nächsten Login. MFA und Passkeys sind an die **Person (Identity)** gebunden, nicht an den Mandanten.
|
||||
|
||||
## 3. Einen neuen Kunden aufsetzen (Provisionierung)
|
||||
|
||||
Ein Kunde wird als **Mandant** angelegt (über die Plattform-/Superadmin-Konsole bzw. beim ersten Deployment per Bootstrap-Admin). Beim Anlegen wird automatisch:
|
||||
- ein **Mandanten-Admin** erzeugt,
|
||||
- die **Standard-Module** aktiviert,
|
||||
- das **Richtlinien-Vorlagenpaket** importiert (inkl. Anforderungen, Variablen, Nachweisregister),
|
||||
- das **Framework** gesetzt (Default **TISAX**; ISO 27001 ist zusätzlich/alternativ wählbar).
|
||||
|
||||
Die **Stammdaten** des Mandanten (Firmenname, Kürzel, Rollen wie ISB/IT-Leitung/DSB, Scope) pflegt der Kunde unter **Einstellungen** — diese speisen automatisch die ISMS-Variablen in den Richtlinien.
|
||||
|
||||
## 4. Framework-Wahl: ISO 27001 und/oder TISAX
|
||||
|
||||
- Ein Mandant kann **ein oder beide** Frameworks führen. Der Umsetzungstext der Richtlinien ist normunabhängig; je Framework gibt es eine eigene Katalog-/Anforderungssicht.
|
||||
- **TISAX (VDA-ISA):** Reifegrad-Modell, Schutzbedarf/Assessment-Level (AL2/AL3), Prüfziele (Informationssicherheit/Prototypen/Datenschutz), VDA-ISA-Export.
|
||||
- **ISO 27001:** Anwendbarkeitserklärung (SoA, Annex A 2022, 93 Controls) mit „anwendbar/ausgeschlossen + Begründung", Managementklauseln (Kennzahlen 9.1, Managementbewertung 9.3, Korrekturmaßnahmen 10.2) und Dokumentenlenkung.
|
||||
- **Umschalten:** In der Admin-Konsole lassen sich die Normen je Mandant **nachträglich aktivieren/deaktivieren**.
|
||||
|
||||
## 5. Die Module (Kurzüberblick)
|
||||
|
||||
| Modul | Zweck |
|
||||
|---|---|
|
||||
| **Assets** | Informationswerte/Systeme/Anwendungen etc. inkl. Schutzbedarf (C/I/V) |
|
||||
| **Prozesse** | Geschäftsprozesse + Verknüpfung zu Assets (Strukturanalyse) |
|
||||
| **Risiken** | Risiko-Register (Eintritt × Auswirkung), Behandlung, Verknüpfung zu Assets/Prozessen |
|
||||
| **Lieferanten** | Lieferanten-/Dienstleistersteuerung (Kritikalität, NIS2, TISAX-Label, Verträge/NDAs) |
|
||||
| **Maßnahmen** | Maßnahmen zur Risikobehandlung, Wirksamkeit |
|
||||
| **Richtlinien** | Richtlinien-/Verfahrensbibliothek aus Vorlagen, Freigabe, Coverage |
|
||||
| **SoA** | ISO-Anwendbarkeitserklärung bzw. TISAX-Control-Assessment |
|
||||
| **Audit-Readiness** | Reifegrad/Gap-Analyse, Nachweise, Abgabe/Export |
|
||||
| **Vorfälle** | Incident-Management (inkl. NIS2-/DSGVO-Meldevorlagen) |
|
||||
| **Aufgaben** | Kanban-Aufgaben, Fristen |
|
||||
|
||||
Module lassen sich je Mandant **ein-/ausschalten** (Admin-Konsole).
|
||||
|
||||
## 6. Onboarding-Wizard
|
||||
|
||||
Neue Mandanten durchlaufen einen geführten Wizard: **Kontext → Scope → Richtlinien → Rollen → Risikokriterien → Prozesse → Controls**. Er baut das ISMS Schritt für Schritt auf; der Fortschritt wird gespeichert.
|
||||
|
||||
## 7. Typische Support-Fälle
|
||||
|
||||
- **„Login klappt nicht / Anmeldung fehlgeschlagen":** falsche E-Mail/Passwort, oder Account nach mehreren Fehlversuchen kurz gesperrt (15 Min). Prüfen: richtige Seite (`/login` vs `/platform/login`), Passwort exakt. Bei Reset ein Initial-Passwort setzen (erzwingt Wechsel).
|
||||
- **„MFA-Gerät verloren":** über Recovery-Codes anmelden; sonst MFA administrativ zurücksetzen (Mandanten-Admin/Betreiber).
|
||||
- **„Ein Modul fehlt in der Navigation":** Modul ist für den Mandanten deaktiviert → in der Admin-Konsole aktivieren.
|
||||
- **„Falsche Norm / ISO fehlt":** Framework des Mandanten prüfen und ggf. ISO 27001 aktivieren (Admin-Konsole).
|
||||
- **„E-Mails kommen nicht an":** SMTP-Konfiguration prüfen (Betreiber); Postfach/From-Adresse.
|
||||
|
||||
## 8. Wo finde ich vertiefende Infos?
|
||||
|
||||
- **Produkt/Funktionsumfang:** `docs/SPEC.md`, `docs/HANDOVER-PM.md`
|
||||
- **Kundennahe Mockups (im Browser):** `docs/ISMS-Prototyp-GEFIM.html`, `ISMS-Lieferantenmanagement-GEFIM.html`
|
||||
- **Feature-Konzepte:** `docs/KONZEPT-framework-iso27001.md` (ISO/TISAX), `KONZEPT-incidents.md`, `KONZEPT-backup-restore.md`, `KONZEPT-identity-mandanten.md` (Login/Mandanten/MFA)
|
||||
- **Aktueller Stand/Änderungen:** `docs/STAND-dev-branch.md`
|
||||
- **Am besten:** die **Demo-/Testinstanz** durchklicken (Login `admin@demo.example` / `Demo1234!`).
|
||||
|
||||
## 9. Betrieb & Grenzen (gut zu wissen)
|
||||
|
||||
- **Test- vs. Produktivumgebung:** Änderungen werden erst auf einer Testinstanz erprobt, dann produktiv ausgerollt. Support arbeitet auf der Produktivumgebung nur mit Bedacht.
|
||||
- **Backups:** Datenbank + Objektspeicher werden gesichert (Betrieb). Restore ist möglich; keine eigenmächtigen Löschaktionen an Produktivdaten.
|
||||
- **Datenschutz/Mandantentrennung:** Jeder Mandant sieht nur seine eigenen Daten — niemals Kundendaten zwischen Mandanten kopieren.
|
||||
- **Secrets/Zugänge:** niemals per E-Mail/Chat weitergeben; Passwörter setzt der Kunde selbst bzw. als Initial-Passwort mit Wechselzwang.
|
||||
|
||||
---
|
||||
|
||||
*Fehlt etwas oder ist ein Support-Fall unklar? Ergänze dieses Handbuch — es ist als lebendes Dokument gedacht.*
|
||||
@@ -0,0 +1,197 @@
|
||||
# Entwickler-Übergabe — ISMS-Tool
|
||||
|
||||
> 📌 **Aktueller Gesamtstand des `dev`-Branches (alle Entwicklungstätigkeiten, PM + Dev):** siehe **`docs/STAND-dev-branch.md`**.
|
||||
|
||||
> Stand: 2026-07-22 · Branch `dev` (Produktionshärtung + Benutzerverwaltung) · Basis `main`
|
||||
> Zweck: Kontext, Setup und Konventionen, damit ein neuer Entwickler direkt weiterarbeiten kann.
|
||||
> Fachlicher Status (fertig/offen) siehe **`docs/HANDOVER-PM.md`**. Neue Härtungs-/Verwaltungspakete: §10.
|
||||
|
||||
---
|
||||
|
||||
## 1. Repository & Zugriff
|
||||
|
||||
- **Lokaler Pfad:** `~/Projects/ISMS-Tool`
|
||||
- **Git-Remote (Gitea, nur HTTP):**
|
||||
`http://gitea-vkbhbn2qdkz5ppk9q4qgb0tn.192.168.1.207.sslip.io/msolarczek/ISMS-Tool.git`
|
||||
(interner Server; kein SSH). **Zugangstoken** liegt im macOS-**Schlüsselbund** (nicht im Repo, nicht in Klartext weitergeben). Für `git push` wird der Token als HTTP-Passwort verwendet.
|
||||
- **Default-Branch:** `main` (es wird direkt auf `main` committet; Commits sind fein granular je Thema).
|
||||
- **Commit-Konvention:** deutschsprachige, aussagekräftige Messages; Referenz auf Spec-Abschnitte (z. B. „§7b"). Co-Authored-By-Trailer für KI-Beiträge.
|
||||
|
||||
---
|
||||
|
||||
## 2. Tech-Stack (verifizierte Versionen)
|
||||
|
||||
| Bereich | Technologie |
|
||||
|--------|-------------|
|
||||
| Runtime | **Node.js 26** |
|
||||
| Framework | **Next.js 16** (App Router, React 19, Server Components + Server Actions, Turbopack im Dev) |
|
||||
| Sprache | TypeScript (strict) |
|
||||
| DB / ORM | **PostgreSQL** (mit **pgvector**) · **Prisma 7** (`@prisma/client` + `@prisma/adapter-pg`, `prisma.config.ts`) |
|
||||
| Auth | **NextAuth v5** (Credentials, JWT-Session) · Passwörter mit `@node-rs/argon2` |
|
||||
| i18n | **next-intl** (Default `de`, `en` vorbereitet; Catalog in `messages/de.json`/`en.json`) |
|
||||
| UI | Tailwind **v4** + shadcn/ui (**Base-UI-Variante**), Dark-Theme über zentrale CSS-Tokens in `src/app/globals.css` |
|
||||
| Spezial | Handlebars + `marked` (Richtlinien-Rendering), `@xyflow/react` + `@dagrejs/dagre` (Abhängigkeitsgraph), `zod` (Validierung) |
|
||||
|
||||
**Scripts** (`package.json`): `dev` (`next dev`), `build`, `start`, `lint` (`eslint`). Seed: `npx tsx prisma/seed.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Setup (von Null)
|
||||
|
||||
```bash
|
||||
# 1. Repo klonen (Token als HTTP-Passwort)
|
||||
git clone http://gitea-…/msolarczek/ISMS-Tool.git
|
||||
cd ISMS-Tool
|
||||
|
||||
# 2. Abhängigkeiten
|
||||
npm install
|
||||
|
||||
# 3. .env anlegen (Vorlage vorhanden)
|
||||
cp .env.example .env
|
||||
# Wichtige Variablen: DATABASE_URL (Postgres inkl. pgvector), AUTH_SECRET, AUTH_URL,
|
||||
# optional REDIS_URL, AI_PROVIDER/AI_API_KEY, SMTP_* (noch ungenutzt).
|
||||
|
||||
# 4. Infrastruktur starten (docker-compose.yml im Repo-Root)
|
||||
docker compose up -d postgres # Postgres mit pgvector (Image pgvector/pgvector:pg16)
|
||||
# Weitere Services im Compose: app, worker, redis, minio (Objektspeicher, für späteren
|
||||
# Logo-Upload), mailhog (SMTP-Dev). Für lokale Entwicklung reicht i. d. R. 'postgres'.
|
||||
|
||||
# 5. Prisma-Client + Migrationen
|
||||
npx prisma generate
|
||||
npx prisma migrate deploy # wendet alle Migrationen an (inkl. RLS-Policies)
|
||||
|
||||
# 6. Seed (Demo-Mandant, Kataloge, Richtlinienpaket, Admin-Konsole)
|
||||
npx tsx prisma/seed.ts
|
||||
|
||||
# 7. Dev-Server
|
||||
npm run dev # http://localhost:3000 (Port 3000, siehe .claude/launch.json)
|
||||
```
|
||||
|
||||
**Demo-Logins** (Passwort `Demo1234!`): `admin@demo.example` (Mandanten-Admin + ISB), `bea.approver@demo.example` (ISB, zweiter Freigeber für den Vier-Augen-Workflow), `auditor@demo.example`, `owner@demo.example`, `user@demo.example` — alle über den **Mandanten-Login** `/login`.
|
||||
|
||||
**Plattform-Admin (Betrieb):** getrennter Store + eigener Login `/platform/login` (TOTP-MFA-Pflicht, Enrollment beim ersten Login). Demo-Konto: `admin@demo.example` / `Demo1234!` (gleiche Adresse, aber getrennte Session ohne Mandantenkontext). Das frühere `isPlatformAdmin`-Flag ist abgelöst; die Admin-Konsole `/admin` ist nur mit Plattform-Session erreichbar. Siehe **Paket 2** der Produktionshärtung.
|
||||
|
||||
---
|
||||
|
||||
## 4. Architektur & tragende Konventionen
|
||||
|
||||
### Mandantenfähigkeit (kritisch!)
|
||||
- Jede Fachtabelle hat `tenant_id`. **Nie ohne Mandantenkontext queren.**
|
||||
- Zentraler Guard **`dbForTenant(tenantId)`** in `src/server/db.ts`: filtert reads automatisch nach `tenantId`, injiziert ihn bei `create`, prüft Ownership bei `findUnique`/`update`/`delete`. Neue tenant-bezogene Modelle **müssen in `TENANT_MODELS`** (in `db.ts`) eingetragen werden.
|
||||
- Zusätzlich **Postgres Row Level Security** je Tabelle (Policy `tenant_isolation`, gesetzt in den Migrationen). Superadmin/plattformweite Reads laufen über den **rohen `prisma`**-Client (nicht `dbForTenant`).
|
||||
- Session (`src/server/auth.ts`) trägt `tenantId`, `roles`, `permissions`, `isPlatformAdmin`.
|
||||
|
||||
### RBAC
|
||||
- Katalog + Rollen-Blueprints in **`src/server/rbac.ts`** (`PERMISSIONS`, `ROLE_DEFS`). Serverseitige Durchsetzung: `requirePermission(session, "x:y")` / `hasPermission(...)`. UI-Verstecken ist nur Komfort.
|
||||
|
||||
### Modul-Gating (§3.4)
|
||||
- Modul-Katalog in **`src/lib/modules.ts`**. Je Mandant `TenantModule`-Zeilen (enabled). Navigation blendet deaktivierte Module aus (`layout.tsx`).
|
||||
- **Serverseitige Durchsetzung:** `requireModule("key")` in `src/server/modules.ts`, angewandt als **Modul-`layout.tsx`** je Routenordner (`assets/`, `processes/`, `risks/`, `measures/`, `policies/`, `suppliers/`, `dependencies/`) → schützt auch Unterrouten. In Server-Actions läuft der Layout-Guard erst nach der Mutation, daher zusätzlich `requireModule` im Action-`guard()` (bisher exemplarisch nur `policies.ts` — **auf übrige Action-Dateien nachzuziehen**).
|
||||
|
||||
### UI-Muster
|
||||
- **Detail/Bearbeiten/Anlegen** überwiegend als **URL-gesteuerte Popups** (`?detail=`/`?edit=`/`?new=1`, `src/components/modal.tsx`) — Ausnahme: **Richtlinien-Dokumente** wurden bewusst auf **eigene Seiten** (`/policies/[code]`, `.../edit`) umgestellt.
|
||||
- Dark-Theme: **keine hartkodierten Hex-Werte** in Komponenten — zentrale Tokens verwenden (`--bg-0`, `--panel`, `--surface-soft`, `--band`, `--ok/--warn/--risk/--info`, …).
|
||||
- Formulare mit „einem Speichern-Button" nutzen HTML-`form`-Attribut-Assoziation (`form="id"`).
|
||||
- Alle sichtbaren Texte über den next-intl-Catalog (`messages/*.json`) — Admin-/Register-Detailtexte teils bewusst inline-Deutsch.
|
||||
|
||||
### Prisma-7-Migrationen (Eigenheit)
|
||||
Nicht-interaktiv, in zwei Schritten:
|
||||
```bash
|
||||
npx prisma migrate diff --from-config-datasource prisma.config.ts \
|
||||
--to-schema prisma/schema.prisma --script > prisma/migrations/<ts>_name/migration.sql
|
||||
# RLS-DO-Block manuell an die migration.sql anhängen (siehe bestehende Migrationen)
|
||||
npx prisma migrate deploy
|
||||
```
|
||||
(Die interaktiven `migrate dev`-Prompts sind in dieser Umgebung blockiert; Flag-Namen in Prisma 7 geändert: `--from-config-datasource`/`--to-schema`.)
|
||||
|
||||
---
|
||||
|
||||
## 5. Verzeichnisstruktur (Auszug)
|
||||
|
||||
```
|
||||
src/
|
||||
app/(app)/ # geschützter App-Bereich (Sidebar-Shell = layout.tsx)
|
||||
dashboard/ assets/ processes/ risks/ measures/ dependencies/ suppliers/
|
||||
policies/ # Richtlinien: page + [code]/(page,edit) + layout.tsx (Modul-Guard)
|
||||
admin/ admin/[id]/ # Plattform-Admin-Konsole (Superadmin)
|
||||
settings/ # Kunden-Einstellungen (tenant:manage)
|
||||
app/login/ # Login
|
||||
components/ # UI + Fach-Modals (asset-, supplier-, service-, policy-*.tsx …)
|
||||
server/
|
||||
auth.ts db.ts rbac.ts modules.ts provision.ts audit.ts
|
||||
risk-calc.ts dependency-graph.ts
|
||||
actions/ # Server Actions je Modul (assets, risks, measures, suppliers,
|
||||
# services, policies, admin, tenant-settings)
|
||||
lib/ # modules, policy-render, supplier(+include), risk, control-titles,
|
||||
# isa-controls, levels, measure, utils
|
||||
prisma/
|
||||
schema.prisma seed.ts import-policies.ts import-managed.ts migrations/
|
||||
messages/ de.json en.json
|
||||
seed/isms-vorlagenpaket-v2/ # VDA-ISA-Vorlagenpaket (Richtlinien/Verfahren, mapping.json, Baseline …)
|
||||
docs/ SPEC.md HANDOVER-PM.md HANDOVER-DEV.md *.html (Mockups)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Modul-Kurzreferenz (wo liegt was)
|
||||
|
||||
- **Richtlinien:** Rendering-Engine `src/lib/policy-render.ts` (Handlebars, Flags, BL-Entfernung, `applyProtection` für TISAX-Level), Import `prisma/import-policies.ts` + `prisma/import-managed.ts`, UI `src/app/(app)/policies/**` + `src/components/policy-*.tsx`, Actions `src/server/actions/policies.ts`. Control-Titel `src/lib/control-titles.ts`.
|
||||
- **Lieferanten/IT-Service:** Engine `src/lib/supplier.ts`, Includes `src/lib/supplier-include.ts`, UI `src/components/supplier-modals.tsx`/`service-modals.tsx`/`supplier-cockpit.tsx`, Actions `suppliers.ts`/`services.ts`.
|
||||
- **Admin/Mandanten:** Provisionierung `src/server/provision.ts` (von Seed **und** `actions/admin.ts` genutzt, idempotent), `actions/tenant-settings.ts` (Stammdaten → ISMS-Variablen via `syncPolicyVariablesFromSettings`).
|
||||
- **Risiko/Graph:** `src/server/risk-calc.ts`, `src/server/dependency-graph.ts`, `src/lib/risk.ts`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Datenmodell — zentrale Modelle
|
||||
|
||||
`Tenant`, `TenantSettings` (Quelle der ISMS-Variablen), `TenantModule`, `User` (`isPlatformAdmin`), `Role`/`Permission`/`RolePermission`/`UserRole`, `AuditLog` (`scope: tenant|platform`).
|
||||
Fachlich: `Asset`/`AssetRelation`, `Process`/`ProcessAsset`/`BiaEntry`, `Risk`/`RiskAsset`/`Measure`/`RiskMeasure`, `Threat`/`Vulnerability`, `SupplierProfile`/`ITServiceProfile` (+ Assessments/Contracts/Ndas/Evidence/Raci/Maturity), Richtlinien: `PolicyDocument`/`PolicyRequirement`/`PolicyVariable`/`PolicyBaselineParam`/`PolicyEvidence` + verwaltete Register (`CryptoEntry`, `ClassificationClass`/`HandlingAspect`/`HandlingRule`, `RiskMatrixClass`/`RiskEwLevel`/`RiskDamageDimension`, `HandbookTopic`).
|
||||
|
||||
---
|
||||
|
||||
## 8. Verifikations-Workflow
|
||||
|
||||
Nach jeder Änderung: **`npx tsc --noEmit`** → **`npm run lint`** → **`npm run build`**. Danach – wo relevant – Browser-Verifikation (Dev-Server + Login `admin@demo.example`). Bei DB-Änderungen: Migration erzeugen/anwenden + `npx tsx prisma/seed.ts` neu laufen lassen. Für das Richtlinien-Rendering existiert ein Residue-Check-Muster (rückstandsfrei über Flag-Kombinationen, angelehnt an `seed/.../_verify.py`).
|
||||
|
||||
---
|
||||
|
||||
## 9. Bekannte Fallstricke
|
||||
|
||||
1. **Beschädigte Seed-Tokens:** Das VDA-ISA-Paket enthält in einigen VA-RACI-Tabellen (VA-05/08/09/10/12/13) abgeschnittene `{{VAR |`-Tokens. Bei jedem Paket-Update **erneut prüfen & reparieren** (sonst bricht Handlebars). Scan: unbalancierte `{{`/`}}` je Zeile.
|
||||
2. **Richtlinien-Re-Import ist nicht-destruktiv** (Phase-1-Härtung Paket 3, `prisma/import-policies.ts`): Diff/Upsert über stabile Schlüssel (`code`/`reqId`/`key`/`blId`/`nr`). Vorhandenes wird inhaltlich aktualisiert, aber **Status/Override/Freigabe** (PolicyDocument) und **nutzergepflegte Variablenwerte** bleiben erhalten; entfernte Paket-Einträge werden **deaktiviert** (`archivedAt`) statt gelöscht (aktive Ansichten filtern `archivedAt: null`). Verwaltete Register aus `import-managed.ts` (CRYPTO/RISKMATRIX/CLASSIFICATION/HANDBUCH) liegen außerhalb des Paket-Namensraums und werden nicht angetastet. Jeder Lauf liefert einen Änderungsreport (Audit-Log, Entity `policy_package`); `{ dryRun: true }` erzeugt die Vorschau ohne Schreibzugriff. Akzeptanztest: `npx tsx scripts/test-reimport.ts`.
|
||||
3. **RLS-Kontext:** RLS-Policies erwarten `current_setting('app.tenant_id')`. Die App nutzt primär den `dbForTenant`-Guard; wenn direkte DB-Zugriffe hinzukommen, `app.tenant_id` in der Transaktion setzen.
|
||||
4. **Turbopack-HMR** kann veraltete Fehler/`MISSING_MESSAGE` zeigen, nachdem `messages/*.json` geändert wurde → Dev-Server neu starten. Produktions-Build ist maßgeblich.
|
||||
5. **Prisma-7-Migrationsflow** wie in §4 (kein `migrate dev`).
|
||||
6. **`.next`-Cache** nicht löschen, während der Dev-Server läuft (Turbopack-Korruption) → Server stoppen, `rm -rf .next`, neu starten.
|
||||
7. **TISAX-Flags:** `FLAG_HIGH_PROTECTION` ist im Modell stets aktiv, `FLAG_ELEVATED_PROTECTION` wird **abgeleitet** (`applyProtection`) — nie manuell setzen. Effektiver Level = Dokument-Override sonst global.
|
||||
|
||||
---
|
||||
|
||||
## 10. Produktionshärtung & Benutzerverwaltung (umgesetzt, Branch `dev`)
|
||||
|
||||
Aufbauend auf dem Fundament wurden mehrere Härtungspakete umgesetzt (feingranulare Commits auf `dev`):
|
||||
|
||||
- **API-Modul-Durchsetzung (§3.4):** zentraler `moduleGuard("<key>")` in `src/server/action-guard.ts`; jede mutierende Action eines gegateten Moduls läuft über `guard(...)` (Session → `assertModuleEnabled` → RBAC). Vollständigkeitscheck `scripts/check-module-guards.ts` (Registry Action→Modul) als `prebuild` — Build failt bei nicht zugeordneter Action-Datei. Neue Action-Datei ⇒ dort eintragen (Modul-Key oder `EXEMPT`).
|
||||
- **Plattform-Admins getrennt:** Store `PlatformAdmin` (kein `tenant_id`), eigene NextAuth-Instanz `src/server/platform-auth.ts` (eigener Cookie/basePath `/api/platform-auth`, Session ohne Tenant), Login `/platform/login`, Bereich unter `src/app/(platform)/…`. **MFA (TOTP, `src/server/mfa.ts`) ist optional** — Enrollment nur erzwungen, wenn `PlatformSetting.mfaRequired` (Singleton) an ist; Umschaltung + Self-Service unter `/platform/profile`. Rate-Limit/Lockout am Login bleiben. Audit `scope=platform` via `writePlatformAudit`.
|
||||
- **Nicht-destruktiver Richtlinien-Re-Import:** siehe §9 Punkt 2.
|
||||
- **Benutzer- & Rollenverwaltung (ohne E-Mail-Flow):**
|
||||
- Plattform-Admin je Mandant: `src/server/actions/platform-users.ts` + `components/platform-tenant-users.tsx`, eingebettet in `/admin/[id]`. Anlegen mit **Initial-/Einmal-Passwort** (selbst setzen oder generiert, einmalig angezeigt), Rollen, Deaktivieren/Reaktivieren, Passwort-Reset.
|
||||
- Mandanten-Admin intern: `src/server/actions/tenant-users.ts` + `components/tenant-users-manager.tsx`/`role-manager.tsx`, Seite `/settings/users` (nur `user:manage`/`role:manage`). Benutzer-CRUD **und** Rollen-CRUD (eigene Rollen + Permissions; Standardrollen schreibgeschützt/klonbar). Strikt `dbForTenant(session)` → kein Cross-Tenant. **Lockout-Schutz** für den letzten aktiven Mandanten-Admin.
|
||||
- **Force-Change:** neue Nutzer starten mit `mustChangePassword=true`; das `(app)`-Layout leitet autoritativ (DB) auf `/change-password` und sperrt deaktivierte Konten. Passwort-Policy: `src/lib/password-policy.ts` (Validierung, client-safe) + `src/server/password.ts` (Argon2id-Hash + Generator); Quelle `TenantSettings.securityPolicy.password`.
|
||||
- **Nutzer-MFA optional:** Tenant-Login (`auth.ts`) verlangt TOTP nur bei eingerichteter MFA; Self-Service unter `/account`. `role:manage` ist neu im RBAC-Katalog (Mandanten-Admin).
|
||||
- **Bearbeiten:** je Nutzer sind **Name & E-Mail** (E-Mail eindeutig je Mandant), Rollen, Aktiv/Deaktiviert und Passwort-Reset editierbar — in beiden Konsolen.
|
||||
- **Zuständigkeit Einstellungen (Superadmin vs. Tenant-Admin):** **Kern-Einstellungen** (aktive Module, TISAX-/Schutzbedarf-**Tiefe**, Richtlinienpaket) steuert ausschließlich der **Superadmin** in der Admin-Konsole (`/admin/[id]`, u. a. `setTenantTisaxLevel`). Der **Tenant-Admin** pflegt in `/settings` nur seinen Bereich (Stammdaten/Branding → ISMS-Variablen) + Benutzer/Rollen; die TISAX-Tiefe ist dort nur noch als Read-only-Anzeige.
|
||||
- **Zukunftssicher:** `createTenantUser`/`createUser` kapseln die Aktivierung über Initial-/Einmal-Passwort — der spätere **E-Mail-Einladungs-Flow (Paket 4)** lässt sich als alternative Aktivierung (Token statt Passwort) einhängen, ohne die UI umzubauen.
|
||||
- **Benutzer-UI als Popup:** Anlegen/Bearbeiten über URL-gesteuerte Modals (`?new`/`?edit`, generische `components/user-forms.tsx` + `user-table.tsx`) in `/settings/users` und `/admin/[id]`; die Tabelle zeigt nur.
|
||||
- **Aufgaben-/Freigabe-Modul (`tasks`):** generisches `Task`/`TaskComment` (RLS, in `TENANT_MODELS`). Erster Typ `policy_approval`: beim Einreichen wählt der Autor einen **konkreten Freigeber** (aktiver Nutzer mit `policy:approve`, ≠ Einreicher) → Aufgabe. Freigeben/Ablehnen (mit Grund)/Kommentieren im Bereich **`/tasks`** (nur der zugewiesene Freigeber; Vier-Augen), Verlauf historisiert; **Dashboard-Kachel** zählt offene Freigaben. Actions: `server/actions/tasks.ts` (+ `submitForApproval` in `policies.ts`). Der Editor zeigt nur noch Status/Freigeber + Link zur Aufgabe.
|
||||
- **Richtlinien-Governance zentralisiert:** zentrale Variablen (Organisation/Rollen/Schutzbedarf-Flags, `lib/policy-variables.ts`) sind im Editor gesperrt (nur Einstellungen); **Schutzbedarf/TISAX** ausschließlich Superadmin (kein Per-Doc-Override, kein globaler Schalter im Modul); **Coverage-Matrix** filtert nach aktivem Assessment-Level (AL2 ohne „sehr hoch").
|
||||
|
||||
## 11. Nächste sinnvolle Aufgaben (Einstiegspunkte)
|
||||
|
||||
- **SMTP + Einladungs-/Aktivierungs-/Reset-Flow (Paket 4, M):** transaktionale Mails (Nodemailer), signierte Einladungs-/Reset-Tokens; ersetzt/ergänzt den Initial-Passwort-Weg.
|
||||
- **Admin Phase 2 — Impersonation (M):** neues Modell `ImpersonationSession`, Cookie-basierter effektiver Tenant + Banner, Ablauf, Audit.
|
||||
- **Tenant-weite MFA-Pflicht scharfschalten (S):** `securityPolicy.mfaRequired` wird von `disableOwnMfa` bereits respektiert; Enrollment-Erzwingung analog zum Force-Change-Gate (Seite außerhalb der `(app)`-Shell) nachziehen.
|
||||
- **NIS2-Modul (L):** eigenes Modul inkl. Incident-Reporting mit Fristen-Timern.
|
||||
- **Richtlinien-Versionierung/Diff (M–L)** und **DOCX/PDF-Export (M)**.
|
||||
|
||||
Weitere Details, Priorisierung und Aufwände: **`docs/HANDOVER-PM.md`**. Projekt-Spec: **`docs/SPEC.md`** + Modul-Prompts/Mockups.
|
||||
@@ -0,0 +1,122 @@
|
||||
# DevOps-Übergabe — ISMS-Tool (Deployment Test → Produktiv)
|
||||
|
||||
> Stand: 2026-07-20 · Branch `main` · Commit `081c000`
|
||||
> Zweck: Betrieb/Deployment. Gemeinsame Arbeit an Dockerfile, Einrichtung Testserver (remote), danach Produktivserver.
|
||||
> Ergänzt: `docs/HANDOVER-DEV.md` (App-Architektur/Setup) und `docs/HANDOVER-PM.md` (fachlicher Status).
|
||||
|
||||
---
|
||||
|
||||
## 1. Überblick der Runtime
|
||||
|
||||
Die App ist eine **Next.js-16-Anwendung im Standalone-Modus** (`output: "standalone"` in `next.config`, Start via `node server.js`), zustandslos horizontal skalierbar. Zustand liegt ausschließlich in den Backing-Services.
|
||||
|
||||
| Service | Image / Herkunft | Port | Zweck | Persistenz |
|
||||
|--------|------------------|------|-------|-----------|
|
||||
| **app** | Multi-Stage-Build (`Dockerfile`) | 3000 | Web-App (Next.js standalone) | zustandslos |
|
||||
| **postgres** | `pgvector/pgvector:0.8.0-pg16` | 5432 | Primärdatenbank (inkl. `vector`-Extension) | Volume `pgdata` |
|
||||
| **redis** | `redis:7.4.2-alpine` (mit `requirepass`) | 6379 | Cache/Queue (für späteren BullMQ-Worker) | Volume `redisdata` |
|
||||
| **minio** | `minio/minio:RELEASE.2025-04-22T22-12-26Z` | 9000/9001 | Objektspeicher (noch **ungenutzt**; für kommenden Logo-/Datei-Upload) | Volume `miniodata` |
|
||||
| **mailhog** | `mailhog/mailhog:v1.0.1` (Profil `dev`) | 1025/8025 | SMTP-Fang für Entwicklung | — |
|
||||
| **worker** | s. Dockerfile (Profil `worker`) | — | **noch nicht lauffähig** (kein `worker`-npm-Script vorhanden) | — |
|
||||
|
||||
Alles bereits als **`docker-compose.yml`** im Repo-Root beschrieben; **`Dockerfile`** ist ein 4-Stage-Build (`deps` mit `npm ci` → `builder` mit `prisma generate` + `next build` → schlanke `migrate`-Stage für den Migrations-/Seed-Job → schlanker `runner` als non-root `app`-User). Alle Images sind auf konkrete Tags gepinnt (F-11), Base ist `node:22-slim` (glibc).
|
||||
|
||||
---
|
||||
|
||||
## 2. Umgebungsvariablen (`.env`)
|
||||
|
||||
Vorlage: **`.env.example`**. Vollständige Liste:
|
||||
|
||||
| Variable | Zweck | Prod-Hinweis |
|
||||
|----------|-------|-------------|
|
||||
| `POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB` | Compose-Init von Postgres | **Secret** (Passwort) |
|
||||
| `DATABASE_URL` | Prisma-Verbindungsstring | **Secret**; muss auf denselben DB-Nutzer/-Namen zeigen |
|
||||
| `REDIS_URL` | Redis-Verbindung | — |
|
||||
| `AUTH_SECRET` | NextAuth-Signaturschlüssel (JWT) | **Secret**, zwingend gesetzt & stark |
|
||||
| `AUTH_URL` | Öffentliche Basis-URL der App | pro Umgebung (Test/Prod) unterschiedlich, inkl. `https://` |
|
||||
| `AI_PROVIDER` / `AI_API_KEY` | KI-Chat / KI-Formulierungshilfe (noch ungenutzt) | Secret, optional |
|
||||
| `SMTP_HOST/PORT/USER/PASSWORD/FROM` | E-Mail (noch ungenutzt; Einladungs-/Benachrichtigungsflow offen) | Secret, optional |
|
||||
| `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` | Objektspeicher | **fehlen in `.env.example`** → für Prod ergänzen (sonst Compose-Defaults `isms`/`isms-secret`) |
|
||||
|
||||
> **Secrets** gehören nicht ins Git. Für Prod: Secret-Management (Docker Secrets / Env aus Vault / CI-Variablen). `.env.example` enthält nur Namen/Defaults.
|
||||
|
||||
---
|
||||
|
||||
## 3. Build & Start
|
||||
|
||||
```bash
|
||||
# Image bauen
|
||||
docker compose build app
|
||||
|
||||
# Test/lokal hochfahren (ohne dev-only mailhog)
|
||||
docker compose up -d postgres redis minio app
|
||||
|
||||
# mit Mailhog (Dev): docker compose --profile dev up -d
|
||||
# Worker (aktuell NICHT lauffähig, s. §6): docker compose --profile worker up -d worker
|
||||
```
|
||||
|
||||
App danach unter `AUTH_URL` (Port 3000) erreichbar.
|
||||
|
||||
---
|
||||
|
||||
## 4. ⚠️ Datenbank-Migrationen & Bootstrap (kritisch)
|
||||
|
||||
**Der App-Container führt KEINE Migrationen beim Start aus** (CMD ist `node server.js`). Migrationen und das erste Provisioning sind ein **separater Deploy-Schritt**:
|
||||
|
||||
1. **Migrationen anwenden:** `npx prisma migrate deploy` gegen die Ziel-DB.
|
||||
- Die `runner`-Stage enthält Prisma-CLI/`tsx` **nicht** (nur Runtime-Trace). Migrationen daher aus der **`builder`-Stage** (voller `node_modules`) oder aus einem eigenen **Migrations-Job/CI-Step** fahren. → **Designentscheidung mit DevOps** (z. B. Init-Container `command: npx prisma migrate deploy` mit builder-Image, `restart: "no"`).
|
||||
- Die Init-Migration legt `CREATE EXTENSION IF NOT EXISTS "vector"` an (pgvector) — das Postgres-Image bringt die Extension mit.
|
||||
2. **Erster Mandant / Superadmin (Prod):** Der Demo-Seed (`prisma/seed.ts`) ist **nur für Entwicklung** (Demo-Mandant + Testnutzer) — **nicht in Produktion ausführen**. In Prod erfolgt das Anlegen von Kunden über die **Admin-Konsole** (`provisionTenant`). **Offen:** Es gibt aktuell **kein Bootstrap-Skript** für den allerersten Plattform-Admin — dieser muss initial angelegt werden (Skript/One-Off gegen `provisionTenant` mit `isPlatformAdmin: true`, oder manuell). → **Mit App-Entwickler abstimmen** (kleiner Task).
|
||||
|
||||
---
|
||||
|
||||
## 5. Persistenz, Backup & Restore
|
||||
|
||||
- **Volumes:** `pgdata` (kritisch), `miniodata` (künftig Uploads), `redisdata` (unkritisch, Cache).
|
||||
- **Backups Prod:** regelmäßiger `pg_dump` (logisch) oder Volume-/Snapshot-Backup; MinIO-Bucket-Backup, sobald Uploads aktiv. Aufbewahrung + Restore-Test einplanen (DSGVO-Löschkonzept ist app-seitig noch offen).
|
||||
- Mandantentrennung ist **logisch** (eine DB, `tenant_id` + Postgres-RLS + App-Guard) — Backups umfassen alle Mandanten gemeinsam.
|
||||
|
||||
---
|
||||
|
||||
## 6. Bekannte Lücken / To-dos für DevOps
|
||||
|
||||
1. **`worker`-Service nicht lauffähig:** Es existiert **kein `npm run worker`**-Script (BullMQ-Scheduler ist app-seitig noch nicht implementiert). Profil `worker` bis dahin **nicht** starten.
|
||||
2. **Migrations-/Bootstrap-Strategie** festlegen (§4) — Migrations-Job + Erst-Superadmin.
|
||||
3. **MinIO-Env** in `.env` für Prod ergänzen; MinIO wird erst mit dem kommenden Logo-/Datei-Upload wirklich genutzt (Bucket-Präfix je Mandant vorgesehen).
|
||||
4. **Reverse-Proxy + TLS** vor der App (Port 3000 nicht direkt exponieren): Traefik/Caddy/nginx mit HTTPS; `AUTH_URL` auf die öffentliche `https://`-Adresse setzen. Rate-Limiting/IP-Härtung für Login/Admin einplanen.
|
||||
5. **Ressourcen/Skalierung:** `app` ist zustandslos → mehrere Replicas möglich; Sticky-Sessions nicht nötig (JWT). Postgres/Redis als Singleton bzw. Managed-Service.
|
||||
6. **Health/Observability:** Postgres-Healthcheck vorhanden; für `app` einen HTTP-Healthcheck/Readiness ergänzen (derzeit keiner definiert). Log-Aggregation + Alerting einrichten.
|
||||
7. **`AUTH_SECRET`** je Umgebung eindeutig & stark; bei Rotation invalidieren alle Sessions.
|
||||
|
||||
---
|
||||
|
||||
## 7. Test- vs. Produktivumgebung — Unterschiede
|
||||
|
||||
| Aspekt | Test (Remote) | Produktiv |
|
||||
|--------|---------------|-----------|
|
||||
| Daten | ggf. Demo-Seed erlaubt | **kein Demo-Seed**; nur echtes Provisioning |
|
||||
| Secrets | Test-Werte | echte Secrets aus Secret-Store |
|
||||
| Mail | Mailhog (Profil `dev`) | echtes SMTP-Relay |
|
||||
| TLS | optional/self-signed | verpflichtend, gültiges Zertifikat |
|
||||
| Backups | optional | verpflichtend + Restore-Test |
|
||||
| Skalierung | 1 Replica | ≥ 2 App-Replicas hinter Proxy |
|
||||
|
||||
---
|
||||
|
||||
## 8. Deploy-Checkliste (Kurz)
|
||||
|
||||
**Testserver:**
|
||||
1. Repo klonen/pullen (Gitea, Branch `main`).
|
||||
2. `.env` aus `.env.example` mit Test-Werten (inkl. `MINIO_*`).
|
||||
3. `docker compose build app`.
|
||||
4. `docker compose up -d postgres redis minio`.
|
||||
5. **Migrationen:** `prisma migrate deploy` (builder-Image/Job).
|
||||
6. **Erst-Superadmin** anlegen (One-Off, s. §4) — für Test ggf. Demo-Seed ok.
|
||||
7. `docker compose up -d app`; Reverse-Proxy/TLS davor; Smoke-Test (Login, Admin-Konsole, Modul-Seite).
|
||||
|
||||
**Produktivserver:** wie oben, aber Secret-Store, **kein** Demo-Seed, TLS verpflichtend, Backups + Monitoring aktiv, ≥ 2 App-Replicas, Migrations-/Bootstrap-Schritt in die Deploy-Pipeline integriert.
|
||||
|
||||
---
|
||||
|
||||
## 9. Referenzen im Repo
|
||||
`Dockerfile`, `docker-compose.yml`, `.env.example`, `next.config.*` (`output: standalone`), `prisma/schema.prisma` + `prisma/migrations/**` (inkl. RLS-Policies & pgvector), `prisma/seed.ts` (nur Dev), `src/server/provision.ts` (Provisioning-Logik für Prod-Onboarding).
|
||||
@@ -0,0 +1,98 @@
|
||||
# Projektübergabe — ISMS-Tool (Stand für Projektmanagement)
|
||||
|
||||
> 📌 **Konsolidierter Gesamtstand aller Entwicklungstätigkeiten auf `dev` (PM + Dev):** siehe **`docs/STAND-dev-branch.md`**.
|
||||
|
||||
> Stand: 2026-07-22 · Branch `dev` (Produktionshärtung + Benutzerverwaltung; noch nicht nach `main` gemerged)
|
||||
> Zweck: Statusüberblick für die Weiterplanung — was ist umgesetzt, was ist offen (mit Priorität & grobem Aufwand).
|
||||
|
||||
## 🆕 Neu auf `dev` (Produktionshärtung Phase 1 + Benutzerverwaltung)
|
||||
|
||||
| Thema | Status | Kurz |
|
||||
|-------|:------:|------|
|
||||
| **API-seitige Modul-Durchsetzung** | ✅ | Deaktiviertes Modul sperrt jetzt auch Writes serverseitig; automatischer Vollständigkeitscheck (Build-Gate). |
|
||||
| **Separater Superadmin-Store + eigener Login** | ✅ | Eigener Store/Login (`/platform/login`), Session ohne Mandantenbezug; `isPlatformAdmin`-Umweg abgelöst. |
|
||||
| **MFA für Superadmins** | ✅ (optional) | Zunächst als Pflicht gebaut, dann auf **optional** umgestellt; Policy-Flag „MFA-Pflicht" (aus) stellt die Erzwingung wieder her. |
|
||||
| **Nicht-destruktiver Richtlinien-Re-Import** | ✅ | Diff/Upsert; Status/Override/Freigabe/Variablenwerte bleiben, entfernte Einträge werden deaktiviert; Änderungsreport + Vorschau. |
|
||||
| **Benutzer- & Rollenverwaltung** | ✅ | Plattform-Admin legt je Kunde Nutzer an (Initial-/Einmal-Passwort); Mandanten-Admin verwaltet Nutzer **und** Rollen intern (eigene Rollen + Rechte, Standardrollen klonbar), mandantengetrennt + Lockout-Schutz. Force-Change beim ersten Login, Passwort-Policy. |
|
||||
| **Nutzer-MFA (Mandant)** | ✅ (optional) | Je Nutzer aktivierbar (`/account`); Login verlangt Code nur bei aktiver MFA. |
|
||||
| **SMTP + Einladungs-/Aktivierungs-/Reset-Flow (Paket 4)** | ⏸️ zurückgestellt | E-Mail-Versand bewusst später; die Nutzer-Aktivierung läuft vorerst über Initial-/Einmal-Passwort und ist so gekapselt, dass der Einladungs-Flow ohne Umbau ergänzt werden kann. |
|
||||
|
||||
## Was ist das Produkt
|
||||
|
||||
Multi-Tenant-**SaaS für Informationssicherheits-Management (ISMS)**, ausgerichtet auf **ISO/IEC 27001:2022** und **TISAX / VDA-ISA 2027**. Web-App (Deutsch, EN vorbereitet), Dark-Theme, mandantenfähig (mehrere Kunden, Nutzer, Rollen). Mehrere fachliche Module + Plattform-/Kundenverwaltung.
|
||||
|
||||
**Aufwands-Legende:** **S** = klein (≤ 1 Tag) · **M** = mittel (2–4 Tage) · **L** = groß (> 1 Woche).
|
||||
|
||||
---
|
||||
|
||||
## ✅ Umgesetzt (produktiv nutzbar)
|
||||
|
||||
| # | Modul | Umfang (Kurz) |
|
||||
|---|-------|---------------|
|
||||
| 1 | **Fundament** | Login/Auth (lokale Accounts, NextAuth v5, JWT), **RBAC** (granulare Rechte, Rollen je Mandant), **Mandanten-Isolation** (tenant_id + Postgres-RLS + zentraler App-Guard), i18n (de/en), Dark-Theme (zentrale Tokens), Audit-Log. |
|
||||
| 2 | **Assets & BIA** | Asset-Inventar + Geschäftsprozesse/BIA als ein Modul; C/I/A-Schutzbedarf, Vererbung, Abhängigkeiten; Detail/Bearbeiten/Anlegen als Popups; zugeordnete Risiken. |
|
||||
| 3 | **Risikoanalyse** | 5×5-Heatmap, Risikoregister, Risiko-Detail mit Maßnahmen (dezimale Minderung, Brutto→Rest visualisiert), Bedrohungs-/Schwachstellen-Kataloge, Control-Verknüpfung. |
|
||||
| 4 | **Maßnahmen** | Kanban-Board (Drag & Drop), berechnetes Restrisiko aus Maßnahmen. |
|
||||
| 5 | **Abhängigkeiten & kritische Pfade** | Interaktiver Graph (React Flow + dagre), Single Points of Failure, kritische Pfade. |
|
||||
| 6 | **Lieferanten- & IT-Service-Management** | Asset-basiert (Lieferant/IT-Service **sind** Assets); Anforderungs-Engine (Schutzbedarf→Stufen), Gate-Logik (erzeugt echte Risiken), ISB-Reifegrad-Freigabe; **RACI-Matrix** über ISA-Controls (VDA-ISA 6.1.3); Cockpit direkt aus dem Asset-Inventar öffenbar. |
|
||||
| 7 | **Richtlinien & Verfahren (VDA-ISA 2027)** | Siehe Detailblock unten — größtes Modul. |
|
||||
| 8 | **Admin-Konsole & Mandantenverwaltung (Phase 1)** | Plattform-Admin (`/admin`): Kunden anlegen + **automatisch provisionieren**, Module-Toggles, Lebenszyklus (aktiv/gesperrt/archiviert). Kunden-Einstellungen (`/settings`): Stammdaten → speisen ISMS-Variablen, Branding, TISAX-Level. **Serverseitige Modul-Durchsetzung** (deaktivierte Module gesperrt, nicht nur ausgeblendet). |
|
||||
|
||||
### Modul 7 „Richtlinien & Verfahren" im Detail (umgesetzt)
|
||||
- **Import** des VDA-ISA-2027-Vorlagenpakets: **28 Dokumente** (Leitlinie L00, R01–R14, VA-01–VA-13), **316 Anforderungen** (122 MUSS · 132 SOLL · 43 HOHER · 19 SEHR HOHER Schutzbedarf) über **45 Controls**; Baseline-Parameter, Variablen, Nachweisregister.
|
||||
- **Rendering-Engine**: Handlebars (verschachtelte `{{#if}}`-Flags), Variablen aus einer Pflegestelle, Deep-Links, BL-Referenzen im Lesemodus entfernt; rückstandsfrei über alle Flag-Kombinationen.
|
||||
- **Bibliothek** + **Referenz-/Coverage-Matrix** (zwei Richtungen: nach Control / nach Dokument).
|
||||
- **Lesemodus** als eigene Seite (kein Popup); **Bearbeitungsmodus** variablenbasiert + **Vier-Augen-Freigabe** (Entwurf → In Freigabe → Freigegeben); **Experten-Modus** (Rohtext-Editor + Formatier-/Einfügehilfen + Auto-Anlage neuer Variablen).
|
||||
- **Verwaltete Register** (editierbar): Verschlüsselungsregister (mit Ablaufüberwachung), Risiko-Bewertungsmatrix (FB-80-04-Defaults), Klassifizierungs-Handhabungsmatrix (AA-80-20). **Anwender-Handbuch** (kuratiert, Baseline-synchron, Deep-Links).
|
||||
- **Schutzbedarf-/TISAX-Level-Schalter (AL2/AL3)** global + **Override je Richtlinie**.
|
||||
|
||||
---
|
||||
|
||||
## 🟥 Offen — Hohe Priorität
|
||||
|
||||
| Thema | Aufwand | Anmerkung |
|
||||
|-------|:------:|-----------|
|
||||
| **NIS2-Modul** (nie begonnen) | **L** | Framework Art. 20/21 + Control-Mapping, Einrichtungs-Einstufung + BSI-Registrierung, **Incident-Reporting-Workflow mit Fristen-Timern (24 h / 72 h / 1 Monat)**, NIS2-Dashboard. War „Teil C" der ursprünglichen Planung. |
|
||||
| **Admin-Konsole Phase 2 — Impersonation** | **M** | Zeitlich begrenzter, protokollierter Support-Zugriff in einen Mandanten; „Support-Sitzung aktiv"-Banner; automatischer Ablauf. |
|
||||
| **Admin-Konsole Phase 2 — Plan/Limits** | **M** | Lizenzstufen, Limits (Nutzer/Speicher/Assets), Warnung/Sperre bei Überschreitung. |
|
||||
| **Separater Superadmin-Store + eigener Login + MFA-Pflicht** | **M–L** | Aktuell ist der Superadmin ein `isPlatformAdmin`-Nutzer im Mandanten (Demo). Spec fordert getrennte Accounts + eigenen Login-Pfad. |
|
||||
| **Richtlinien: echte Versionierung + Diff** | **M–L** | Aktuell ändert die Freigabe nur den Status (ohne Versionshistorie/Diff). Entwurf-neben-Freigegeben, block-/klauselgenauer Diff. |
|
||||
| **Richtlinien: DOCX/PDF-Export** | **M** | Voll gerendert im GEFIM-Corporate-Design; Referenz-/Nachweisdoku separat. |
|
||||
|
||||
---
|
||||
|
||||
## 🟧 Offen — Mittlere Priorität
|
||||
|
||||
| Thema | Aufwand | Anmerkung |
|
||||
|-------|:------:|-----------|
|
||||
| **Richtlinien: Status „Revoked" + Auto-Version** | **S** | Vom Kunden ausdrücklich für später gemerkt: Status-Auswahl inkl. Revoked (manuell), Version zählt bei jedem Speichern automatisch hoch. |
|
||||
| **Richtlinien: Word-Upload (.docx-Import)** | **M** | Eigene Dokumente hochladen → Block-Modell + Original als Anhang, versioniert, im Freigabeprozess. |
|
||||
| **Richtlinien: KI-Wizard** | **L** | Geführte Erstellung/Anpassung (control-getrieben, Feature-Flags/Reifegrad), KI formuliert Blocktext. |
|
||||
| **Richtlinien: KI-Formulierungshilfe im Experten-Modus** | **M** | Braucht Anthropic-API-Anbindung. |
|
||||
| **Zentrale Baseline-/Variablen-Einstellseite** | **S–M** | Eine Pflegestelle mit Freigabe-Durchlauf. |
|
||||
| **Admin Phase 2 — Logo-Upload / Objektspeicher je Mandant** | **M** | Für UI-Kopf + Export (Branding/Whitelabel). |
|
||||
| **Admin Phase 2 — SMTP/Benachrichtigungen + Einladungs-/Aktivierungs-Flow** | **M** | E-Mail-Einladung, Passwort-Setzen, Benachrichtigungsregeln (Fristen/Freigaben/Vorfälle). |
|
||||
| **Lieferanten Phase 2** | **M–L** | Fragebogen-Builder, Self-Service-Portal (externer Lieferantenzugang), Scheduler (Review-/Ablauf-Erinnerungen). |
|
||||
| **Risikomatrix zusammenführen** | **M** | Bewertungsmatrix im Richtlinienmodul ist eigene 4×4-Pflegestelle (FB-80-04); Risikoanalyse nutzt 5×5. Auf eine gemeinsame, zentrale Skala vereinheitlichen. |
|
||||
| **Platzhalter-Module ausbauen** | je **M–L** | Sidebar-Punkte vorhanden, aber nicht gebaut: **SoA & Controls**, **Vorfälle**, **Nachweise**, **Management-Review**, **KI-Chat**. |
|
||||
|
||||
---
|
||||
|
||||
## 🟩 Offen — Niedrige Priorität / Technische Schulden
|
||||
|
||||
| Thema | Aufwand | Anmerkung |
|
||||
|-------|:------:|-----------|
|
||||
| **Modul-Durchsetzung auf API-Ebene vervollständigen** | **S** | Route-Zugriff (GET) ist für alle Module gesperrt; der `requireModule`-Guard in Server-Actions ist bisher **exemplarisch nur für Richtlinien** gesetzt. Einzeiler je Action-Guard nachziehen. |
|
||||
| **Richtlinien-Re-Import ist destruktiv** | **M** | Re-Import löscht + legt Dokumente/Anforderungen neu an (setzt per-Dokument-Status/Override/Freigabe zurück). Spec wünscht „deaktivieren statt löschen" + Historie erhalten. |
|
||||
| **Coverage zeigt alle statt nur aktive Anforderungen** | **S** | Referenzmatrix listet vollständig (gut für Audit); optional Filter „nur aktive" nach effektiven Flags. |
|
||||
| **Admin Phase 2 — Datenexport/Löschung/Retention (DSGVO)** | **L** | Mandantenvollständiger Export, Löschkonzept, Aufbewahrungsfristen. |
|
||||
| **Optionale Zusatzfeatures** | je **M** | SSO (OIDC/SAML), API-Keys/Webhooks, Onboarding-Wizard, E-Mail-Domain-Allowlist, Wartungs-/Status-Banner. |
|
||||
|
||||
---
|
||||
|
||||
## Hinweise für die Planung
|
||||
|
||||
- **Spezifikationen** liegen im Repo: `docs/SPEC.md` (Gesamt-Spec) sowie die Übergabe-Prompts und Mockups je Modul (Richtlinien, Admin-Konsole). Neue Anforderungen kamen bisher als „Delta-Prompts" (z. B. TISAX-Level-Update).
|
||||
- **Nächster logischer Block:** entweder **NIS2** (letztes großes Framework, hängt am Incident-/Vorfälle-Modul) oder **Admin-Konsole Phase 2** (Impersonation + Plan/Limits + Superadmin-Login), je nach Vertriebs-/Compliance-Priorität.
|
||||
- **Demo-Umgebung:** Mandant „demo", Login `admin@demo.example` (ist Superadmin + Mandanten-Admin), Passwort im Seed. 4 Demo-Rollen vorhanden.
|
||||
- **Qualität:** Jede Iteration wurde mit `tsc` + `lint` + `build` und – wo möglich – Browser-Verifikation abgeschlossen; Commits sind fein granular und je Thema.
|
||||
@@ -0,0 +1,238 @@
|
||||
# Implementierungsfaden — TISAX-Onboarding-Wizard Neustruktur
|
||||
|
||||
> Status: Entwurf · Grundlage: Konzept v2 (4 Ebenen, nach TISAX-Fachprüfung) + IST-Analyse des Task-Moduls (Branch `dev-tasks-kanban`, `ce1e847`).
|
||||
> Ziel: Aus dem linearen 9-Schritt-Monolithen `/onboarding` werden vier Ebenen — **Fundament → Strukturanalyse → Cockpit → Audit** — informationszentriert, prozessgeführt erhoben, bereichsbasiert umgesetzt.
|
||||
|
||||
---
|
||||
|
||||
## 0. Ausgangslage & Auswirkung der Kanban-Anpassung
|
||||
|
||||
Das Task-Modul wurde zwischenzeitlich auf ein **Kanban-Board** umgestellt (`src/components/kanban-board.tsx`, `src/app/(app)/tasks/page.tsx`, Action `updateTaskStatus`, Status `IN_PROGRESS`). Das ist die Basis für Ebene 3 — das Bereichs-Board wird **additiv** darauf gebaut, nicht neu.
|
||||
|
||||
**Bereits vorhanden (nutzbar):** generisches Task-Modell, Kanban mit DnD-Statuswechsel, `assigneeId` + `createdById` + Vier-Augen-Freigabe, PROPOSED→OPEN/DISCARDED-Vorschlagsmechanik, Wizard-Trigger (`task-triggers.ts`, `proposeTasksFromTriggers`), polymorphe `links`-Json + harte `entityType/entityId`-Kopplung, Teil-Sync Task→Objekt bei Policy-Freigabe (`approveTask`).
|
||||
|
||||
**Fehlt (dieser Plan liefert es):** `domain`/Bereich, RACI/Mitwirkende, `orderIdx`, Recurrence/Wiedervorlage, Auto-Completion-Deckel, Bereichs-/Personen-Filter, harte Control-/Evidence-Verknüpfung, Information als Kernobjekt.
|
||||
|
||||
**Altlasten (Vorarbeit M0):**
|
||||
- `TASK_STATUSES` in `src/lib/tasks.ts` enthält `IN_PROGRESS` nicht, obwohl Board/Actions ihn nutzen → Inkonsistenz beheben.
|
||||
- `src/app/(app)/tasks/page.tsx:166` referenziert `open` — im File nicht definiert (nur `myOpen`/`active`/`proposals`/`terminal`). Verifizieren & fixen.
|
||||
|
||||
---
|
||||
|
||||
## 1. Datenmodell (Prisma-Migrationen)
|
||||
|
||||
Konventionen wie im Bestand: `cuid()`-IDs, `tenantId`, `@@map(snake_case)`, `@@unique([tenantId, …])`. Enums additiv; freie `String`-Statusfelder brauchen keine Migration.
|
||||
|
||||
### 1.1 Werte-Modell: Information IST ein (primärer) Asset — kein Extra-Objekt
|
||||
|
||||
**Korrektur ggü. erstem Entwurf.** Ein Informationswert ist kein neues Objekt neben dem Asset, sondern ein **primärer Asset** (ISO 27005 / TISAX: primäre Werte = Informationen + Prozesse; sekundäre = Träger). Euer Schema bildet das bereits ab:
|
||||
- `AssetType.INFORMATION` / `DATA` = primäre Werte; `SYSTEM/APPLICATION/LOCATION/SUPPLIER/IT_SERVICE/SOFTWARE/PERSON` = sekundär/Träger.
|
||||
- `ProcessAsset.role = PRIMARY | SECONDARY` trennt primär/sekundär je Prozess-Beziehung.
|
||||
- `AssetRelation` bildet Träger-Abhängigkeiten ab; `confidentiality/integrity/availability` liegen schon am `Asset`.
|
||||
|
||||
→ **Kein** `InformationValue`/`ProcessInformation`/`InformationAsset`. Stattdessen kleine Ergänzungen am Bestand:
|
||||
|
||||
```prisma
|
||||
enum InfoLabel { NONE INFO_HIGH INFO_VERY_HIGH PROTOTYPE PERSONAL_DATA }
|
||||
|
||||
model Asset {
|
||||
// … Bestand (type, C/I/A, ownerId, status, tags) …
|
||||
normalizedName String? // Dedup-Schlüssel (s. 2.1)
|
||||
label InfoLabel @default(NONE) // Info hoch/sehr hoch, Prototyp, personenbezogen → steuert Scope/Bereiche
|
||||
@@unique([tenantId, normalizedName]) // verhindert Exakt-Duplikate (v.a. type INFORMATION/DATA)
|
||||
}
|
||||
```
|
||||
|
||||
**Primär/sekundär** bleibt über `ProcessAsset.role`. Optional als intrinsische Klassifikation `Asset.tier (PRIMARY|SUPPORTING)`, ableitbar aus `type` — nur einführen, falls die Rolle je Prozess nicht ausreicht (s. offene Entscheidung 4.1).
|
||||
**Schutzbedarf:** bleibt am `Asset`. Primäre Informations-Assets tragen den echten C/I/A-Wert; sekundäre erben per **Maximum** der von ihnen getragenen primären Assets.
|
||||
**„Erhebung über den Prozess":** Im Prozess-Schritt werden primäre Informations-Assets erfasst (Dedup/Autocomplete gegen bestehende Assets, 2.1), dann Träger-Assets via `ProcessAsset(SECONDARY)` + `AssetRelation` verknüpft. Anker = das primäre Informations-Asset. **Keine Datenmigration nötig** — nur additive Spalten.
|
||||
|
||||
### 1.2 Standard-Prozess-Katalog (Ebene 2)
|
||||
|
||||
```prisma
|
||||
model ProcessCatalogEntry { // global, kein tenantId
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
name String
|
||||
category ProcessCategory // CORE | MANAGEMENT | SUPPORT (Neben→SUPPORT)
|
||||
suggestedAssetTypes AssetType[]
|
||||
suggestedRiskCodes String[] // → RiskCatalogEntry.code
|
||||
suggestedInfoLabels InfoLabel[]
|
||||
@@map("process_catalog")
|
||||
}
|
||||
```
|
||||
|
||||
### 1.3 Team / Funktionszuordnung (Ebene 1)
|
||||
|
||||
Heute sind ISMS-Rollen read-only Variablen. Neu: echte Zuordnung Funktion→User(n) inkl. „unbesetzt".
|
||||
|
||||
```prisma
|
||||
model ProjectFunctionAssignment {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
functionKey String // ISB, PM, HR_LEAD, IT_LEAD, BCM, AUDITOR_INT, DPO …
|
||||
userId String? // null = unbesetzt → erzeugt Task „Funktion besetzen"
|
||||
domain Domain? // Default-Bereich dieser Funktion (Sichtbarkeit)
|
||||
invitedEmail String? // Einladung, falls Account noch nicht existiert
|
||||
createdAt DateTime @default(now())
|
||||
@@index([tenantId, functionKey])
|
||||
@@map("project_function_assignments")
|
||||
}
|
||||
```
|
||||
|
||||
### 1.4 Bereich (Domain) & Control→RACI-Mapping (Ebene 3)
|
||||
|
||||
```prisma
|
||||
enum Domain { GOVERNANCE HR PHYSICAL BCM IT PROCUREMENT COMPLIANCE DATA_PROTECTION PROTOTYPE }
|
||||
enum RaciKind { RESPONSIBLE ACCOUNTABLE CONSULTED INFORMED }
|
||||
|
||||
model ControlDomainMap { // global default; tenant-Override via tenantId
|
||||
id String @id @default(cuid())
|
||||
tenantId String? // null = globaler Default
|
||||
control String // "3.1.4" oder Kapitel-Präfix "3"
|
||||
domain Domain
|
||||
raci RaciKind @default(RESPONSIBLE)
|
||||
functionKey String? // Default-Verantwortliche Funktion
|
||||
@@map("control_domain_map")
|
||||
}
|
||||
```
|
||||
|
||||
Seed-Defaults (Kapitel → Bereich), fachlich korrigiert:
|
||||
| Kapitel | Domain | Anmerkung |
|
||||
|---|---|---|
|
||||
| 1 | GOVERNANCE | ISB + Management |
|
||||
| 2 | HR | |
|
||||
| 3 (phys.) | PHYSICAL | |
|
||||
| 3 (BCM) | BCM | **aus K3 gelöst** — eigener Bereich |
|
||||
| 4 IAM | IT + **HR (CONSULTED)** | Joiner-Mover-Leaver |
|
||||
| 5 | IT | |
|
||||
| 6 | PROCUREMENT + **ISB/Recht (CONSULTED)** | |
|
||||
| 7 | COMPLIANCE + **DPO/IT (CONSULTED)** | |
|
||||
| Prototyp | PROTOTYPE | nur bei Label |
|
||||
| Datenschutz | DATA_PROTECTION | nur bei Label |
|
||||
|
||||
### 1.5 Task-Erweiterungen (Ebene 3)
|
||||
|
||||
```prisma
|
||||
model Task {
|
||||
// … Bestand …
|
||||
domain Domain? // Bereich (Default aus ControlDomainMap)
|
||||
orderIdx Int @default(0) // manuelle Sortierung je Bereich
|
||||
recurrence String? // ISO-8601-Dauer/RRULE, z.B. "P1Y"
|
||||
remindAt DateTime?
|
||||
effectiveUntil DateTime? // Wirksamkeitsintervall (Wiedervorlage)
|
||||
participants TaskParticipant[]
|
||||
@@index([tenantId, domain, status])
|
||||
}
|
||||
|
||||
model TaskParticipant { // RACI zusätzlich zu assigneeId (=primär Responsible)
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
taskId String
|
||||
userId String
|
||||
raci RaciKind
|
||||
@@unique([tenantId, taskId, userId, raci])
|
||||
@@map("task_participants")
|
||||
}
|
||||
```
|
||||
|
||||
### 1.6 Nachweis-/Evidence-Register (Ebene 3+4)
|
||||
|
||||
```prisma
|
||||
model Evidence {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
title String
|
||||
kind String // record | protocol | screenshot | export
|
||||
fileRef String?
|
||||
taskId String?
|
||||
control String?
|
||||
validFrom DateTime?
|
||||
validUntil DateTime? // koppelt an Task.effectiveUntil
|
||||
createdAt DateTime @default(now())
|
||||
@@index([tenantId, control])
|
||||
@@map("evidence")
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Querschnitts-Bausteine
|
||||
|
||||
### 2.1 Dedup-Erkennung & Autovervollständigung für Informationswerte
|
||||
|
||||
Kernanforderung: Menschen erfassen über den Prozess, sollen aber denselben Wert nicht doppelt anlegen (auch nicht bei abweichender Groß-/Kleinschreibung).
|
||||
|
||||
- **Normalisierung → `normalizedName`:** `trim` → Mehrfach-Whitespace kollabieren → Unicode-NFC → `toLowerCase` (locale-aware `de`) → Umlaut-Faltung (ä→ae, ö→oe, ü→ue, ß→ss) → Satzzeichen entfernen. Ergebnis ist der `@@unique`-Schlüssel.
|
||||
- Beispiel: „Kundendaten", „kundendaten", „ Kundendaten " → alle `kundendaten`.
|
||||
- **Exakt-Duplikate:** durch `@@unique([tenantId, normalizedName])` unmöglich; bei Kollision wird das bestehende Asset *verknüpft* (`ProcessAsset`) statt neu angelegt.
|
||||
- **Autovervollständigung:** As-you-type-Suche im Server (`searchAssets(query)`, gefiltert auf `type INFORMATION/DATA`) gegen (a) das Tenant-Asset-Register und (b) globale Katalog-Vorschläge. Treffer zeigen „bereits erfasst in Prozess X" → ein Klick verknüpft.
|
||||
- **Fuzzy-Nah-Duplikate (weiche Warnung):** Trigramm-/Levenshtein-Ähnlichkeit auf `normalizedName`; ab Schwelle „Meintest du *Kundendaten*?" **vor** dem Anlegen. Bei Postgres optional `pg_trgm` (`similarity()`), sonst in-app Levenshtein auf der Kandidatenliste.
|
||||
- **UI:** Combobox (bestehendes `components.json`/shadcn-Setup) mit Vorschlagsliste, Badge „neu" vs. „verknüpfen".
|
||||
|
||||
### 2.2 Auto-Completion-Engine — gedeckelt
|
||||
|
||||
Zentrale Funktion `syncTaskFromObject(entityType, entityId)`, aufgerufen bei Statuswechsel von Policy/Risk/Control/Asset. Fachprüfungs-Regel: **Existenz ≠ Wirksamkeit.**
|
||||
|
||||
| Auslöser | Task geht auf … | Deckel |
|
||||
|---|---|---|
|
||||
| `PolicyDocument.status = FREIGEGEBEN` | `DONE` (dokumentiert) | Reifegrad 3 / audit-ready nur mit verknüpftem `Evidence` + Vier-Augen |
|
||||
| Asset C/I/A + Owner gesetzt | `DONE` | — |
|
||||
| `Risk.status = ACCEPTED/CLOSED` | `DONE` | Restrisiko gesetzt |
|
||||
| `ControlImplementation.status = erledigt` | `DONE` (umgesetzt) | Reifegrad-Anhebung getrennt bestätigen |
|
||||
|
||||
- Kein Auto-`DONE` ohne mindestens dokumentierten Zustand; „audit-ready" ist ein **separater, manueller** Schritt mit Nachweis.
|
||||
- **Wiedervorlage:** Tasks mit `recurrence` erzeugen bei `DONE` automatisch eine Folge-Task mit neuem `dueDate`/`effectiveUntil` (Serienlogik).
|
||||
|
||||
### 2.3 Bereichs-Sichtbarkeit & RACI
|
||||
|
||||
- Default-Sicht: **eigene Bereiche** (aus `ProjectFunctionAssignment.domain` des Users) + eigene/zugewiesene Tasks + Pool.
|
||||
- **PM + ISB:** `task:read_all` (existiert bereits) → alle Bereiche.
|
||||
- Gezielte Mitwirkung: Eintrag in `TaskParticipant` (CONSULTED/INFORMED) macht Task für die Person sichtbar, ohne ihr den ganzen Bereich zu öffnen.
|
||||
- Kanban erhält einen **Bereichs-Selektor** (Lane-Filter) zusätzlich zu den Status-Spalten; Sortierung je Bereich nach `orderIdx`, dann Priorität.
|
||||
|
||||
---
|
||||
|
||||
## 3. Meilenstein-Faden (jeder Schritt einzeln lauffähig)
|
||||
|
||||
### M0 · Vorarbeit & Bereinigung
|
||||
- `TASK_STATUSES` um `IN_PROGRESS` ergänzen (`src/lib/tasks.ts`); `open`-Bug in `tasks/page.tsx:166` verifizieren/fixen.
|
||||
- Enums `Domain`, `RaciKind`, `InfoLabel`, `InfoProcessRole` + Task-Felder `domain`/`orderIdx` (nullable) migrieren — noch ohne UI-Wirkung.
|
||||
- *Risiko: minimal. Kein Verhaltensbruch.*
|
||||
|
||||
### M1 · Ebene 1 „Fundament" (Wizard-Umbau Teil 1)
|
||||
- Onboarding-Steps in `src/lib/onboarding/register-steps.ts` neu ordnen/ergänzen: `context` → `scope` (einfrieren) → `policy` (Leitlinie, verlinkt Richtlinien-Modul) → `roles`(Team) → `criteria` (Risikoakzeptanz + C/I/A-Skala).
|
||||
- **Team-Entität** `ProjectFunctionAssignment` + Zuweisen/Einladen-Flow (Schritt `roles`). Neue Funktionen: BCM, unabhängiger interner Auditor, DPO, Asset-/Risk-Owner-Kennzeichnung.
|
||||
- Leitlinie als Fundament-Artefakt (nicht als Cockpit-Task).
|
||||
- *Betroffen: `src/app/(app)/onboarding/steps/*`, `src/server/roles.ts`, `src/server/actions/onboarding*.ts`.*
|
||||
|
||||
### M2 · Ebene 2 „Strukturanalyse" (Information = primärer Asset)
|
||||
- Additive `Asset`-Spalten (`normalizedName`, `label`) + `ProcessCatalogEntry` migrieren. **Keine** Datenmigration — Bestand bleibt gültig.
|
||||
- Wizard-Fluss **prozessgeführt**: Prozesse wählen (Katalog) → je Prozess primäre Informations-Assets erfassen (Combobox mit Dedup/Autocomplete, 2.1) → Träger-Assets (`ProcessAsset SECONDARY`: System/Anwendung/Raum/Person/Dienstleister/Standort) → Schutzbedarf am Asset (Maximum/Kumulation/Verteilung) → Risiken aus Katalog.
|
||||
- *Betroffen: neue Steps `processes`/`assets`/`protection`/`risks`, `RiskCatalogEntry`-Matching (existiert).*
|
||||
|
||||
### M3 · Ebene 3 „Cockpit" auf bestehendem Kanban
|
||||
- `ControlDomainMap` seeden (Tabelle 1.4); Task-Erzeugung (`soa.ts`, `task-triggers.ts`, `gap.ts`) setzt `domain` + Default-RACI.
|
||||
- Kanban erweitern: Bereichs-Lane/-Filter + Personen-Filter; Default „meine Bereiche"; `orderIdx`-Sortierung (DnD persistiert Reihenfolge).
|
||||
- `TaskParticipant` (RACI) + Sichtbarkeitslogik (2.3).
|
||||
- **Auto-Completion-Engine** (2.2) + Recurrence/Wiedervorlage; `Evidence`-Register.
|
||||
- Fragebogen (`context`) auf Bereiche verteilen → Fragen erzeugen Tasks im jeweiligen Bereich.
|
||||
- *Betroffen: `kanban-board.tsx`, `tasks/page.tsx`, `src/server/actions/tasks.ts`, `soa.ts`, `policies.ts` (Sync-Hook).*
|
||||
|
||||
### M4 · Ebene 4 „Audit-Wizard" abtrennen
|
||||
- Neuer, aktivierbarer Wizard aus heutigen Steps `gap` + `readiness`; **internes Audit** (unabhängig, AL3-Pflicht) als eigener Schritt ≠ Readiness-Snapshot.
|
||||
- Reifegrad + Nachweise laufen bereits kontinuierlich (M3) → hier nur Konsolidierung + Management-Review.
|
||||
- *Betroffen: neue Route `/audit-readiness` o. ä., Auslagern aus `onboarding/register-steps.ts`.*
|
||||
|
||||
---
|
||||
|
||||
## 4. Offene Entscheidungen
|
||||
1. **Primär/sekundär — intrinsisch oder relational?** Reicht `ProcessAsset.role` (Rolle je Prozess), oder soll ein intrinsisches `Asset.tier (PRIMARY|SUPPORTING)` als Wahrheit ergänzt werden (ableitbar aus `type`)? → Vorschlag: mit `role` starten, `tier` nur bei Bedarf. *(C/I/A-Ablageort ist entschieden: bleibt am `Asset`, sekundär erbt per Maximum.)*
|
||||
2. **Fuzzy-Matching-Technik:** `pg_trgm` (DB-nah, schnell) vs. in-app Levenshtein (DB-agnostisch). → Abhängig davon, ob Postgres-Extension im Coolify-Deployment verfügbar ist.
|
||||
3. **RACI-Tiefe:** volle RACI oder zunächst nur Responsible + Consulted (Sichtbarkeit)? → Vorschlag: klein starten (R + C), A = ISB/PM implizit.
|
||||
4. **Audit-Wizard-Aktivierung:** manuell vs. ab Coverage-Schwelle.
|
||||
|
||||
---
|
||||
|
||||
## 5. Reihenfolge-Logik (warum dieser Faden)
|
||||
M0 legt risikolos das Datenfundament. M1–M2 bauen die *sequenziellen* Ebenen (Setup/Strukturanalyse), auf denen alles Weitere aufsetzt — inkl. der informationszentrierten Struktur, dem größten Modell-Hebel. M3 nutzt maximal das bereits vorhandene Kanban (additiv statt Neubau). M4 ist die saubere Abtrennung am Ende. Jeder Meilenstein ist für sich lauffähig und liefert sichtbaren Nutzen.
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,135 @@
|
||||
# Konzept — Datensicherung, Wiederherstellung, DSGVO-Export & Löschung (certvia)
|
||||
|
||||
> Status: **Konzept/Entscheidungsvorlage** (kein Code). Produkt: **certvia** (ISMS-Tool, Single-DB + Postgres-RLS, alle Mandanten in denselben Tabellen mit `tenant_id`). Kernidee: **eine mandanten-scoped Traversierungs-Engine** bedient vier Zwecke — Per-Tenant-Backup, gezielten Restore, DSGVO-Auskunft/-Export und DSGVO-Löschung/Offboarding.
|
||||
|
||||
## 0. Zielbild
|
||||
1. **Disaster-Recovery** der gesamten DB (Totalausfall, Ransomware, „Zeitpunkt-T-Wiederherstellung").
|
||||
2. **Gezielter Einzelkunden-Restore** (Kunde A zurück, Kunde B unangetastet) — über das **Betreiber-Portal**.
|
||||
3. **DSGVO-Auskunft/-Datenportabilität** (Art. 15/20) — je Mandant und je betroffener Person.
|
||||
4. **DSGVO-Löschung** (Art. 17) — ganzer Mandant (Offboarding) und einzelne Person, mit ISMS-konformer Aufbewahrung.
|
||||
|
||||
Alle vier teilen sich **einen** Baustein: das Durchlaufen aller mandantengescopten Tabellen in FK-Reihenfolge, gefiltert auf `tenant_id` (bzw. auf eine Person).
|
||||
|
||||
## 1. Architektur-Grundlage (bestehend, wird genutzt)
|
||||
- **`TENANT_MODELS`** (`src/server/db.ts`) = autoritative Menge aller mandantengescopten Tabellen. Plus deren FK-Topologie ⇒ die verbindliche Reihenfolge für Export (parent→child) und Löschung (child→parent).
|
||||
- **`tenant_id`-Spalte + RLS** ⇒ jede Operation `WHERE tenant_id = A` ist **beweisbar** auf einen Mandanten begrenzt.
|
||||
- **cuid-Primärschlüssel** (kein Serial) ⇒ Reinsert kollisionsfrei, IDs bleiben erhalten, keine Sequenz-Konflikte.
|
||||
- **Owner-`prisma`-Client** (BYPASSRLS) für Backup/Restore/Löschung; **nie** der RLS-Client.
|
||||
- **Globale Tabellen** (Kataloge, `Permission`, `Tenant`-Stammsatz, künftig **`Identity`**) sind **nicht** tenant-scoped → über Schicht A gesichert, nicht Teil des Tenant-Artefakts.
|
||||
- **MinIO/S3** hält Dateien/Logos je Mandant (Prefix) — DB-Backup allein reicht nicht.
|
||||
|
||||
## 2. Schicht A — Cluster-Disaster-Recovery (ganze DB)
|
||||
- **pgBackRest** oder **wal-g**: periodisches Vollbackup + kontinuierliches **WAL-Archiving** nach S3/offsite ⇒ **PITR** (Point-in-Time-Recovery).
|
||||
- Zweck: Totalausfall/Ransomware/menschlicher Massenfehler → „DB auf Zeitpunkt T".
|
||||
- **Verschlüsselt** (SSE-KMS oder client-seitig) — dockt an die (vorerst geparkte) DB-Härtung an.
|
||||
- Deckt auch die **globalen** Tabellen inkl. `Identity`/Credentials ab, die Schicht B bewusst nicht anfasst.
|
||||
|
||||
## 3. Schicht B — Mandanten-scoped Logical Export/Restore
|
||||
### Export (Backup-Artefakt je Mandant)
|
||||
- Aus **einem konsistenten Snapshot** (`REPEATABLE READ`-Transaktion), damit die FK-Integrität innerhalb des Mandanten stimmt.
|
||||
- Je Tabelle aus `TENANT_MODELS`: `COPY (SELECT * FROM t WHERE tenant_id = 'A') TO …` → ein Artefakt (z. B. NDJSON/COPY) pro Mandant → gzip → verschlüsselt nach S3.
|
||||
- Enthält **zusätzlich** den MinIO-Prefix des Mandanten (Datei-Snapshot) und ein **Manifest** (Schema-/Migrationsversion, Zeitstempel, Zeilenzahlen je Tabelle, Prüfsummen).
|
||||
- Zeitplan: nächtlich + **on-demand vor riskanten Operationen** (Restore, Massen-Import).
|
||||
|
||||
### Restore (gezielt Kunde A)
|
||||
- Owner-Client, **eine Transaktion**, FK-Reihenfolge, alles `WHERE tenant_id = 'A'`:
|
||||
1. Mandant **sperren** (`status = SUSPENDED`) → keine parallelen Schreibzugriffe.
|
||||
2. **Pre-Restore-Sicherheitsschnappschuss** des aktuellen Standes (Restore ist damit reversibel).
|
||||
3. **Replace**: `DELETE … WHERE tenant_id='A'` (child→parent) + Reinsert aus dem Artefakt (parent→child). Constraints ggf. `DEFERRED`.
|
||||
4. MinIO-Prefix des Mandanten wiederherstellen.
|
||||
5. Mandant reaktivieren, **Audit** schreiben.
|
||||
- **Beweisbar sicher** für andere Mandanten: keine Operation verlässt `tenant_id='A'`.
|
||||
- Schema-Version im Manifest gegen aktuelle Migration prüfen; bei Differenz Artefakt vor Reinsert migrieren/abweisen.
|
||||
|
||||
## 4. Betreiber-Portal — Restore-Flow
|
||||
Restore ist eine **Betreiber**-Fähigkeit (kein Mandanten-Admin) → Plattform-Portal (`/admin`, `platformAuth`).
|
||||
- **Auslöser:** Aktion „Wiederherstellen" auf `/admin/[id]`, gegated durch **`requirePlatformFullAdmin` + frischer MFA-Step-up** (`assertPlatformStepUp`).
|
||||
- **Auswahl:** Mandant + Sicherungspunkt (Liste der Per-Tenant-Snapshots / PITR-Zeitpunkt) + **Vorschau/Dry-run** (Zeilenzahlen, Snapshot-Zeit) + **getippte Bestätigung** („RESTORE kunde-a").
|
||||
- **Ausführung als Hintergrund-Job im Worker** (BullMQ, vorhanden) — **nicht** inline in der Server-Action (Timeouts/Progress/Audit). Die Action **enqueued** nur.
|
||||
- **Kontrollen:** Sperre während Restore · Pre-Restore-Schnappschuss · `tenant_id`-Scope · Plattform-Audit (wer/Mandant/Snapshot/wann) · MinIO mit.
|
||||
|
||||
## 5. DSGVO-Export (Art. 15 Auskunft / Art. 20 Portabilität)
|
||||
**Rollen (wichtig):** certvia ist **Auftragsverarbeiter**, der Mandant ist **Verantwortlicher**. Anfragen richten sich an den Mandanten; certvia liefert das **Werkzeug**. Deshalb existiert der Export an **zwei** Stellen:
|
||||
- **Mandanten-Self-Service** (Mandanten-Admin, für die eigenen Betroffenen),
|
||||
- **Betreiber-Portal** (AVV-Unterstützung / Ausfallhilfe).
|
||||
|
||||
**Zwei Granularitäten:**
|
||||
1. **Per-Mandant** — der gesamte Kundendatensatz (= das Backup-Artefakt aus §3, maschinenlesbar/JSON). Nutzen: Portabilität beim Anbieterwechsel, Offboarding-Kopie.
|
||||
2. **Per-Betroffener** (eine natürliche Person) — alle personenbezogenen Zeilen dieser Person: `User` (Mitgliedschaft), Auth-Daten aus **`Identity`** (Existenz/E-Mail/MFA-Status — **keine** Secrets), sowie alle Referenzen (`owner_id`, `assigneeId`, `createdBy`, `AuditLog.actorId`, `TaskParticipant`, `Audit.*UserId`, …) und Freitext mit Personenbezug.
|
||||
|
||||
**Format/Zustellung:** ZIP (JSON + zugehörige Dateien aus MinIO), erzeugt vom **Worker-Job**, Zustellung über **zeitlich begrenzten signierten Link** (nicht per Mail). Export wird **auditiert**.
|
||||
|
||||
## 6. DSGVO-Löschung (Art. 17 „Recht auf Vergessenwerden")
|
||||
**Zwei Scopes:**
|
||||
1. **Mandanten-Löschung / Offboarding** — alle `tenant_id='A'`-Zeilen (child→parent, eine Transaktion) + MinIO-Prefix. Danach **globale Aufräumung**: eine `Identity` **ohne verbleibende Mitgliedschaft** wird gelöscht/anonymisiert.
|
||||
2. **Einzelne Person (Betroffener)** — Kernspannung im ISMS: **Löschung vs. Nachweis-/Aufbewahrungspflicht**.
|
||||
|
||||
**Löschen vs. Anonymisieren (die zentrale Design-Regel):**
|
||||
- Datensätze, die aus **ISMS-/Nachweisgründen** oder wegen **rechtlicher Pflicht** (Art. 17 Abs. 3) erhalten bleiben müssen (v. a. **Audit-Trail**, Freigaben, Nachweise), werden **anonymisiert/pseudonymisiert** (Name/E-Mail → Tombstone, referenzielle Struktur bleibt), **nicht** hart gelöscht — sonst bricht die Nachvollziehbarkeit.
|
||||
- Wo keine Aufbewahrungspflicht greift: **Hard-Delete**.
|
||||
- Ergebnis: **Löschnachweis/„Deletion Certificate"** (wer/wann/Scope/was gelöscht vs. anonymisiert), auditiert.
|
||||
|
||||
**Personen über mehrere Mandanten (Auth-Umbau!):** Jeder Mandant ist ein **eigener Verantwortlicher**. Löschung erfolgt **pro Mandant-Scope** (Mitgliedschaft + PII in dessen Datensätzen) — **nicht** global über alle Mandanten. Erst wenn **keine** Mitgliedschaft der Person mehr existiert, wird die **globale `Identity`** entfernt/anonymisiert.
|
||||
|
||||
**Backups vs. Löschung (bekannte Spannung):** Unveränderliche Backups lassen sich nicht punktuell „aufbohren". Standard: Löschung wirkt auf **Live-Daten** + wird über eine **Tombstone-/Löschliste beim Restore erneut angewandt** (ein alter Snapshot bringt gelöschte PII nicht zurück); Backups laufen über **Retention** aus. Diese Regel muss dokumentiert und im Restore-Job erzwungen werden.
|
||||
|
||||
## 7. Gemeinsame Engine (der Architektur-Gewinn)
|
||||
Backup-Export, DSGVO-Export, Offboarding und Löschung teilen **eine** tenant-scoped Traversierung über `TENANT_MODELS` + FK-Topologie:
|
||||
- Export = SELECT je Tabelle, `tenant_id`- oder personen-gefiltert.
|
||||
- Restore = DELETE+INSERT, `tenant_id`-gescopt.
|
||||
- Löschung = DELETE (child→parent) bzw. UPDATE-Anonymisierung, `tenant_id`- oder personen-gescopt.
|
||||
Ein Baustein, vier Anwendungsfälle → geringe Redundanz, konsistentes Verhalten, ein Testfokus (Isolation).
|
||||
|
||||
## 8. Schnittstelle zum Auth-Umbau (Identity)
|
||||
- **Export einer Person** vereint globale `Identity` (Existenz/E-Mail/MFA-Status, **keine** Secrets) + alle Mitgliedschaften + zugewiesene/erstellte Objekte.
|
||||
- **Restore eines Mandanten** holt **Mitgliedschaften** (`User`) zurück, **nicht** den globalen Credential-Store (der liegt in Schicht A). Fehlt beim Reinsert die referenzierte `Identity` → sauber behandeln (neu verknüpfen/Einladung).
|
||||
- **Löschung** ist controller-scoped (pro Mandant); globale `Identity` erst bei 0 Mitgliedschaften.
|
||||
⇒ Diese Punkte **jetzt** mitdesignen, **umsetzen nach** WS0 (Identity-Fundament).
|
||||
|
||||
## 9. Verschlüsselung & Schlüssel (Entscheidung)
|
||||
**Entscheidung:** **Client-seitige AES-256-Verschlüsselung mit einem Schlüssel pro Umgebung** — **nicht** allein auf Storage-SSE verlassen. Grund: das Artefakt ist verschlüsselt, **bevor** es S3/MinIO erreicht → der Speicher-Betreiber sieht nie Klartext (at-rest **und** in-transit **und** zero-knowledge vom Speicher). Beide Backup-Tools können das nativ (keine Zusatzkomponente). Dies ist das **gemeinsame Primitiv**, auf dem die Backup-Lane und die Härtungs-Lane bauen.
|
||||
|
||||
**Stack (durchgängig AES-256, konsistent zur bestehenden TOTP-Verschlüsselung AES-256-GCM):**
|
||||
| Schutzobjekt | Mechanismus |
|
||||
|---|---|
|
||||
| Host at-rest (`pgdata`, MinIO) | **LUKS / provider-verschlüsseltes Volume** (deckt physischen Plattendiebstahl/Decommission; transparent im Betrieb) |
|
||||
| Cluster-Backup (Schicht A) | **pgBackRest** mit nativer **AES-256-Repo-Verschlüsselung** (`repo-cipher-type=aes-256-cbc` + `repo-cipher-pass`) → S3/MinIO |
|
||||
| Per-Tenant-Export + DSGVO-Pakete (Schicht B) | **`age`** je Artefakt (X25519, encrypt-then-upload) |
|
||||
| MinIO-Dateien | **restic** (eingebaute Verschlüsselung) oder MinIO-SSE als Defense-in-Depth |
|
||||
|
||||
**Warum nicht SSE-only:** SSE (AWS SSE-KMS / MinIO KES+KMS) ist transparent, aber der Speicher-Betreiber hält die Schlüssel, und self-hosted MinIO-SSE bräuchte KES+KMS als Extra-Komponente. SSE gern **zusätzlich**, nicht als alleinige Zusicherung.
|
||||
|
||||
**Schlüsselverwaltung:**
|
||||
- **Jetzt (self-hosted VPS):** **ein** AES-256-Schlüssel (pgBackRest) + **ein** `age`-Keypair **pro Umgebung** (test/dev/prod getrennt), als **Coolify-Env-Secret** + **Offline-Kopie im Org-Passwortmanager** (versiegelt).
|
||||
- **Register „restore-kritische Secrets":** führt zusammen — **Backup-Keys**, **Pepper**, **`MFA_ENC_KEY`**, `AUTH_SECRET`. Regeln: **niemals** im selben Bucket wie die verschlüsselten Artefakte; **Verlust des Keys = Verlust der Wiederherstellbarkeit**.
|
||||
- ⚠ **Umgebungs-Secret-Kohärenz beim Restore:** Pepper und `MFA_ENC_KEY` stehen **nicht** im per-Mandant-Artefakt. Ein Restore in eine Umgebung mit **anderem** Pepper/`MFA_ENC_KEY` bricht **alle** Passwort-/MFA-Prüfungen. Restore daher nur in eine Umgebung mit **passenden** Secrets (oder Passwort-/MFA-Reset einplanen).
|
||||
- **Später (Phase 2):** Upgrade-Pfad auf **HashiCorp Vault** oder Provider-KMS (Rotation/Audit/Trennung) — bewusst offen, nicht jetzt bauen.
|
||||
|
||||
**Aufgabenteilung der Lanes:** die **Backup-Lane** ruft die Verschlüsselung auf (pgBackRest-Repo-Key bzw. `age`-Recipient); die **Härtungs-Lane** stellt Host-Encryption (LUKS) bereit und verwaltet/rotiert die Keys + das Secrets-Register.
|
||||
|
||||
**Aufbewahrung & Test:**
|
||||
- **Retention** je Schicht dokumentieren (DR-WAL/Base, Per-Tenant-Snapshots, DSGVO-Exporte) — dem DSB vorzulegen.
|
||||
- **Restore-Test** regelmäßig + dokumentiert (der Prod-Runbook fordert das bereits für `pgdata`).
|
||||
|
||||
## 10. Governance-/Sicherheitskontrollen (Zusammenfassung)
|
||||
| Operation | Wer | Zusatzschutz |
|
||||
|---|---|---|
|
||||
| Cluster-PITR | Betreiber/Ops | Offsite-Zugriff, 4-Augen empfohlen |
|
||||
| Tenant-Restore | Plattform-Full-Admin | **MFA-Step-up**, getippte Bestätigung, Mandant-Sperre, Pre-Restore-Snapshot, Audit |
|
||||
| DSGVO-Export | Mandanten-Admin **oder** Betreiber | signierter Link, Audit |
|
||||
| Löschung Person | Mandanten-Admin (Verantwortlicher) | Anonymisierungs-Regeln, Löschnachweis, Audit |
|
||||
| Mandanten-Löschung | Plattform-Full-Admin | **MFA-Step-up**, getippte Bestätigung, Löschnachweis, MinIO + globale Identity-Aufräumung |
|
||||
|
||||
## 11. Phasen & offene Entscheidungen
|
||||
**Phasen:**
|
||||
1. Schicht A (pgBackRest/wal-g + PITR + verschlüsselt) — unabhängig, **sofort** möglich.
|
||||
2. Traversierungs-Engine über `TENANT_MODELS` (Export/Restore-Kern) — **nach WS0**.
|
||||
3. Betreiber-Portal-Restore (Worker-Job + Kontrollen).
|
||||
4. DSGVO-Export (per-Mandant + per-Person).
|
||||
5. DSGVO-Löschung (Anonymisierung vs. Hard-Delete + Löschnachweis + Tombstone-on-Restore).
|
||||
|
||||
**Offene Entscheidungen (für PM/DSB):**
|
||||
- Retention-Fristen je Schicht (DSB-Vorgabe).
|
||||
- Welche Tabellen/Felder bei Personen-Löschung **anonymisiert** (Nachweispflicht) vs. **hart gelöscht** werden — eine explizite **Feld-Klassifikation** ist nötig.
|
||||
- Aufbewahrung/Weg der DSGVO-Export-Pakete (Ablauf des signierten Links).
|
||||
- Ob per-Mandant-Snapshots als DSGVO-Portabilitätsformat genügen oder ein zusätzliches „menschenlesbares" Format nötig ist.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Konzept — Konfigurierbarer Backup-Zielspeicher (Backend + Lokal) (certvia)
|
||||
|
||||
> Status: **Konzept/Entscheidungsvorlage** (kein Code). Produkt: **certvia**. Folge-Feature der Backup-Lane. Ziel: den Zielspeicher für Backup-/DSGVO-Artefakte **im Betreiber-Portal konfigurierbar** machen und **lokale (persistente) Speicherung** als vollwertige Option anbieten — nicht nur über Env.
|
||||
|
||||
## 1. Ist-Zustand (`src/server/storage/backup-store.ts`)
|
||||
- Es gibt bereits eine **`BackupStore`-Abstraktion** (`put/get/list/remove`) mit zwei echten Implementierungen: **`S3BackupStore`** (MinIO/S3) und **`LocalBackupStore`** (echte Byte-Persistenz).
|
||||
- **Aber:** Die Wahl trifft `createBackupStore()` **einmalig beim Prozessstart, rein Env-basiert**: alle `S3_*` gesetzt → S3, sonst lokaler Ordner (`BACKUP_LOCAL_DIR` bzw. `<cwd>/.backups`). Exportiert als **statisches Singleton** `backupStore`.
|
||||
- **Nur 3 Nutzer:** `src/server/backup/export.ts`, `restore.ts`, `ops.ts`.
|
||||
- **Schwächen:** (a) nicht im Backend wählbar; (b) der lokale Ordner liegt im Container → beim Redeploy **flüchtig**; (c) S3-Config nur als Env, nicht pro Betreiber pflegbar.
|
||||
|
||||
## 2. Zielbild
|
||||
- **Betreiber wählt im Portal** das Ziel: **Lokal** oder **S3/MinIO**, inkl. Config, mit „Verbindung testen".
|
||||
- **Lokal ist persistent** (gemountetes Volume), nicht flüchtig.
|
||||
- Env bleibt als **Fallback** funktionsfähig (Rückwärtskompatibilität).
|
||||
|
||||
## 3. Datenmodell (`PlatformSetting`, Singleton erweitern)
|
||||
Aktuell nur `mfaRequired`. Ergänzen:
|
||||
- `backupTarget String @default("local")` — `local` | `s3`
|
||||
- `backupLocalDir String?` — Pfad des lokalen Ziels (muss auf ein **gemountetes** Volume zeigen)
|
||||
- `backupS3Endpoint / backupS3Bucket / backupS3Region / backupS3AccessKey String?`
|
||||
- `backupS3SecretKeyEnc String?` — S3-Secret **verschlüsselt at-rest** über `src/server/secret-crypto.ts` (`encryptSecret`/`decryptSecret`, Schlüssel `MFA_ENC_KEY`/`AUTH_SECRET`) — **nie** Klartext in der DB.
|
||||
|
||||
Migration additiv (nullable, Default `local`). Kein Backfill nötig.
|
||||
|
||||
## 4. Store-Factory umbauen
|
||||
- `backupStore`-Singleton → **`getBackupStore(): Promise<BackupStore>`**: liest `PlatformSetting`, baut den passenden Store, entschlüsselt den S3-Key.
|
||||
- **Präzedenz:** DB-Config (wenn `backupTarget` gesetzt/vollständig) → **sonst** Env (`S3_*` / `BACKUP_LOCAL_DIR`) → **sonst** lokaler Default `.backups`. So bleibt bestehendes Env-Deployment lauffähig.
|
||||
- **Caching + Invalidierung:** Store memoisieren, bei Änderung der Backup-Settings invalidieren (Version/Timestamp aus `PlatformSetting.updatedAt`).
|
||||
- Die **3 Call-Sites** (`export.ts`, `restore.ts`, `ops.ts`) von `backupStore` auf `await getBackupStore()` umstellen.
|
||||
- **Fail-secure:** unvollständige S3-Config → klarer Fehler (nicht still auf lokal fallen, wenn `backupTarget=s3` gewählt wurde).
|
||||
|
||||
## 5. Betreiber-UI
|
||||
- Neue Seite im Plattform-Portal, z. B. **`/admin/backup`** (oder Abschnitt in den Plattform-Einstellungen).
|
||||
- Gated: **`requirePlatformFullAdmin` + MFA-Step-up** (`assertPlatformStepUp`) — Betreiber-Config mit Credentials.
|
||||
- Felder: Ziel-Radio (Lokal/S3), je nach Wahl die Config; **„Verbindung testen"** (Probe-`put`+`get`+`remove` eines winzigen Test-Keys) mit klarer Rückmeldung; Speichern über eine Action analog `setPlatformMfaRequired` (`platformSetting.upsert`, S3-Secret vor dem Schreiben verschlüsseln).
|
||||
|
||||
## 6. Persistenz für „Lokal" (Compose)
|
||||
- In `docker-compose.coolify.yml` ein **persistentes Volume** ergänzen (analog `pgdata`/`miniodata`): `backups:` und in **app + worker** unter dem Pfad aus `backupLocalDir` mounten (z. B. `/app/.backups`). Ohne Mount bleibt Lokal flüchtig.
|
||||
- Doku-Hinweis: `backupLocalDir` muss innerhalb des gemounteten Pfads liegen.
|
||||
|
||||
## 7. Sicherheit
|
||||
- S3-Secret **nur verschlüsselt** in der DB (`secret-crypto`).
|
||||
- Config-Bearbeitung nur **Full-Admin + Step-up**, auditiert.
|
||||
- **`BACKUP_ENC_KEY`** (Artefakt-Verschlüsselung, `src/server/backup/crypto.ts`) bleibt **getrennt** vom Zielspeicher — Verschlüsselung des Inhalts ≠ Wahl des Speicherorts.
|
||||
- Umgebungs-Secret-Kohärenz (Restore) unverändert: `BACKUP_ENC_KEY`/`PASSWORD_PEPPER`/`MFA_ENC_KEY` sind Env, nicht Artefakt (siehe `KONZEPT-backup-restore.md` §9).
|
||||
|
||||
## 8. Tests
|
||||
- `scripts/test-backup-*` erweitern: Store-Auflösung aus DB-Config (local & s3), Präzedenz DB→Env→Default, „Verbindung testen"-Pfad, Fail-secure bei unvollständiger S3-Config.
|
||||
- Export→Restore end-to-end gegen **beide** Backends.
|
||||
|
||||
## 9. Sofort testbar (ohne Umbau)
|
||||
Schon heute: ohne `S3_*` fällt der Store auf **lokal** zurück → Export/Restore/DSGVO laufen (Artefakte im Container-`.backups`, **flüchtig**). Für einen schnellen Funktionstest genügt: **backup-worker + Redis** (vorhanden) + `BACKUP_ENC_KEY` (Fallback `AUTH_SECRET`). Der Umbau macht das Ziel **wählbar** und **persistent**.
|
||||
|
||||
## 10. Offene Entscheidungen
|
||||
- Eigene Seite `/admin/backup` vs. Abschnitt in bestehenden Plattform-Einstellungen.
|
||||
- Mehrere Ziele/Profile (Primär + Offsite) — jetzt 1 Ziel, Mehrfachziele als Phase 2.
|
||||
- Ob der lokale Pfad frei wählbar ist oder auf den gemounteten Volume-Pfad festgelegt wird (empfohlen: fest, um Fehlkonfiguration zu vermeiden).
|
||||
@@ -0,0 +1,162 @@
|
||||
# KONZEPT: Mehr-Framework-Fähigkeit — ISO 27001 neben TISAX (pro Mandant wählbar)
|
||||
|
||||
**Stand:** 2026-08-21 · **Zielgruppe:** mehrköpfiges Entwicklerteam + PM · **Status:** Entwurf zur Abnahme
|
||||
|
||||
> **Nachtrag 2026-08-21 — D4 und Lane 2 sind entschieden und umgesetzt:** Nicht zwei Seed-Pakete,
|
||||
> sondern **ein Dokumentensatz mit zwei Framework-Mappings** (Variante A). Umsetzung und Begründung:
|
||||
> `docs/FRAMEWORK-MAPPING-ISO27001.md`. Die übrigen Lanes bleiben unverändert gültig.
|
||||
|
||||
> **Ziel:** Kunden sollen pro Mandant **ISO 27001 und/oder TISAX** wählen können. Je Framework gibt es u. a. ein eigenes Vorlagenpaket, einen eigenen Control-Katalog und eine eigene Audit-/Readiness-Logik. Heute ist das Tool durchgängig **implizit auf VDA-ISA 2027 / TISAX** verdrahtet.
|
||||
|
||||
---
|
||||
|
||||
## 1. Ausgangslage (Ist-Analyse, belegt)
|
||||
|
||||
Das Fachmodell kennt **kein** „Framework/Standard" pro Mandant. Alles ist implizit VDA-ISA/TISAX:
|
||||
- **Kein Framework-Feld:** `Tenant` (`prisma/schema.prisma:31`) hat nur `sector` + generisches `config Json`; `TenantSettings` (`:52`) hat als einzigen Standard-Anker `tisaxLevel` (`:70`, „AL2|AL3"). ISO 27001 erscheint nur als Marketing-Text (`src/lib/brand.ts:57`) und in einem Kommentar (`src/server/actions/tenant-users.ts:197`).
|
||||
- **Control-Katalog** liegt als **String-ID** vor (kein Enum): `ControlAssessment.control` (`:967`, z. B. „1.3.1"/„5.3.4-KI", Werte 0–3), `ControlImplementation.reqId` (`:988`), `ControlDescription` (`:1217`, „VDA-ISA-Spalte 4"). Titel/IDs kommen aus VDA-ISA (`src/lib/control-titles.ts:1`). `Domain`-Enum (`:1029`) enthält TISAX-only `PROTOTYPE`.
|
||||
- **Ein** Vorlagenpaket verdrahtet: Parser `prisma/import-policies.ts` (Codes L00/R../VA-, `:115`), globale Ablage `PolicyTemplateVersion` (`:1637`, **ohne** Framework-Dimension), Auflösung `prisma/template-store.ts` (`resolvePackageForTenant` wählt nur nach Locale die *eine* neueste PUBLISHED-Version, `:147`), Sync-Skript `scripts/sync-policy-templates.ts:20` (fest `seed/isms-vorlagenpaket-v2` de/en, `meta.standard:"VDA ISA 2027"`, `version:"2.1"`).
|
||||
- **Readiness/Reifegrad** ist TISAX: Reifegrad **0–3** (`src/lib/maturity.ts:11`), Zielgrad aus AL2/AL3 + Schutzbedarf (`src/server/assessment-level.ts`), Anforderungsschema MUSS/SOLL/HOCH/SEHR-HOCH + Prüfziele IS/Prototyp(8.)/Datenschutz(9.) (`src/lib/scope-filter.ts`, `src/lib/export/vda-isa.ts:9`). Die reinen Rechen-Engines `src/lib/readiness.ts` und `src/lib/gap-consolidation.ts` sind numerisch **standard-agnostisch**.
|
||||
- **SoA** existiert als Modul-Key `soa` (`src/lib/modules.ts:19`), ist faktisch aber ein **VDA-ISA-Reifegrad-Assessment** (`src/server/actions/soa.ts`, Werte 0–3), **nicht** die ISO-typische Applicability-Erklärung (anwendbar/ausgeschlossen + Begründung je Annex-A-Control).
|
||||
- **Provisionierung**: `provisionTenant` (`src/server/provision.ts:53`) ist die zentrale Stelle — schreibt `tisaxLevel`, aktiviert alle Module, importiert das *eine* Paket, setzt TISAX-Schutzbedarf-Flags. `ProvisionOpts` kennt kein `framework`.
|
||||
|
||||
**Bereits standard-agnostisch (wiederverwendbar):** Multi-Tenancy/RLS, Modul-Toggle (`TenantModule`), Vorlagen-**Mechanik** (Parser-Struktur, nicht-destruktiver `reconcilePackage`, DB-Versionsablage, Locale-Fallback), Control-Speicherung als String-ID, Onboarding-Registry/Progress, die Rechen-Engines readiness/gap.
|
||||
|
||||
**Hart an TISAX gekoppelt (abstrahieren/duplizieren):** AL2/AL3-Schutzbedarf + Flags, Reifegrad 0–3 + C5-Belegtabelle, MUSS/SOLL-Schema + Prüfziele 8./9., der eine Vorlagenpaket-Pfad + single-published-Auflösung, VDA-ISA-Exporte/Labels, Control-Titel, `Domain.PROTOTYPE`, die SoA-Semantik, zahlreiche i18n-Labels „TISAX"/„VDA-ISA".
|
||||
|
||||
---
|
||||
|
||||
## 2. Zielbild
|
||||
|
||||
Ein **Framework als First-Class-Dimension**: Mandant wählt ein oder mehrere Frameworks (`ISO_27001`, `TISAX`). Je Framework werden Vorlagenpaket, Control-Katalog, Scope-/Assessment-Modell, Readiness/SoA-Sicht und Export **framework-spezifisch** aufgelöst — über eine **Strategie-Schicht**, damit die generische Mechanik (Tenancy, Vorlagen-Import, Wizard-Shell, Rechen-Engines) unverändert bleibt.
|
||||
|
||||
Leitprinzipien:
|
||||
- **Additiv / Expand-Contract**: bestehende (Test-)Mandanten laufen unverändert als TISAX weiter; neue Spalten/Tabellen additiv, keine Datenmigration von Inhalten (nur Testdaten).
|
||||
- **TISAX-Verhalten bleibt bit-genau erhalten** (Regressionsschutz) — ISO wird *daneben* gebaut, nicht *statt*.
|
||||
- **Ein Mandant kann beide Frameworks führen** (n:m) — geteilte Belege/Policies, aber getrennte Katalog-/SoA-Sichten.
|
||||
- **Feature-Flag**: ISO bleibt hinter einem Schalter, bis Katalog + Readiness + SoA abgenommen sind.
|
||||
|
||||
---
|
||||
|
||||
## 3. Entscheidungen (D) — vom Team/PO zu bestätigen
|
||||
|
||||
| # | Entscheidung | Empfehlung | Begründung |
|
||||
|---|--------------|-----------|------------|
|
||||
| **D1** | Framework-Kardinalität | **n:m** (Mandant kann ISO **und** TISAX) via eigener Tabelle `TenantFramework` | Nutzeranforderung „oder/und"; erlaubt per-Framework-Attribute (z. B. TISAX-Level, ISO-Zertifizierungsziel). |
|
||||
| **D2** | `tisaxLevel` | bleibt vorerst auf `TenantSettings`, wird als **TISAX-scoped** dokumentiert (nur relevant, wenn TISAX aktiv); optional später in `TenantFramework.config` verschieben | Minimiert Migration + die ~356 dbForTenant-Aufrufstellen; kein Umbau bestehender Reads. |
|
||||
| **D3** | Control-Speicherung | **String-ID beibehalten**, Framework als zusätzliche Dimension (kein Enum-Umbau) | `ControlAssessment.control` etc. nehmen ISO-Annex-A-IDs (A.5.1 …) ohne Schema-Bruch auf. |
|
||||
| **D4** | Vorlagenpaket | ~~zweites Seed-Paket~~ → **entschieden 2026-08-21: ein Dokumentensatz, zwei Mappings** (`mapping.json` + `mapping-iso.json` in `seed/isms-vorlagenpaket-v2`). `framework`-Dimension auf `PolicyTemplateVersion` bleibt nötig (+ Unique `(framework, version)`). | Gleiche Dokument-Codes können in einem Mandanten nicht zweimal existieren (`@@unique([tenantId, code])`); der Umsetzungstext ist ohnehin normunabhängig. Siehe `FRAMEWORK-MAPPING-ISO27001.md`. |
|
||||
| **D5** | Assessment-Modell | **Strategie-Interface** je Framework (Scope/Reifegrad/Ziel/SoA), TISAX = heutige 0–3/AL-Logik, ISO = SoA-Applicability + Umsetzungsstatus | ISO kennt kein AL2/AL3 und keine VDA-ISA-Reifegrade; saubere Trennung ohne TISAX-Regression. |
|
||||
| **D6** | ISO-SoA | echte **Statement of Applicability** (Annex-A-Liste, anwendbar/ausgeschlossen + Begründung, Verknüpfung Policy/Evidence) — neu für ISO; TISAX behält sein Reifegrad-Assessment | ISO-27001-Kernartefakt fehlt heute fachlich. |
|
||||
| **D7** | Rollout | **Feature-Flag** „ISO" + erst Test-Instanz; TISAX unverändert | Risikoarme Einführung; TISAX-Kunden unberührt. |
|
||||
| **D8** | Katalog-Grundlage ISO | **Annex A (ISO/IEC 27001:2022, 93 Controls, 4 Themen)** + Klauseln 4–10 als Managementsystem-Anforderungen | Aktueller Normstand; 2022er Struktur. |
|
||||
|
||||
---
|
||||
|
||||
## 4. Zielarchitektur
|
||||
|
||||
### 4.1 Datenmodell (additiv)
|
||||
- **`enum Framework { ISO_27001, TISAX }`**.
|
||||
- **`model TenantFramework`** (n:m): `tenantId`, `framework`, `isPrimary Boolean`, `config Json` (per-Framework-Attribute, z. B. `{ tisaxLevel: "AL3" }` bzw. `{ certScope, certBodyTarget }`), Unique `(tenantId, framework)`. → in `TENANT_MODELS` (RLS) aufnehmen.
|
||||
- **`PolicyTemplateVersion`**: neue Spalte `framework Framework`; Unique `(framework, version)` statt nur `version`; Default-Backfill `TISAX`.
|
||||
- **`PolicyPackageState`** (Mandanten-Merker, `schema:1612`): um `framework` erweitern (je Framework eine importierte Version).
|
||||
- **ISO-SoA** (neu): `model SoaEntry { tenantId, framework=ISO_27001, control (A.x.y), applicable Boolean, justification String, implementationStatus enum, linkedPolicyCode?, linkedEvidenceId? }` — RLS-scoped.
|
||||
- **`Domain`-Enum**: ISO-Themen ergänzen bzw. `PROTOTYPE` als TISAX-only markieren; ISO-Controls mappen auf die 4 Annex-A-Themen (Organizational/People/Physical/Technological) → entweder neue Enum-Werte oder eine framework-abhängige Domain-Auflösung.
|
||||
|
||||
### 4.2 Strategie-Schicht (Kernstück)
|
||||
Ein `FrameworkStrategy`-Interface kapselt alle TISAX-spezifischen Annahmen; je Framework eine Implementierung:
|
||||
```
|
||||
interface FrameworkStrategy {
|
||||
key: Framework
|
||||
resolvePackage(locale): PublishedPackage // template-store, framework-parametrisiert
|
||||
loadCatalog(): { controls, titles, scope } // c1/c5/mapping bzw. Annex-A/Klauseln
|
||||
scopeFilter(settings): ControlRow[] // TISAX: AL/Prüfziel · ISO: Applicability
|
||||
targetFor(control, settings): AssessmentTarget // TISAX: Reifegrad 0–3 · ISO: Umsetzungsstatus/SoA
|
||||
readinessView(rows): ReadinessSummary // nutzt generische readiness/gap-Engines
|
||||
export(): ExportArtifact // TISAX: VDA-ISA · ISO: SoA + Annex-A-Gap
|
||||
wizardSteps(): StepKey[] // framework-abhängige Sichtbarkeit/Inhalte
|
||||
}
|
||||
```
|
||||
Bestehende Dateien werden hinter diese Schnittstelle gezogen: `assessment-level.ts`, `maturity.ts`, `scope-filter.ts`, `control-titles.ts`, `export/vda-isa*.ts` → `TisaxStrategy`. Die generischen Engines `readiness.ts`/`gap-consolidation.ts` bleiben und werden von beiden Strategien gefüttert.
|
||||
|
||||
### 4.3 Auflösung zur Laufzeit
|
||||
- `template-store.ts`: `resolvePackageForTenant(tenant, framework, locale)` — wählt PUBLISHED-Version je `(framework, locale)`.
|
||||
- `provisionTenant`: `ProvisionOpts.frameworks: Framework[]` → schreibt `TenantFramework`-Zeilen, importiert **je Framework** das passende Paket + Katalog, setzt nur bei TISAX die AL-Flags.
|
||||
- UI/Server lösen die aktive Framework-Sicht über die Mandanten-`TenantFramework` + eine aktive Auswahl (bei Mehr-Framework: Umschalter, analog Mandantenwahl).
|
||||
|
||||
---
|
||||
|
||||
## 5. Workstreams / Lanes für das Team
|
||||
|
||||
Fünf Lanes + PM. Abhängigkeiten in Klammern.
|
||||
|
||||
### Lane 1 — Framework-Kern (Datenmodell, Provision, Auflösung) *(Fundament, zuerst)*
|
||||
- `Framework`-Enum, `TenantFramework`-Tabelle (+ RLS/`TENANT_MODELS`), `PolicyTemplateVersion.framework` (+ Unique), `PolicyPackageState.framework` — additive Expand-Migrationen + Backfill bestehender Daten auf `TISAX`.
|
||||
- `ProvisionOpts.frameworks` + framework-abhängige Paket-/Katalog-Auflösung in `provision.ts`.
|
||||
- `template-store.ts` framework-parametrisieren.
|
||||
- **DoD:** bestehende Mandanten laufen unverändert (framework=TISAX), neuer Mandant kann mit `frameworks:[ISO_27001]` **oder** `[TISAX]` **oder** beiden provisioniert werden; Gate grün.
|
||||
|
||||
### Lane 2 — ISO-Mapping & -Katalog *(inhaltlicher Teil erledigt; Rest braucht L1)*
|
||||
- ✅ **erledigt (2026-08-21):** `mapping-iso.json` (27 Klauseln + 93 Annex-A-Controls) auf der bestehenden
|
||||
Bibliothek; 19 ISO-only-Abschnitte ergänzt; Sichtbarkeit über `FLAG_FW_ISO27001`/`FLAG_FW_TISAX`;
|
||||
SoA-Gerüst mit den Pflichtangaben aus 6.1.3 d); `_verify_iso.py` grün.
|
||||
- ⬜ ISO-`control-titles`, ISO-Scope-/Control-Kataloge (Pendants zu `c1-scope.json`/`c5-controls.json`).
|
||||
- ⬜ `parsePackageFiles`/`sync-policy-templates.ts` über **Frameworks × Sprachen** iterieren — heute ist
|
||||
`mapping.json` fest verdrahtet, `mapping-iso.json` wird noch nicht gelesen.
|
||||
- ✅ **erledigt:** Englische Fassung `isms-vorlagenpaket-v2-en` nachgezogen (eigene Texte, `--lang en`).
|
||||
- **DoD:** ISO-Mapping importiert als eigene `PolicyTemplateVersion(framework=ISO_27001)`; ein ISO-Mandant
|
||||
erhält Annex-A-Controls und sieht die ISO-Anforderungssicht.
|
||||
|
||||
### Lane 3 — Assessment-/Readiness-Abstraktion *(braucht L1; parallel zu L2)*
|
||||
- `FrameworkStrategy`-Interface; heutige TISAX-Logik als `TisaxStrategy` extrahieren (verhaltensgleich!).
|
||||
- `IsoStrategy`: Scope = Applicability; Ziel = Umsetzungsstatus (statt Reifegrad 0–3); Readiness/Gap über die bestehenden generischen Engines.
|
||||
- `readiness.ts`/`gap-consolidation.ts` framework-parametrisiert füttern; keine TISAX-Regression.
|
||||
- **DoD:** TISAX-Readiness identisch zu heute (Snapshot-Test); ISO liefert eine erste Readiness-/Gap-Sicht auf Annex-A-Basis.
|
||||
|
||||
### Lane 4 — ISO-SoA + Exporte *(braucht L2+L3)*
|
||||
- Echte **SoA-Sicht** (`SoaEntry`): Annex-A-Liste, anwendbar/ausgeschlossen + Begründung, Verknüpfung Policy/Evidence, Umsetzungsstatus; Modul-Key `soa` beherbergt beide Sichten (TISAX-Reifegrad bleibt).
|
||||
- ISO-Export: SoA-Dokument + Annex-A-Gap-Report; VDA-ISA-Export bleibt TISAX-only.
|
||||
- **DoD:** ISO-Mandant kann eine vollständige SoA pflegen und exportieren.
|
||||
|
||||
### Lane 5 — Wizard, Settings/Admin & i18n *(braucht L1; UI-Feinschliff am Ende)*
|
||||
- Framework-Auswahl in Admin (Mandant anlegen) + `/settings`; `setTenantTisaxLevel` → TISAX-scoped, ISO-Zertifizierungsziel analog.
|
||||
- Onboarding-Registry framework-aware (`getVisibleSteps` guard je Framework): TISAX behält Scope/AL/Prüfziel + Controls-Reifegrad; ISO ersetzt AL-Schritt durch Applicability/SoA-Schritt.
|
||||
- i18n: framework-neutrale Labels + per-Framework-Overrides; „TISAX/VDA-ISA"-Strings entkoppeln (`messages/de.json`/`en.json`, `settings/page.tsx`, `audit-readiness/*`, `admin/page.tsx`).
|
||||
- **DoD:** Kunde wählt im Admin ISO und/oder TISAX; der Wizard zeigt die passenden Schritte; keine „TISAX"-Labels bei reinen ISO-Mandanten.
|
||||
|
||||
**PM:** Reihenfolge L1 → (L2 ∥ L3) → L4 → L5; Abnahme je Lane; Regressions-Gate für TISAX (Snapshot der heutigen Readiness/Exporte) als Pflicht vor jedem Merge.
|
||||
|
||||
---
|
||||
|
||||
## 6. Migration & Rollout
|
||||
- **Expand:** additive Migrationen (Enum, `TenantFramework`, Spalten); Backfill: für jeden bestehenden Mandanten `TenantFramework(framework=TISAX, isPrimary=true)`; `PolicyTemplateVersion.framework=TISAX`.
|
||||
- **Feature-Flag** „ISO 27001" (Plattform-Setting) gated Admin-Auswahl + Provisionierung, bis L2–L4 abgenommen.
|
||||
- **Keine Inhaltsmigration** (nur Testdaten); neue ISO-Mandanten frisch provisioniert.
|
||||
- **Contract (später):** ungenutzte TISAX-only-Felder erst nach stabilem Mehr-Framework-Betrieb aufräumen (z. B. `tisaxLevel` → `TenantFramework.config`).
|
||||
|
||||
## 7. Risiken & Gegenmaßnahmen
|
||||
| Risiko | Gegenmaßnahme |
|
||||
|--------|---------------|
|
||||
| TISAX-Regression durch Refactoring | `TisaxStrategy` verhaltensgleich extrahieren; Snapshot-Tests der heutigen Readiness/Exporte als Merge-Gate. |
|
||||
| ISO-Katalog-Qualität (Annex-A ↔ Policies) | Fachliches Mapping-Review (ISMS-Experte) vor L4; `mapping.json` als Single Source. |
|
||||
| SoA-Semantik ist fachlich neu | Eigene Lane (L4) mit klarer Definition applicable/exclusion + Begründungspflicht. |
|
||||
| Mehr-Framework-Komplexität in UI | Aktive-Framework-Umschalter analog Mandantenwahl; getrennte Katalog-Sichten. |
|
||||
| `Domain.PROTOTYPE`/AL nur TISAX | Framework-abhängige Domain-/Scope-Auflösung; ISO ignoriert AL/Prototyp. |
|
||||
| i18n-Wildwuchs „TISAX" | Zentrale framework-neutrale Keys + Overrides; Lint auf verbleibende Hardcodes. |
|
||||
|
||||
## 8. Grobe Aufwandsschätzung
|
||||
| Lane | Aufwand (PT, grob) |
|
||||
|------|--------------------|
|
||||
| L1 Framework-Kern | 4–6 |
|
||||
| L2 ISO-Paket & Katalog (inkl. fachliches Mapping) | 8–12 |
|
||||
| L3 Assessment-Abstraktion | 5–8 |
|
||||
| L4 ISO-SoA + Exporte | 5–8 |
|
||||
| L5 Wizard/Settings/i18n | 4–6 |
|
||||
| PM/Fachreview | durchgehend |
|
||||
| **Summe** | **~26–40 PT**, L2/L3 parallelisierbar |
|
||||
|
||||
## 9. Offene Punkte (vom PO/Fachexperten zu klären)
|
||||
- Umfang ISO-Vorlagenpaket: nur Annex-A-Controls oder auch Managementsystem-Klauseln 4–10 als geführte Artefakte? (Empfehlung: beides.)
|
||||
- ~~Wie stark sollen ISO- und TISAX-Sicht bei Doppel-Framework **Belege/Policies teilen**?~~ → **entschieden:** ein gemeinsames Policy-Set, zwei Mappings (Variante A, 2026-08-21).
|
||||
- ISO-Reifegrad optional zusätzlich zur Applicability (manche Kunden wollen Reifegrade auch unter ISO)?
|
||||
- Zielformat ISO-Exporte (SoA-Dokument als Word/PDF/XLSX; Annex-A-Gap als XLSX).
|
||||
@@ -0,0 +1,217 @@
|
||||
# KONZEPT: Objektspeicher-Migration MinIO → Garage
|
||||
|
||||
**Stand:** 2026-08-20 · **Zielgruppe:** mehrköpfiges Entwicklerteam + PM · **Status:** Entwurf zur Abnahme
|
||||
|
||||
> **Randbedingung (2026-08-20):** Es existieren **nur Test-Instanzen** — **keine produktiven Daten**. Daher **keine Datenmigration** (kein rclone-Sync), sondern ein **kompletter Neu-Deploy** mit frischer Garage. Das eliminiert die frühere Migrations-Lane und das Wartungsfenster; Cutover = MinIO-Service durch Garage ersetzen, provisionieren, neu deployen (optional DB-Reset wie gehabt).
|
||||
|
||||
---
|
||||
|
||||
## 1. Ausgangslage & Motivation
|
||||
|
||||
certvia nutzt aktuell **MinIO** als S3-kompatiblen Objektspeicher (Dokument-Uploads + Backup-Artefakte). Anlass für die Prüfung: der Hinweis, MinIO werde „nicht mehr weiterentwickelt".
|
||||
|
||||
**Faktenlage (verifiziert 2026-08-20):**
|
||||
|
||||
- **Mai 2025** — MinIO entfernt die Admin-Konsole/Verwaltungs-GUI aus der Community Edition (nur noch rudimentärer Object-Browser; Bucket-/User-/Policy-Verwaltung nur noch im kommerziellen AIStor).
|
||||
- **Okt 2025** — MinIO publiziert keine Container-Images mehr auf Docker Hub/Quay (auch nicht für einen kritischen CVE-Fix).
|
||||
- **Dez 2025** — Community-Repo im **Maintenance-Mode**: keine neuen Features, keine PRs, Security-Fixes nur „case-by-case"; Repo als **„no longer maintained"** markiert. Fokus liegt auf **AIStor** (Abo-Produkt). Der Code bleibt AGPLv3 verfügbar.
|
||||
|
||||
**Bewertung:** MinIO ist nicht „von heute auf morgen tot", aber die **Community Edition ist faktisch im End-of-Life-/Wartungsmodus**. Für ein selbstgehostetes ISMS-/Compliance-Produkt (das genau Betriebs-, Wartungs- und Supply-Chain-Sicherheit demonstrieren soll) ist der proaktive Wechsel auf einen aktiv gepflegten Store gerechtfertigt und gut begründbar (u. a. relevant für die eigene Lieferanten-/Komponentenbewertung).
|
||||
|
||||
**Warum Garage:** aktiv entwickelt (Deuxfleurs, AGPLv3, Rust), bewusst **minimalistisch & leichtgewichtig**, S3-kompatibel, für Selbsthosting/kleine bis mittlere Deployments und geo-verteilte Replikation ausgelegt. Passt zum internen Coolify-Testserver **und** zum Contabo-Prod-VPS.
|
||||
|
||||
---
|
||||
|
||||
## 2. Zielbild
|
||||
|
||||
Ein **API-kompatibler Austausch** des Storage-Backends: Der Anwendungscode spricht weiterhin S3 (AWS SDK v3, `forcePathStyle`), lediglich der Container-Dienst, die Provisionierung von Bucket/Key und die Daten werden migriert. **Keine Änderung an Fachlogik, UI oder Datenmodell.**
|
||||
|
||||
Was gleich bleibt:
|
||||
- S3-Protokoll, AWS SDK v3, `forcePathStyle: true`, die Env-Kontrakte `S3_ENDPOINT / S3_ACCESS_KEY / S3_SECRET_KEY / S3_BUCKET / S3_REGION`.
|
||||
- Die Storage-Abstraktionen `src/server/storage/adapter.ts` (Uploads) und `src/server/storage/backup-store.ts` (Backups) inkl. Local-/Stub-Fallback.
|
||||
- Key-Schema (`<tenantId>/uploads/<uuid>-<name>`), Mandanten-Isolation über Key-Präfix.
|
||||
|
||||
---
|
||||
|
||||
## 3. Ist-Analyse certvia (Code-Stand dev)
|
||||
|
||||
Zwei S3-Konsumenten, beide identischer S3-Dialekt:
|
||||
|
||||
| Konsument | Datei | Zweck | Ops |
|
||||
|-----------|-------|-------|-----|
|
||||
| Upload-Storage | `src/server/storage/adapter.ts` | hochgeladene Richtlinien + Audit-Nachweise | Put/Get, HeadBucket→CreateBucket |
|
||||
| Backup-Store | `src/server/storage/backup-store.ts` | verschlüsselte Backup-Artefakte (`.cvb`), DSGVO-ZIP | Put/Get/List/Delete, HeadBucket→CreateBucket |
|
||||
|
||||
Gemeinsam:
|
||||
- `new S3Client({ endpoint, region, forcePathStyle: true, credentials })` — **path-style**, exakt was Garage erwartet.
|
||||
- Verwendete S3-Operationen: `PutObject`, `GetObject`, `HeadBucket`, `CreateBucket`, `ListObjectsV2`, `DeleteObjects`. **Alle außer `CreateBucket` sind Garage-Standard.**
|
||||
- Region-Default `us-east-1`.
|
||||
- Backend-Auswahl rein über Env → sauberer Graceful-Fallback (Stub/Local), kein Hardcoding auf MinIO.
|
||||
|
||||
**Zu provisionierende Buckets (Neu-Deploy, keine Altbestände zu übernehmen):**
|
||||
- `S3_BUCKET` = `isms-documents` (Uploads).
|
||||
- Backup-Bucket: nur falls der Backup-Store auf S3 statt lokal (`BACKUP_LOCAL_DIR`) betrieben wird — dann eigenen Bucket provisionieren.
|
||||
|
||||
### Der einzige echte Reibungspunkt: Bucket-/Key-Anlage
|
||||
|
||||
Garage verwaltet **Buckets und Access-Keys sowie deren Rechte** über die **Garage-Admin-API / `garage`-CLI**, **nicht** über die S3-Operation `CreateBucket`. Konsequenz:
|
||||
- `HeadBucket`, `PutObject`, `GetObject`, `ListObjectsV2`, `DeleteObjects` → funktionieren gegen Garage unverändert.
|
||||
- `CreateBucket` (unsere Selbstheilung „Bucket fehlt → anlegen") → **wird von Garage über die S3-API nicht bedient**. Buckets/Keys müssen **vorab out-of-band** provisioniert werden.
|
||||
|
||||
> Hinweis: `backup-store.ts` **schluckt** einen `CreateBucket`-Fehler bereits (Bucket gilt als „vorhanden angenommen"), `adapter.ts` **wirft** dagegen bei nicht-„already exists"-Fehlern. Nach Vorab-Provisionierung greift ohnehin nur der `HeadBucket`-Erfolgspfad — trotzdem soll `ensureBucket()` explizit Garage-tauglich gemacht werden (siehe Lane C), damit wir uns nicht auf verschlucktes Fehlerverhalten verlassen.
|
||||
|
||||
---
|
||||
|
||||
## 4. Entscheidungen (D) — vom Team/PO zu bestätigen
|
||||
|
||||
| # | Entscheidung | Empfehlung | Begründung |
|
||||
|---|--------------|-----------|------------|
|
||||
| **D1** | Zielspeicher | **Garage, self-hosted — ENTSCHIEDEN 2026-08-20** | Aktiv gepflegt, S3-kompatibel, leichtgewichtig, DSGVO/Datenresidenz in eigener Hand. Alternativen (SeaweedFS, Ceph/RGW, extern R2/Hetzner) in §12 abgewogen. |
|
||||
| **D2** | Region-Handhabung | Garage-`s3_region` = **`us-east-1`** setzen | App-Env bleibt unverändert (Default `us-east-1`) → keine Code-/Config-Drift. |
|
||||
| **D3** | `ensureBucket()` | **Vorab-Provisionierung** + `ensureBucket` prüft nur (HeadBucket), kein S3-CreateBucket | Deterministisch; klare Fehlermeldung „Bucket nicht provisioniert" statt stiller Selbstheilung. |
|
||||
| **D4** | Cutover-Strategie | **Neu-Deploy, kein Wartungsfenster** (MinIO→Garage im Compose ersetzen, provisionieren, deployen; optional DB-Reset) | **Keine produktiven Daten** → keine rclone-Migration nötig. |
|
||||
| **D5** | Topologie | **Single-Node** Garage pro Environment | Passt zur aktuellen 1-Host-Topologie; Multi-Node/Replikation als spätere Ausbaustufe dokumentieren. |
|
||||
| **D6** | Deployment | Garage als **Compose-Service** in `docker-compose.coolify.yml` (ersetzt `minio`) | Gleiches Betriebsmodell wie bisher (Coolify/Traefik). |
|
||||
| **D7** | Reihenfolge | Aktuell nur **Test-Instanz(en)** — dort umsetzen; Prod später nach gleichem Muster | Es gibt derzeit keine Prod-Instanz; Runbook bleibt für spätere Prod gültig. |
|
||||
|
||||
Strategische Vorfrage (self-hosted vs. externer managed S3): **entschieden am 2026-08-20 zugunsten self-hosted Garage** — Datenresidenz + Betriebshoheit für ein DSGVO-/ISMS-Produkt. Externe Optionen (Hetzner OS/Cloudflare R2) bleiben nur als dokumentierte Alternative in §12.
|
||||
|
||||
---
|
||||
|
||||
## 5. Zielarchitektur
|
||||
|
||||
```
|
||||
┌───────────────────────── Coolify-Stack (pro Environment) ─────────────────────────┐
|
||||
app ──S3──► │ garage (Container) │
|
||||
worker ─S3► │ ├─ garage.toml (rpc_secret, s3_api.s3_region=us-east-1, api_bind_addr :3900, │
|
||||
backup- ─S3► │ │ admin_token, metadata_dir, data_dir) │
|
||||
worker │ ├─ Volume: garage_meta → /var/lib/garage/meta (KRITISCH: Metadaten/Layout) │
|
||||
│ └─ Volume: garage_data → /var/lib/garage/data (Objekt-Bytes) │
|
||||
│ garage-provision (Init-Job, restart:no): Layout + Bucket + Key + Rechte via CLI │
|
||||
└────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- **Endpoint:** `S3_ENDPOINT=http://garage:3900` (S3-API-Port; Standard 3900). Admin-API auf 3903 (nur intern).
|
||||
- **Zwei Ports beachten:** 3900 = S3, 3902 = Web (optional), 3903 = Admin. Nur S3 wird von der App genutzt; Admin bleibt clusterintern.
|
||||
- **Secrets (pro Environment via Coolify-Env, echte Werte NIE im Chat/Repo):** `GARAGE_RPC_SECRET` (32-byte hex), `GARAGE_ADMIN_TOKEN`, plus der erzeugte Access-Key/Secret, die als `S3_ACCESS_KEY/S3_SECRET_KEY` in die App gehen.
|
||||
- **Backup der Garage-Metadaten:** `garage_meta` enthält Bucket-/Key-/Layout-Definitionen — muss in die Host-Backup-Strategie (analog `pgdata`). Ohne Meta sind die Daten nicht adressierbar.
|
||||
|
||||
---
|
||||
|
||||
## 6. Workstreams / Lanes für das Team
|
||||
|
||||
Vier parallelisierbare Lanes + PM-Koordination (die frühere rclone-Migrations-Lane entfällt, da Neu-Deploy). Abhängigkeiten in Klammern.
|
||||
|
||||
### Lane A — Infra & Deployment (Owner: DevOps)
|
||||
- Garage-Service in `docker-compose.coolify.yml` ergänzen (Image pinnen, Ports, 2 Volumes, `security_opt`/`cap_drop` analog bestehender Services, Healthcheck auf Admin-API `/health`).
|
||||
- `garage.toml` als Config (über Env/Coolify-Mount): `rpc_secret`, `s3_region=us-east-1`, `metadata_dir`, `data_dir`, `admin_token`.
|
||||
- Single-Node-Layout initial (Node einer Zone mit Kapazität zuweisen — ohne Layout kein Schreibzugriff).
|
||||
- `minio`-Service erst **nach** abgenommenem Garage-Betrieb entfernen (bis dahin als Rollback-Sicherheitsnetz stehen lassen).
|
||||
- Garage-`meta`-Volume in Host-Backup aufnehmen.
|
||||
- **Liefergegenstand:** lauffähiger Garage-Container auf der Test-Instanz, Admin-API erreichbar, Layout „ready".
|
||||
|
||||
### Lane B — Provisioning-Automatisierung (Owner: DevOps/Backend) — *(braucht A)*
|
||||
- Init-Job `garage-provision` (restart:no, analog `migrate`): idempotent
|
||||
1. Layout anwenden (falls noch nicht),
|
||||
2. Bucket(s) anlegen (`isms-documents`, ggf. Backup-Bucket),
|
||||
3. Access-Key erzeugen **oder** vorhandenen importieren,
|
||||
4. Key→Bucket-Rechte (read/write/owner) setzen.
|
||||
- Umsetzung über `garage`-CLI **oder** Admin-API (HTTP) — Entscheidung dokumentieren; idempotent (mehrfach ausführbar ohne Fehler).
|
||||
- Ausgabe des Access-Key/Secret **nur** in Coolify-Secrets, nicht in Logs.
|
||||
- **Liefergegenstand:** ein Skript/Job, der aus „leerer Garage" reproduzierbar den betriebsbereiten Zustand herstellt (dokumentiert in `docs/DEPLOY-*`).
|
||||
|
||||
### Lane C — App-Code-Anpassung (Owner: Backend) — *(unabhängig, klein)*
|
||||
- `ensureBucket()` in **beiden** Stores Garage-tauglich: `HeadBucket` zur Verifikation; bei „missing" **kein** S3-`CreateBucket`, sondern klarer Konfigurationsfehler „Bucket nicht provisioniert — Provisioning-Job ausführen". (Provisionierung liegt bei Lane B.)
|
||||
- Optional: gemeinsame S3-Client-Factory extrahieren (DRY über `adapter.ts`/`backup-store.ts`) — nur wenn ohne Risiko.
|
||||
- Region/Endpoint-Doku in `.env.coolify.example` + `.env.example` aktualisieren (MinIO-Kommentare → Garage; `forcePathStyle`-Begründung bleibt gültig).
|
||||
- **Tests:** bestehende `scripts/test-backup-*.ts` + Upload/Download-Pfad gegen einen lokalen Garage-Container grün; neuer Smoke-Test „Bucket fehlt → sprechender Fehler".
|
||||
- **Liefergegenstand:** PR mit Code + aktualisierten Tests, `tsc/lint/build` grün.
|
||||
|
||||
### Lane D — Test, Cutover & Abnahme (Owner: QA/DevOps + PM) — *(integriert A–C)*
|
||||
- End-to-End-Durchstich auf der **Test-Instanz** (Neu-Deploy): Upload, Download, Backup-Export (`.cvb`), DSGVO-ZIP, Restore, Mandanten-Isolation.
|
||||
- **Cutover-Runbook** (siehe §7) an der Test-Instanz **einmal durchspielen** (MinIO raus, Garage rein, provisionieren, deployen, ggf. DB-Reset).
|
||||
- **Rollback-Runbook** (siehe §8).
|
||||
- Abnahmekriterien (§9) abhaken.
|
||||
- **Liefergegenstand:** abgenommene Test-Instanz auf Garage + freigegebenes Runbook (auch für spätere Prod).
|
||||
|
||||
**PM:** Reihenfolge/Abhängigkeiten (A→B, C parallel, D integriert), Abnahme je Lane, Freigabe des Runbooks für spätere Prod (D7).
|
||||
|
||||
---
|
||||
|
||||
## 7. Cutover-Runbook (Neu-Deploy, kein Wartungsfenster nötig)
|
||||
|
||||
1. Im Compose `minio`-Service durch `garage` + `garage-provision` (Init-Job) ersetzen; Volumes `garage_meta`/`garage_data` anlegen.
|
||||
2. Coolify-Env setzen: `S3_ENDPOINT=http://garage:3900`, `S3_REGION=us-east-1`, `GARAGE_RPC_SECRET`, `GARAGE_ADMIN_TOKEN` (literal, echte Werte NICHT aus dem Chat). `S3_ACCESS_KEY/S3_SECRET_KEY` = der beim Provisioning erzeugte Garage-Key.
|
||||
3. Deploy: Garage startet, Layout „ready", `garage-provision` legt Bucket(s) + Key + Rechte an.
|
||||
4. Optional **DB-Reset** (wie in bisherigen Deploys), falls alte Objekt-Referenzen im Datenbestand stören — bei frischer/geseedeter Test-Instanz meist unnötig.
|
||||
5. **Smoke-Tests** (§9) aktiv durchführen.
|
||||
6. `minio`-Service + Volumes entfernen; Garage-`meta`-Volume in Host-Backup bestätigen.
|
||||
|
||||
## 8. Rollback
|
||||
|
||||
- Da es **keine produktiven Daten** gibt, ist Rollback unkritisch: Compose zurück auf `minio` (oder frischer Re-Deploy). Optional den alten `minio`-Service während der ersten Testphase noch nicht löschen (Schritt 6 verzögern), bis Garage abgenommen ist.
|
||||
|
||||
---
|
||||
|
||||
## 9. Validierung / Abnahmekriterien
|
||||
|
||||
Gegen Garage müssen grün sein:
|
||||
- **Upload:** Richtlinie hochladen → Objekt in Garage, `<tenantId>/uploads/...`-Präfix korrekt.
|
||||
- **Download:** Datei abrufen (`/files/[...key]`), Content-Disposition/Filename-Metadatum stimmt.
|
||||
- **Backup-Export:** `.cvb`-Artefakt erzeugt (CVB1-Header), Persistenz + Download.
|
||||
- **DSGVO-ZIP:** erzeugt und lesbar.
|
||||
- **Restore:** Backup → Wiederherstellung, Datenintegrität, **Mandanten-Isolation** gewahrt.
|
||||
- **List/Delete:** Backup-Historie listet, Aufräumen entfernt Prefix.
|
||||
- **Fehlerfall:** fehlender Bucket → sprechender Konfigfehler (kein stiller CreateBucket-Versuch).
|
||||
- **Automatisiert:** `scripts/test-backup-*.ts` grün gegen Garage; `tsc/lint/build` grün.
|
||||
|
||||
---
|
||||
|
||||
## 10. Risiken & Gegenmaßnahmen
|
||||
|
||||
| Risiko | Gegenmaßnahme |
|
||||
|--------|---------------|
|
||||
| `CreateBucket` (S3) gegen Garage nicht verfügbar | Vorab-Provisionierung (Lane B) + `ensureBucket` nur prüfend (Lane C). |
|
||||
| Garage-`meta`-Volume nicht gesichert → Buckets/Keys „weg" | Meta-Volume in Host-Backup; im Runbook explizit verifiziert. |
|
||||
| Region-/Endpoint-Mismatch (Coolify-Env vs. `garage.toml`) | D2 fixiert `us-east-1` beidseitig; in Abnahme geprüft. |
|
||||
| Access-Key/Secret landet in Logs | Provisioning schreibt nur in Coolify-Secrets; Log-Redaction. |
|
||||
| Layout nicht angewendet → Schreibfehler „no capacity" | Provisioning-Job setzt Layout idempotent; Healthcheck. |
|
||||
| Coolify-Interpolations-/„managed"-Fallen (bekannt) | Neue Env (`GARAGE_*`) literal setzen, nicht über `${…}` referenzieren; im Container-Env verifizieren. |
|
||||
| Presigned URLs / spezielle S3-Features | certvia nutzt aktuell keine Presigned-URLs (Downloads laufen serverseitig) — vor Ausbau prüfen. |
|
||||
|
||||
---
|
||||
|
||||
## 11. Grobe Aufwandsschätzung
|
||||
|
||||
| Lane | Aufwand (Personentage, grob) |
|
||||
|------|------------------------------|
|
||||
| A Infra/Deployment | 2–3 |
|
||||
| B Provisioning | 2–3 |
|
||||
| C App-Code | 1–2 |
|
||||
| D Test/Cutover/Abnahme | 1–2 |
|
||||
| PM/Koordination | durchgehend |
|
||||
| **Summe** | **~6–10 PT** (ohne Datenmigration), gut parallelisierbar |
|
||||
|
||||
---
|
||||
|
||||
## 12. Alternativen (zur Vollständigkeit für D1)
|
||||
|
||||
| Option | Pro | Contra |
|
||||
|--------|-----|--------|
|
||||
| **Garage** (empfohlen) | aktiv, leicht, S3, self-hosted, DSGVO in eigener Hand | Bucket/Key via Admin-API (einmaliger Provisioning-Aufwand); kein Erasure-Coding (Replikation) |
|
||||
| SeaweedFS | performant, S3-Gateway, aktiv | größerer Funktionsumfang/komplexer als nötig |
|
||||
| Ceph/RGW | Enterprise-Standard, sehr robust | schwergewichtig, hoher Betriebsaufwand — für 1-Host überdimensioniert |
|
||||
| Externer managed S3 (Hetzner OS / Cloudflare R2) | kein Storage-Ops, hohe Verfügbarkeit | Datenresidenz/Abhängigkeit extern; Kosten; DSGVO-AV nötig |
|
||||
|
||||
---
|
||||
|
||||
## 13. Quellen (MinIO-Status / Garage-Provisioning)
|
||||
|
||||
- MinIO users complain after admin UI removed from Community Edition — blocksandfiles.com (2025-06)
|
||||
- MinIO Faces Fallout for Stripping Functions from Open Source Version — futuriom.com (2025-06)
|
||||
- MinIO Ends Community Development, Positions AIStor as the Future — faun.dev / devopslinks
|
||||
- MinIO in Maintenance Mode: Open Source Alternatives — bizety.com (2025-12)
|
||||
- minio/minio Discussion #21326 „It's not a feature issue, it's a trust one" — github.com
|
||||
- Garage — Administration API / Features / Bucket & Key Operations — garagehq.deuxfleurs.fr, deepwiki.com
|
||||
|
||||
*(Quellen-Status zeitkritisch; vor Projektstart kurz gegenprüfen.)*
|
||||
@@ -0,0 +1,50 @@
|
||||
# Konzept — Sicherheitshärtung (Lane H)
|
||||
|
||||
> Status: **Entscheidungsvorlage / Backlog** (kein Code). Produkt: **certvia** (ISMS-Tool). Freigegeben, weil der Auth-Umbau (Option C, WS0–WS5 + Contract) abgeschlossen ist. **Parallel** zur Backup-Lane baubar. Trifft die Backup-Lane genau am **gemeinsamen Verschlüsselungs-Primitiv** (§9 in `docs/KONZEPT-backup-restore.md`).
|
||||
|
||||
## 0. Umfang
|
||||
Alles unter „DB-/Plattform-Härtung", das **nicht** ins Backup-Konzept gehört: **Pepper**, **Host-Encryption at-rest**, **verschlüsselte Backups** (operativer Bezug zu §9), **DB-Connection-TLS**, **Secrets-Register**. Argon2-Parameter sind **erledigt**.
|
||||
|
||||
## 1. Pepper (Passwort-Hash) — App-Härtung
|
||||
**Ist:** `src/server/password.ts` nutzt Argon2id mit fixierten Parametern (`ARGON2_OPTIONS`), **Salt automatisch**, **kein Pepper**.
|
||||
**Soll:** globaler **Pepper** über die Argon2-`secret`-Option — bei `hash()` **und** jeder `verify()`-Stelle.
|
||||
- **Schlüsselquelle:** neues Umgebungs-Secret `PASSWORD_PEPPER` (32-Byte hex), analog `MFA_ENC_KEY`.
|
||||
- **Umsetzung schlank dank Option C:** der verify-Pfad ist nach WS1/WS4 zentralisiert (Login gegen Identity) → `secret` an genau den zentralen hash/verify-Helfer geben statt an 6 verstreute Stellen. Bevorzugt einen `verifyPassword(hash, pw)`-Wrapper einführen (falls noch nicht), damit Pepper **eine** Stelle ist.
|
||||
- ⚠ **Nicht rotierbar** ohne Passwort-Reset für alle (kein Rehash-on-Login) — wie `MFA_ENC_KEY`. Deshalb **jetzt setzen, solange test/dev-DBs frisch/leer sind**.
|
||||
- **Restore-Kohärenz:** Pepper ist ein **Umgebungs-Secret**, steht nicht in Backup-Artefakten → Restore nur in Umgebung mit passendem Pepper (siehe Backup-Konzept §9).
|
||||
**Dateien:** `src/server/password.ts` (+ zentraler verify-Wrapper), alle `verify()`-Aufrufer, `.env*`-Beispiele, Deploy-Env.
|
||||
|
||||
## 2. Host-Encryption at-rest (Live-DB + Objektspeicher)
|
||||
**Ist:** `pgvector/pgvector` (Community-Postgres, **kein TDE**); `pgdata`/MinIO-Volumes liegen im Klartext auf der VPS-Platte.
|
||||
**Soll:** **LUKS/dm-crypt** bzw. **provider-verschlüsseltes Volume** für das Daten-Volume (deckt `pgdata` **und** MinIO).
|
||||
- Schützt gegen physischen Plattendiebstahl/Decommission; transparent im Betrieb (im RAM entschlüsselt) — **kein** Schutz gegen Live-Server-Kompromittierung (dafür App-Feld-Encryption + Zugriffskontrollen).
|
||||
- Operativer Runbook-Punkt (nicht App-Code): einmalig einrichten, in `docs/DEPLOY-PROD-CONTABO.md` als Go-Live-Checkliste ergänzen.
|
||||
|
||||
## 3. Verschlüsselte Backups (operativer Bezug zu §9)
|
||||
Setzt die Entscheidung aus `docs/KONZEPT-backup-restore.md` §9 **operativ** um:
|
||||
- **pgBackRest** mit `repo-cipher-type=aes-256-cbc` + `repo-cipher-pass` → S3/MinIO.
|
||||
- **`age`** für Per-Tenant-/DSGVO-Artefakte; **restic** für MinIO-Dateien.
|
||||
- Verdrahtung in Coolify (Cron/Job + Zugangsdaten), Retention, **Restore-Test** dokumentieren.
|
||||
|
||||
## 4. DB-Connection-TLS
|
||||
**Ist:** `DATABASE_URL`/`RLS_DATABASE_URL` ohne `sslmode` → App↔Postgres **ohne** TLS, aber netz-isoliert (internes Docker-Netz `backend`, `internal: true`).
|
||||
**Soll:** `sslmode=require` (bzw. `verify-full` mit CA) **sobald** die DB je den Host/eine Vertrauensgrenze verlässt (managed DB, eigener DB-Host). Aktuell durch die Netz-Isolation gemindert → **Phase 2 / bedingt**, nicht dringlich.
|
||||
|
||||
## 5. Secrets-Register „restore-/betriebs-kritisch"
|
||||
Ein gepflegtes Register (Ort: Org-Passwortmanager) mit Ownership + Rotationsregel:
|
||||
| Secret | Zweck | Rotierbar? |
|
||||
|---|---|---|
|
||||
| `AUTH_SECRET` | Session-/JWT-Signatur | ja (invalidiert Sessions) |
|
||||
| `MFA_ENC_KEY` | TOTP-Secret-Verschlüsselung (AES-256-GCM) | **nein** ohne MFA-Neueinrichtung |
|
||||
| `PASSWORD_PEPPER` | Passwort-Pepper (neu, §1) | **nein** ohne Passwort-Reset |
|
||||
| pgBackRest-Repo-Key | Cluster-Backup-Verschlüsselung | ja (mit Repo-Rekey) |
|
||||
| `age`-Keypair | Per-Tenant-/DSGVO-Artefakte | ja (neue Artefakte) |
|
||||
Regeln: **je Umgebung getrennt** (test/dev/prod); **niemals** im selben Bucket wie die Artefakte; Offline-Kopie versiegelt.
|
||||
|
||||
## 6. Erledigt (nur Verweis)
|
||||
- **Argon2id-Parameter** fixiert/dokumentiert (`src/server/password.ts`, `ARGON2_OPTIONS`) — gemerged.
|
||||
- **TOTP-Secrets** AES-256-GCM at-rest (`src/server/secret-crypto.ts`, SEC3-d) — bestand bereits.
|
||||
|
||||
## 7. Phasen & offene Entscheidungen
|
||||
**Phasen:** (1) Pepper (App, jetzt — leere DBs). (2) Host-Encryption + verschlüsselte Backups (Ops, mit Backup-Lane). (3) Secrets-Register formalisieren. (4) DB-TLS + Vault/KMS = Phase 2.
|
||||
**Offen (PM/ISB/DSB):** Pepper-Env-Name bestätigen + „nicht rotierbar" akzeptieren · Vault/KMS-Zeitpunkt · optional Spalten-Verschlüsselung (pgcrypto) für besonders sensible PII.
|
||||
@@ -0,0 +1,98 @@
|
||||
# Umsetzungskonzept — Zentrale Identität mit Mandanten-Mitgliedschaften (Option C)
|
||||
|
||||
> Status: **Entscheidungsvorlage** (ohne Code). Ziel: eine Person meldet sich mit **einem** Login/Passwort und **einer** MFA an und wählt anschließend, in **welchem Mandanten** sie arbeitet — mit je Mandant unterschiedlichen Rollen. Die mandantengetrennte Datenhaltung (RLS, Ownership) bleibt **unangetastet**.
|
||||
|
||||
## 1. Grundmodell in einem Satz
|
||||
Eine **globale `Identity`** (E-Mail + ein Passwort + eine MFA) verweist auf **N per-Mandant-`User`-Zeilen** („Mitgliedschaften", jede mit eigenen Rollen). Zentralisiert werden nur **Anmeldung + MFA + Mandantenwechsel**; alles Fachliche bleibt pro Mandant.
|
||||
|
||||
## 2. Getroffene Entscheidungen
|
||||
| # | Entscheidung | Festlegung |
|
||||
|---|---|---|
|
||||
| A | MFA-Zeitpunkt | **Beim Login**, als getrennter zweiter Schritt (Two-Step, „identifier-first") |
|
||||
| B | Reset-Hoheit | Mandanten-Admin verliert MFA-/Passwort-Reset; Reset via **Self-Service (Recovery-Codes) + Plattform-Ebene**. Mandanten-Admin entzieht nur die **Mitgliedschaft**. |
|
||||
| C | Nutzeranlage | **Einladung/Bestätigung** als Standard (Kunden-Dashboard zwingend); Plattform-Admin darf zusätzlich direkt verknüpfen |
|
||||
| D | Migration Altbestand | **Entfällt** — bisher nur Testdaten. Neuanlage/Seed statt Zusammenführung. |
|
||||
| E | Plattform-Admins | **Getrennter Store** (`platform_admins`) bleibt — eigene Sicherheitsdomäne |
|
||||
| + | Login-Fluss | MFA-Abfrage **erst nach** Benutzername + Passwort (siehe §5) |
|
||||
| + | Passwort-Policy | **Eine globale Baseline**, passphrasen-freundlich (NIST 800-63B), mind. so streng wie der strengste Mandant |
|
||||
|
||||
**Phase 2 (bewusst zurückgestellt):** per-Mandant-Schalter „bei jedem Betreten Step-up erzwingen"; E-Mail-Änderung als Identity-Operation.
|
||||
|
||||
## 3. Datenmodell-Skizze (konzeptuell)
|
||||
**Neu: `Identity` (global)** — die Anmelde-Identität einer Person.
|
||||
- `email` (global eindeutig, Verknüpfungsschlüssel) · `passwordHash` · MFA (`mfaSecret`, `mfaEnrolledAt`, `recoveryCodes`) · `status` · `sessionsValidAfter` (globaler Kill-Switch) · Lockout-Felder.
|
||||
|
||||
**`User` (bestehend, bleibt pro Mandant) = „Mitgliedschaft"** — bekommt nur ein neues Feld `identityId → Identity`.
|
||||
- Behält: `tenantId`, `name`, `status`, **Rollen** (`user_roles`), **alle Ownership-FKs** (Asset-/Risk-/Prozess-Eigentümer …).
|
||||
- Gibt ab (wandert auf `Identity`): `passwordHash`, MFA-Felder, Recovery-Codes → künftig **nicht mehr** für Auth genutzt.
|
||||
|
||||
**Verknüpfung:** `Identity 1 —— N User(=Membership)`. Eine Person mit drei Mandanten = **eine** Identity + **drei** User-Zeilen.
|
||||
|
||||
**Unverändert:** `Role`/`UserRole`/`Permission` (pro Mandant), `Tenant`, `TenantSettings` (inkl. MFA-Pflicht-Flag), `platform_admins` (separat).
|
||||
|
||||
## 4. Was liegt wo?
|
||||
| Aspekt | Identity (global) | Membership = User (pro Mandant) |
|
||||
|---|---|---|
|
||||
| Passwort / Passphrase | ✅ (eins) | — |
|
||||
| MFA / Recovery-Codes | ✅ (eine Einrichtung) | — |
|
||||
| Rollen & Rechte | — | ✅ (je Mandant frei verschieden) |
|
||||
| Ownership (Assets, Risiken …) | — | ✅ |
|
||||
| Sperre der Person (global) | ✅ `status`/`sessionsValidAfter` | — |
|
||||
| Entzug des Zugangs zu **einem** Mandanten | — | ✅ Mitgliedschaft deaktivieren/löschen |
|
||||
|
||||
## 5. Login-Fluss (Two-Step, MFA beim Login)
|
||||
1. **Schritt 1 — E-Mail + Passwort** → Credential der `Identity` prüfen (Lockout + konstante Laufzeit gegen Enumeration wie heute).
|
||||
2. **Zwischenzustand:** kurzlebiger, einzweckiger **„MFA-pending"-Token** serverseitig — erlaubt **ausschließlich** den MFA-Abschluss, **keine** App-Session. (Verhindert „halb angemeldet"-Bypass.)
|
||||
3. **Schritt 2 — MFA** (eigene Seite), angezeigt wenn: Identity hat MFA **oder** ≥ 1 Mitgliedschaft in einem MFA-Pflicht-Mandanten.
|
||||
- MFA vorhanden → TOTP/Passkey verifizieren.
|
||||
- MFA nötig, aber nicht eingerichtet → **jetzt** einrichten (Enroll-Gate).
|
||||
- Keine MFA nötig → überspringen.
|
||||
4. **Volle Session** ausstellen (Identity authentifiziert + MFA erfüllt).
|
||||
5. **Mandanten-Auswahl:** aktive Mitgliedschaften in aktiven Mandanten. Auswahl → Server setzt `tenantId` + Rollen. **Nur eine** Mitgliedschaft → Auswahl überspringen.
|
||||
- **Sicherheitsnetz:** verlangt der gewählte Mandant MFA und ist sie (noch) nicht erfüllt → MFA vor Betreten nachziehen.
|
||||
|
||||
## 6. Mandantenwechsel (ohne erneuten Login) — Sicherheitskontrollen
|
||||
Zulässig und Standard, **aber nur mit diesen drei Pflicht-Kontrollen:**
|
||||
1. **Server-autoritativer Kontext:** aktiver `tenantId` wird bei **jedem** Wechsel aus einer **frisch validierten Mitgliedschaft** neu abgeleitet — nie aus Client-Input. RLS `app.tenant_id` pro Transaktion daraus.
|
||||
2. **Re-Validierung bei jedem Wechsel/Request:** Mitgliedschaft + Mandant + Nutzerstatus + `sessionsValidAfter` prüfen → Entzug/Sperre wirkt sofort.
|
||||
3. **MFA-Netz beim Betreten** eines Pflicht-Mandanten (Backstop zu §5.5).
|
||||
- Zusätzlich: **Wechsel wird auditiert** („Identity X → Mandant Y"), Folgeaktionen werden der aktiven Mitgliedschaft/Mandant zugeordnet.
|
||||
- Restrisiko bewusst: breiterer Blast-Radius eines kompromittierten Credentials → beherrscht über starke Identität + MFA + kurze Session-Laufzeit + globalen Kill-Switch.
|
||||
|
||||
## 7. MFA-Matrix (Person × Mandant)
|
||||
| Identity hat MFA? | Zielmandant verlangt MFA? | Ergebnis beim Login/Betreten |
|
||||
|---|---|---|
|
||||
| ja | ja | Faktor verifizieren |
|
||||
| ja | nein | kein Zwang (Faktor liegt vor, wird nicht abgefragt) |
|
||||
| nein | ja | **Einrichtung erzwingen** |
|
||||
| nein | nein | keine MFA |
|
||||
|
||||
> Grenze: Ein Mandant kann **kein** eigenes, isoliertes MFA-Gerät erzwingen — es gibt **einen** Faktor pro Person. (Preis der zentralen Identität.)
|
||||
|
||||
## 8. Nutzeranlage
|
||||
**Über das Plattform-(Admin-)Dashboard:**
|
||||
- E-Mail unbekannt → neue `Identity` (Initialpasswort/Einladung, `mustChangePassword`) + Mitgliedschaft im Zielmandanten mit Rollen.
|
||||
- E-Mail bekannt → **kein** neues Passwort/MFA, **nur** Mitgliedschaft ergänzen. Person sieht den Mandanten künftig in der Auswahl. (Betreiber darf direkt verknüpfen.)
|
||||
|
||||
**Über das Kunden-(Mandanten-)Dashboard — immer per Einladung:**
|
||||
- Mandanten-Admin sieht **neutral** „Einladung an *E-Mail* gesendet" — unabhängig davon, ob die Identity schon existierte (**kein** Cross-Tenant-Leak / keine Konten-Enumeration).
|
||||
- Identity existiert → Person **bestätigt** den Beitritt in ihrem bestehenden Konto (Einwilligung durch den Menschen, nicht durch den fremden Admin).
|
||||
- Identity existiert nicht → normaler „Konto einrichten + beitreten"-Flow.
|
||||
- Rollen werden bei der Einladung je Mandant vergeben (frei verschieden pro Mandant).
|
||||
|
||||
## 9. Passwort-/Passphrasen-Policy
|
||||
- **Eine globale Baseline** (weil ein Credential), mind. so streng wie der strengste Mandant.
|
||||
- Passphrasen voll unterstützt: lange Obergrenze (≥ 64 Zeichen), Leer-/Unicode-Zeichen erlaubt, **keine** erzwungene Zusammensetzung, **kein** Zwangswechsel, **Abgleich gegen Leak-Listen**. Hashing wie bisher Argon2id.
|
||||
|
||||
## 10. Auswirkungen auf Bestehendes
|
||||
- **Zwei Auth-Instanzen bleiben** (Mandant vs. Plattform). Die Mandanten-Instanz authentifiziert künftig gegen **`Identity`** statt `User`; die Session trägt zusätzlich die **Mitgliedschaftsliste** und den **aktiven** `tenantId`.
|
||||
- **RLS/Ownership/Audit unverändert** — hängen weiter an der per-Mandant-`User`-Zeile.
|
||||
- **Login-UI** wird zweistufig (Passwort-Seite → MFA-Seite → Mandanten-Auswahl); die heutige „alles in einem Formular"-Maske entfällt.
|
||||
- **MFA-/Passwort-Reset** in der Mandanten-Nutzerverwaltung entfällt (→ Self-Service/Plattform); dort bleibt „Mitgliedschaft deaktivieren/Rollen ändern".
|
||||
- **Bootstrap/Seed** legt künftig `Identity` + Mitgliedschaft(en) an.
|
||||
|
||||
## 11. Offene Detailpunkte fürs Implementierungs-Feindesign (kein Blocker)
|
||||
- Genaue Lebensdauer/Signierung des „MFA-pending"-Zustands.
|
||||
- Darstellung & Default der Mandanten-Auswahl (zuletzt genutzt merken?).
|
||||
- Wortlaut der neutralen Einladungs-Rückmeldung + Ablauf/Frist der Einladung.
|
||||
- Recovery-Code-Fluss als alleiniger Selbst-Reset-Weg (Anzahl, Nachgenerierung).
|
||||
@@ -0,0 +1,121 @@
|
||||
# Incident-Management — Fachkonzept (Certvia)
|
||||
|
||||
Modul „Vorfälle" (Placeholder im Bestand). Umfang: **Standard** — erfassen → kategorisieren/bewerten → bearbeiten (Verantwortliche, Aufgaben, Maßnahmen) → abschließen + Lessons Learned. Rahmen: **ISO 27001** (A.5.24–5.28), **NIS2** (Meldepflicht-Bewusstsein + Fristen), **TISAX/VDA-ISA** (1.6.x). Kanäle: **intern manuell** + **E-Mail-to-Ticket**. **Keine Behörden-API** — NIS2-/DSGVO-Meldung wird **vorbereitet** (Fristen-Timer + Meldevorlage/Export), Übermittlung erfolgt manuell.
|
||||
|
||||
---
|
||||
|
||||
## 1. Rollen (RACI-Kurz)
|
||||
| Rolle | Aufgabe |
|
||||
|---|---|
|
||||
| **Melder** (intern / E-Mail) | Meldet den Verdacht/Vorfall (Titel, Beschreibung, was/wann). |
|
||||
| **ISB / Incident-Manager** | Triage, Kategorisierung, Bewertung, Steuerung, **Meldepflicht-Entscheidung**, Abschluss. |
|
||||
| **IT / Bearbeiter** | Sofort-/Behebungsmaßnahmen umsetzen (als Aufgaben). |
|
||||
| **Geschäftsführung** | Eskalation, Freigabe externer Meldungen. |
|
||||
| **DSB** (optional) | Bei Personenbezug (DSGVO Art. 33/34). |
|
||||
|
||||
## 2. Kanäle (Intake)
|
||||
- **Intern manuell:** berechtigte Rollen legen Vorfall über die UI an (Popup wie bei Assets/Aufgaben).
|
||||
- **E-Mail-to-Ticket:** Zustellung an ein **Certvia-seitiges Eingangspostfach** (nicht an ein Kundenpostfach). Certvia betreibt eine Inbound-Domain und vergibt **je Mandant eine eindeutige, nicht erratbare Adresse** (z. B. `vorfall-<token>@in.certvia.de`); der Kunde nutzt sie direkt **oder** leitet von seiner eigenen Adresse (`vorfall@kunde.de`) dorthin **weiter**. Über die Zieladresse erfolgt die **Mandantenzuordnung**. Eingehende Mail → Vorfall im Status **Neu/Triage** (Betreff→Titel, Text→Beschreibung, Absender→Melder). Dedupe über Message-Header; **Absender-Allowlist** (nur interne Kundendomänen erzeugen Tickets) + SPF/DKIM/DMARC-Prüfung + Spam-Filter; externe/unbekannte Absender werden „extern" markiert (Triage). Anhänge später (Storage-Paket).
|
||||
- **Inbound ist ein eigener Kanal:** SEC1 deckte nur den **Ausgang** (SMTP) ab; für den Empfang braucht es einen Empfangsweg. **Warum kein Kundenpostfach:** kein Speichern/Pollen von Kunden-IMAP/OAuth-Credentials → weniger Aufwand, robuster, DSGVO-/sicherheitsseitig sauberer.
|
||||
- **Konkrete Umsetzung (All-inkl · einfachster Weg, gewählt):** Subdomain **`in.certvia.de`** bei All-inkl mit **Catch-all-Postfach** — alle `vorfall-<token>@in.certvia.de` landen in **einem** Postfach. *(Catch-all in All-inkl KAS: E-Mail → E-Mail-Postfach → „Neues Postfach anlegen", das **Adressfeld leer lassen**. Catch-all ist spam-anfällig → eigene, nirgends veröffentlichte Intake-Subdomain hält die Spam-Fläche klein; zusätzlich Allowlist/DKIM/Review-Pfad.)* Certvia holt die Mails per **IMAP** (kurzes Polling/IDLE, BullMQ-Job), parst sie (mailparser), ermittelt den **Token aus dem Empfänger-Header** (`Delivered-To`/`X-Envelope-To` — **nicht** `To`, da dort bei Weiterleitung die Kundenadresse steht), ordnet dem Mandanten zu, legt den Vorfall an und verschiebt die Mail nach „Verarbeitet"/„Fehler". Idempotenz über `Message-ID`; unbekannter/kein Token → **Betreiber-Review** statt Drop. **Kein Postfach je Kunde** (Catch-all + **Auto-Token**), keine KAS-API nötig; einmaliger globaler Setup (Subdomain + Catch-all + IMAP-Zugang als Plattform-Secret).
|
||||
- **Weiterleitungs-Fallstricke:** Weiterleitung bricht i. d. R. **SPF** (DKIM bleibt meist gültig) → **nicht** hart auf SPF-Fail ablehnen; Vertrauen über **Absender-Allowlist + DKIM**, SPF nur als Signal. Auto-Reply/Bounce-Schleifen über `Auto-Submitted`/Precedence-Header erkennen und ignorieren. Größenlimit/Spam-Filter beachten.
|
||||
- **Mail-Einstellungen:** die **mandantenspezifischen** Einstellungen (Intake-Adresse/Routing, Benachrichtigungspräferenzen, Absender-Anzeige) werden im **Einstellungs-Modul** gepflegt. Die **SMTP-Zugangsdaten/der Transport** bleiben aus Sicherheitsgründen auf **Plattform-/Secret-Store-Ebene** (SEC1) — kein Mandant legt Server-Credentials selbst an.
|
||||
|
||||
## 3. Lebenszyklus / Statusmodell
|
||||
**Primärfluss:**
|
||||
`Neu/Eingegangen → Triage → In Bearbeitung → Eingedämmt (contained) → Behoben → Abgeschlossen` · (+ `Wiedereröffnet`)
|
||||
- Jeder Übergang: Pflichtfelder-Check, Zeitstempel, Akteur, Audit-Eintrag.
|
||||
- **Parallel-Track „Meldung"** (nur wenn meldepflichtig): `Meldepflicht geprüft → Erstmeldung (24 h) → Folgemeldung (72 h) → Abschlussbericht (1 Monat)` — als **Status + Timer**, Übermittlung manuell.
|
||||
|
||||
## 4. Datenmodell (Incident-Objekt)
|
||||
- **Kennung:** `refNo` (z. B. `INC-2026-0042`), `tenantId` (RLS).
|
||||
- **Basis:** Titel, Beschreibung, **Kanal/Quelle** (manuell/E-Mail), Melder (+Kontakt).
|
||||
- **Zeiten:** `occurredAt` (Eintritt), `detectedAt` (Entdeckung), `reportedAt` (interne Meldung), Timeline.
|
||||
- **Kategorie** (Taxonomie): Schadsoftware · Phishing/Social Engineering · Unbefugter Zugriff · Datenabfluss/-verlust · Systemausfall/Verfügbarkeit · Physisch (Zutritt/Diebstahl) · Fehlbedienung/Konfiguration · Lieferant/Drittpartei · **Prototyp/Kundendaten** (TISAX) · Sonstiges.
|
||||
- **Betroffenheit:** verknüpfte **Assets/Prozesse (BIA)**, Schutzziel-Impact **C/I/A**, Datenkategorien, **Personenbezug** (→ DSGVO-Flag), **Prototyp/Kundendaten** (→ TISAX-Flag).
|
||||
- **Bewertung:** **Schweregrad/Priorität** (siehe §5).
|
||||
- **Steuerung:** `owner` (Incident-Manager), Bearbeiter, Status.
|
||||
- **Meldepflicht:** `nis2Relevant`, `dsgvoRelevant` (bool) + Meldestatus + Fristen (§6).
|
||||
- **Behebung:** Sofortmaßnahmen, **Ursache (Root Cause)**, Lösung/Resolution.
|
||||
- **Abschluss:** Abschlussnotiz, **Lessons Learned**, verknüpfte **CAPA-Aufgaben**.
|
||||
- **Verknüpfungen:** **Maßnahmen** (im zentralen Maßnahmen-Modul, §9), **Risiken** (bestätigt/neu), **Controls** (welche versagten/betroffen), **Nachweise**.
|
||||
- **Kommentare/Notizen:** **Kommentar-Thread** am Vorfall (Autor, Zeitstempel, editierbar nach Regel) für die Zusammenarbeit — **getrennt** von der automatischen, manipulationssicheren **Audit-Timeline** (§8/§9). Interne vs. sichtbare Kommentare optional.
|
||||
- **Anhänge:** Belege (Screenshots/Logs) — Modell vorbereiten, Datei-Persistenz mit Storage-Paket.
|
||||
|
||||
## 5. Schweregrad / Priorisierung
|
||||
- **Schweregrad** aus **Auswirkung** (C/I/A-Verletzung × Umfang: einzelnes System … unternehmensweit … Kunde/Lieferkette) und **Dringlichkeit** → Klassen **niedrig · mittel · hoch · kritisch**.
|
||||
- Treibt **interne SLA** (Reaktion/Behebung), **Eskalation** und **Benachrichtigungen**. Matrix mandantenkonfigurierbar (Default vorgegeben).
|
||||
|
||||
## 6. Fristen & Timer (vorbereitet, ohne Behörden-API)
|
||||
| Auslöser | Frist | Umsetzung im Tool |
|
||||
|---|---|---|
|
||||
| **NIS2** – Früh-/Erstmeldung | **24 h** ab Kenntnis | Timer/Countdown + Erinnerung (SEC1) + Meldevorlage |
|
||||
| **NIS2** – Meldung | **72 h** | Timer + Vorlage (Aktualisierung) |
|
||||
| **NIS2** – Abschlussbericht | **1 Monat** | Timer + Abschluss-Vorlage/Export |
|
||||
| **DSGVO** Art. 33 (bei Personenbezug) | **72 h** | Timer + Datenschutz-Meldevorlage |
|
||||
| **Interne SLA** (je Severity) | konfigurierbar | Reaktions-/Behebungs-Timer |
|
||||
- Timer nur, wenn **Meldepflicht = ja** (NIS2-Betroffenheit des Mandanten aus den Einstellungen). Countdown im Vorfall + Dashboard-Kachel; **Eskalation** bei drohender/verpasster Frist. **Übermittlung an die Behörde erfolgt manuell** (Vorlage/Export bereitgestellt).
|
||||
|
||||
## 7. Benachrichtigungen (SEC1)
|
||||
Neuer Vorfall → ISB/Incident-Manager; Zuweisung → Bearbeiter; Statuswechsel → Beteiligte; **Fristen-Erinnerung/Eskalation**; Abschluss → Melder/GF. Respektiert Benachrichtigungspräferenzen + Mandantenisolation.
|
||||
|
||||
## 8. Abschluss & Lessons Learned
|
||||
- Pflicht beim Abschluss: **Ursache**, **Lösung**, Wirksamkeit der Maßnahmen, **Lessons Learned**.
|
||||
- **CAPA**: korrigierende/präventive Maßnahmen als **Aufgaben** anlegen; **Risikoregister** aktualisieren (Risiko bestätigt/neu); Bezug zu betroffenen **Controls**.
|
||||
- Optionaler **Post-Incident-Review** (Kurzbericht) → speist **Management-Review**.
|
||||
|
||||
## 9. Verknüpfung zu bestehenden Modulen
|
||||
- **Maßnahmen-Modul** (vorhanden): Sofort- und CAPA-Maßnahmen werden **im zentralen Maßnahmen-Modul angelegt/gepflegt** (nicht doppelt im Vorfall) und mit dem Vorfall **verknüpft**; im Vorfall erscheinen sie als verknüpfte Liste mit „Maßnahme direkt aus dem Vorfall anlegen". Verantwortliche/Fristen/Status kommen aus dem Maßnahmen-Modul; Bezug zu Risiken/Controls möglich. *(Hinweis: falls „Maßnahmen"/„Aufgaben" heute getrennt sind, an **eine** zentrale Maßnahmen-/Aufgaben-Backbone andocken.)*
|
||||
- **Kommentare** dagegen liegen **am Vorfall** (Thread, §4) — sie sind Zusammenarbeit, keine trackbare Maßnahme.
|
||||
- **Assets/BIA · Risiken · Controls**: Betroffenheit und Wirkung verknüpfen; Vorfall kann Risiko bestätigen/erzeugen.
|
||||
- **Audit-Log**: Vorfall-Timeline (wer/wann/was) manipulationssicher (getrennt von den Kommentaren).
|
||||
- **Nachweise/Export**: Vorfallregister + Einzelbericht (DOCX/PDF über Export-Layer), NIS2-/DSGVO-Meldevorlagen (vorbefüllt) für die manuelle Übermittlung.
|
||||
|
||||
## 10. Framework-Mapping
|
||||
| Rahmen | Bezug |
|
||||
|---|---|
|
||||
| **ISO 27001:2022** | A.5.24 Planung/Vorbereitung · A.5.25 Bewertung/Entscheidung · A.5.26 Reaktion · A.5.27 Lernen · A.5.28 Beweissicherung |
|
||||
| **TISAX / VDA-ISA** | 1.6.x Incident-/Ereignismanagement; Prototyp-/Kundendaten-Bezug |
|
||||
| **NIS2** (Art. 23) | Meldekette 24 h/72 h/1 Monat — im Tool als Timer/Vorlage vorbereitet |
|
||||
| **DSGVO** | Art. 33/34 Datenpanne (72 h) — Timer/Vorlage |
|
||||
|
||||
## 11. Rechte / Sicherheit
|
||||
- Strikt **mandantengebunden (RLS)**; rollenbasierte Rechte (melden vs. bearbeiten vs. abschließen/melden).
|
||||
- **Vertraulichkeit:** sensible Vorfälle optional auf einen eingeschränkten Personenkreis begrenzbar.
|
||||
- Meldevorlagen/Exports datensparsam; jede Aktion auditiert.
|
||||
|
||||
## 12. Technische Einordnung
|
||||
- **Eigenes Modul „Vorfälle"** (`incidents`), modul-gated (Superadmin-Toggle); **Maßnahmen** über das zentrale **Maßnahmen-Modul** (verknüpft); **Kommentare** als eigener Thread am Vorfall; **Mail** über SEC1; **Timeline** über Audit; Verknüpfungen zu Assets/Risiken/Controls.
|
||||
- **Mail-Einstellungen:** mandantenseitig im **Einstellungs-Modul** (Intake-Adresse, Benachrichtigungen); SMTP-Transport plattformseitig (SEC1).
|
||||
- Popups/Bedienung im etablierten Muster (wie Assets/Maßnahmen).
|
||||
|
||||
## 12a. Provisionierung des Intake-Postfachs (Betreiberportal & Onboarding)
|
||||
Das Anlegen der Inbound-Route (`vorfall-<token>@in.certvia.de`) ist zunächst ein **manueller Betreiber-Schritt** — dafür braucht es die richtigen Infos beim Onboarding und einen sichtbaren Status.
|
||||
|
||||
**Beim Kunden-Onboarding erfassen** (Admin-Konsole „Kunde anlegen", nur wenn Modul „Vorfälle" + E-Mail-to-Ticket aktiv):
|
||||
- **Absender-/Weiterleitungs-Domäne(n)** des Kunden (z. B. `kunde.de`) → **Allowlist**.
|
||||
- optional konkrete **Quelladresse** (`vorfall@kunde.de`), von der weitergeleitet wird.
|
||||
- **Intake-Adresse** wird von Certvia **automatisch generiert** (`vorfall-<token>@in.certvia.de`) und angezeigt (der Kunde richtet die Weiterleitung darauf ein).
|
||||
- optional Benachrichtigungsempfänger/Sprache.
|
||||
|
||||
**Provisionierungs-Status je Kunde** (Betreiberportal): `Postfach anzulegen → angelegt → verifiziert`.
|
||||
- Solange „anzulegen": **Hinweis-Badge** am Kundendatensatz („⚠ Intake-Postfach anlegen") **und** eine **Sammelliste offener Provisionierungen** auf dem Betreiber-Dashboard.
|
||||
- **Betreiber-Schritt:** Inbound-Route/Alias im Inbound-Dienst anlegen (manuell **oder** per Provider-API) → Status „angelegt". **Verifizierung** per Test-Mail (analog SEC1-Testversand) → „verifiziert".
|
||||
- **Ausbau:** bei Inbound-Providern mit API kann die Route beim Modul-Aktivieren **automatisch** angelegt werden → Status springt direkt auf „angelegt"; bis dahin bleibt es der manuelle Hinweis-Schritt.
|
||||
- Alle Provisionierungs-Aktionen im **Plattform-Audit** (`scope=platform`).
|
||||
|
||||
> **Mit der gewählten Variante (All-inkl Catch-all + Auto-Token):** Es muss **kein Postfach je Kunde** angelegt werden; der **Token wird automatisch generiert**. Der einmalige Setup (Subdomain `in.certvia.de` + Catch-all-Postfach + IMAP-Zugang) ist ein **globaler** Betreiber-Schritt, nicht je Kunde. Der **per-Kunde-Schritt reduziert sich** darauf, die **Weiterleitung des Kunden per Test-Mail zu verifizieren** → vereinfachter Status je Kunde: `Weiterleitung ausstehend → verifiziert`. Der Onboarding-Datenbedarf bleibt (Allowlist-Domänen, Quelladresse); die Intake-Adresse wird automatisch erzeugt/angezeigt.
|
||||
|
||||
## 13. Abgrenzung / spätere Ausbaustufen
|
||||
- **Direkte Behörden-Übermittlung** (BSI-Meldeportal/-API) — jetzt bewusst **nicht** (nur Vorlage/Export).
|
||||
- Automatische Erkennung/**SIEM-Integration**, **externe/anonyme** Meldung, SLA-Automationen, KI-gestützte Klassif/Zusammenfassung — spätere Stufen.
|
||||
|
||||
## 14. Offene Entscheidungen
|
||||
1. **NIS2-Betroffenheit je Mandant** — woher (Mandanten-Einstellungen: „wichtige/wesentliche Einrichtung"?), steuert die Timer.
|
||||
2. **Severity-Matrix** — fester Default oder mandantenkonfigurierbar?
|
||||
3. **Inbound (entschieden):** All-inkl **Catch-all-Postfach** auf `in.certvia.de` + **IMAP-Abholung**, **Auto-Token**, kein Postfach je Kunde. Rest-Details: Polling-Intervall vs. IMAP-IDLE, welcher Header trägt den Token (`Delivered-To`/`X-Envelope-To` — beim ersten Test verifizieren), Ordner-/Fehler-Handling.
|
||||
4. **Anhänge** — abhängig vom Storage-Paket (bis dahin nur Referenz/Text).
|
||||
5. **Vertraulichkeits-Stufen** für sensible Vorfälle — jetzt oder später?
|
||||
|
||||
---
|
||||
*Nächster Schritt auf Wunsch: Entwickler-Task-Paket (Branches, Stories, DoD) — Maßnahmen auf das Task-Modul aufsetzend, Mail über SEC1, Timer/Meldevorlagen NIS2/DSGVO.*
|
||||
@@ -0,0 +1,50 @@
|
||||
# Konzept — Betreiber-Konsole-UX + vollständige i18n (parallele Lane)
|
||||
|
||||
> Status: **Backlog/Feindesign-Skizze** (kein Code). Produkt: **certvia** (ISMS-Tool). Unabhängig von Identity/Backup/Härtung → **parallel** abarbeitbar. Enthält die zwei gemeldeten „Bugfixes" + zwei kleine Ergänzungen.
|
||||
|
||||
## Bugfix 1 — Betreiber-Konsole: Module & Benutzer als Popup, Stammdaten sichtbar
|
||||
**Betrifft:** `src/app/(platform)/admin/[id]/page.tsx` (Mandanten-Detailseite im Betreiber-Portal).
|
||||
|
||||
**Ist:** Module-Liste und Benutzerverwaltung liegen **inline direkt auf dem Kundenprofil**; die eigentlichen Stammdaten des Kunden sind dort **nicht** prominent.
|
||||
|
||||
**Soll:**
|
||||
- **Module → Popup:** nicht mehr inline, sondern per Button „Module verwalten" → Popup (Muster wie gehabt über searchParam, z. B. `?modules=1`, `<Modal>`). Toggle/Import bleiben im Popup.
|
||||
- **Benutzer → Popup:** die Benutzer-Tabelle/-Verwaltung nicht mehr im Hauptfenster, sondern Button „Benutzer verwalten" → Popup (`?users=1`). Anlage/Bearbeiten laufen wie bisher als verschachtelte Modals (`?new`/`?edit`).
|
||||
- **Hauptfenster stattdessen:** **Stammdaten** (aus `TenantSettings`: Unternehmensname/Kurzname, Adresse, Sektor, D-U-N-S, TISAX-Level, Status) **+ Hauptkontakt** prominent sichtbar. „Hauptkontakt" = neues/abgeleitetes Feld (z. B. designierter Mandanten-Admin oder ein Stammdaten-Kontaktfeld) — **offene Kleinentscheidung:** eigenes Feld in `TenantSettings` (`mainContactName/Email/Phone`) vs. Ableitung aus dem `tenant-admin`.
|
||||
|
||||
**Muster ist vorhanden:** die Seite nutzt bereits `<Modal>` + searchParams (`?new`/`?edit`/`?audit`) → Module/Benutzer analog kapseln, keine neue Infrastruktur.
|
||||
|
||||
**Dateien:** `src/app/(platform)/admin/[id]/page.tsx`, ggf. `src/components/*` (Auslagerung Module-/Benutzer-Block), optional Migration für `mainContact*` in `TenantSettings`.
|
||||
|
||||
## Bugfix 2 — Vollständige UI-Sprache (Menü + Beschreibungen) + per-Mitarbeiter-Umschaltung
|
||||
**Wichtiger Befund:** Der **englische UI-Katalog existiert bereits** (`messages/en.json`, ~95 % vs. `messages/de.json`). Bisher ist **nur der Richtlinien-Inhalt** EN (über `TenantSettings.locale`, das die **Import-Sprache der Vorlagen** steuert). Das **Menü/die Beschreibungen** sind EN im Katalog vorhanden, werden aber **nie angezeigt**, weil:
|
||||
```
|
||||
src/i18n/request.ts:8 → const locale = "de"; // hart verdrahtet
|
||||
// Kommentar: "MVP is fixed to de; per-user locale (en) is prepared — switch here later"
|
||||
```
|
||||
|
||||
**Soll:** die UI-Sprache **per Mitarbeiter individuell** umschaltbar.
|
||||
- **Speicherort (Option-C-konform):** persönliche Präferenz gehört an die **`Identity`** (folgt der Person über alle Mandanten) — neues Feld `Identity.uiLocale` (`de`|`en`, Default `de`). *(Alternative: pro Mitgliedschaft — verworfen, weil Menüsprache eine Personen-, keine Mandantenpräferenz ist.)*
|
||||
- **Aktivierung:** `src/i18n/request.ts` liest statt der Konstante die `uiLocale` der aktiven Session-Identity (Fallback `de`).
|
||||
- **Umschalter:** im **Nutzer-Menü** (Header/Profil) ein Sprachauswahl-Control → Server-Action `setUiLocale` → `Identity.uiLocale` speichern, Seite neu laden.
|
||||
- **Restsprache:** `messages/en.json` auf 100 % prüfen/auffüllen (Lücken, neue Strings aus TISAX/Identity-Umbau). Sicherstellen, dass **alle** sichtbaren Strings über den Katalog laufen (keine hartkodierten deutschen Texte in Komponenten).
|
||||
|
||||
**Abgrenzung:** `TenantSettings.locale` bleibt für die **Vorlagen-Import-Sprache** (Inhalt); **neu** ist die **UI-Sprache je Person** (`Identity.uiLocale`) — zwei getrennte Achsen.
|
||||
|
||||
**Dateien:** `prisma/schema.prisma` (`Identity.uiLocale` + Migration), `src/i18n/request.ts`, Nutzer-Menü-Komponente (Header/Profil) + `setUiLocale`-Action, `messages/en.json` (Lückenschluss), Audit der hartkodierten Strings.
|
||||
|
||||
## Ergänzung A — Login-Maske: Organisationsfeld entfällt
|
||||
**Ist:** `src/app/login/page.tsx` zeigt weiterhin ein optionales Feld **„Organisation"** (`tenant`, als Hinweis behalten).
|
||||
**Soll:** Feld **entfernen** — nach Option C ist es überflüssig (Login gegen globale Identity; Mandant wird **nach** dem Login über `/select-tenant` gewählt). Die `tenant`-Durchreichung in `login`-Action / `signMfaPending` / `signLoginTicket` kann entfallen bzw. leer bleiben.
|
||||
**Dateien:** `src/app/login/page.tsx` (Feld raus), ggf. `src/server/login-ticket.ts`-Signaturen entschlacken.
|
||||
|
||||
## Ergänzung B — Konsistenz-Check „Stammdaten"
|
||||
Beim Sichtbarmachen der Stammdaten (Bugfix 1) prüfen, dass die Quelle **eine** bleibt (`TenantSettings` speist die ISMS-Variablen) — keine Doppelpflege einführen.
|
||||
|
||||
## Reihenfolge / Parallelität
|
||||
- **Bugfix 1** (Betreiber-Konsole) und **Bugfix 2** (i18n) sind unabhängig → parallel.
|
||||
- **Ergänzung A** (Login) ist ein 10-Minuten-Fix, gern zusammen mit Bugfix 2 (beide Auth-/UI-nah).
|
||||
- Keine Abhängigkeit zu Backup/Härtung; Bezug zu Option C nur konzeptuell (`Identity.uiLocale`, `/select-tenant` existiert bereits).
|
||||
|
||||
## Gate (wie immer)
|
||||
tsc/lint/build + `scripts/test-*.ts` grün; UI-Änderungen im Browser verifizieren (Betreiber-Popups, Sprachumschaltung DE↔EN, Login ohne Organisationsfeld).
|
||||
@@ -0,0 +1,355 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>certvia – BIA-Prozessübersicht (Mockup)</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&family=Open+Sans:wght@400;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root{
|
||||
--violet:#5d52a3; --violet2:#7d6fd6; --magenta:#812d80; --blue:#8dc4e0; --ink:#3b3b3a;
|
||||
--violet-050:#f2f0f9; --violet-100:#e6e2f3; --blue-050:#eef7fb;
|
||||
--grad-soft:linear-gradient(135deg,#5d52a3 0%,#8dc4e0 100%);
|
||||
--bg:#f5f6fa; --card:#ffffff; --line:#e7e8ef; --line2:#eff0f5; --muted:#7a7b86;
|
||||
--soft:#fafbfd;
|
||||
--ok:#2e9e6b; --warn:#e0982e; --risk:#d64c4c; --info:#3a86c8;
|
||||
--ok-bg:#e9f6ef; --warn-bg:#fdf3e2; --risk-bg:#fbe9e9; --info-bg:#e9f2fb; --gray-bg:#eef0f4;
|
||||
--shadow:0 1px 3px rgba(30,25,60,.06),0 6px 20px rgba(30,25,60,.05);
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
html,body{margin:0}
|
||||
body{font-family:"Open Sans",system-ui,sans-serif;color:var(--ink);background:var(--bg);font-size:14px}
|
||||
h1,h2,h3,h4{font-family:"Poppins",sans-serif;font-weight:600;margin:0}
|
||||
.wrap{max-width:1180px;margin:0 auto;padding:26px 26px 60px}
|
||||
|
||||
/* Page head */
|
||||
.crumb{font-size:12px;color:var(--muted);margin-bottom:3px}
|
||||
.pagehead{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
|
||||
.pagehead h1{font-size:23px}
|
||||
.pagehead .sub{color:var(--muted);margin-top:5px;font-size:13px;max-width:640px;line-height:1.5}
|
||||
.head-actions{display:flex;align-items:center;gap:10px}
|
||||
.toggle{display:flex;background:#fff;border:1px solid var(--line);border-radius:10px;padding:3px;gap:2px}
|
||||
.toggle button{border:0;background:transparent;font-family:Poppins;font-weight:600;font-size:12.5px;color:var(--muted);padding:6px 12px;border-radius:8px;cursor:pointer;display:flex;align-items:center;gap:6px}
|
||||
.toggle button.active{background:var(--violet-100);color:var(--violet)}
|
||||
.btn{border:0;border-radius:10px;padding:9px 15px;font-weight:600;font-family:Poppins;font-size:13px;cursor:pointer;display:inline-flex;align-items:center;gap:7px}
|
||||
.btn.primary{background:var(--grad-soft);color:#fff}
|
||||
|
||||
/* KPI */
|
||||
.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:20px 0 6px}
|
||||
.kpi{background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);padding:15px 16px}
|
||||
.kpi .lbl{color:var(--muted);font-size:12px;font-weight:600}
|
||||
.kpi .val{font-family:Poppins;font-weight:700;font-size:27px;margin:5px 0 0;line-height:1}
|
||||
.kpi .val small{font-size:14px;color:var(--muted);font-weight:600}
|
||||
.kpi .bar{height:6px;border-radius:6px;background:#eef0f6;overflow:hidden;margin-top:11px}
|
||||
.kpi .bar>i{display:block;height:100%;border-radius:6px}
|
||||
|
||||
/* Legend */
|
||||
.legend{display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin:16px 2px 4px;font-size:12px;color:var(--muted)}
|
||||
.legend .grp{display:flex;align-items:center;gap:8px}
|
||||
.legend .sw{width:12px;height:12px;border-radius:3px;display:inline-block}
|
||||
.legend .dot{width:10px;height:10px;border-radius:50%;display:inline-block}
|
||||
.legend b{color:var(--ink);font-weight:600}
|
||||
|
||||
/* Lanes */
|
||||
.lane{margin-top:22px}
|
||||
.lane-head{display:flex;align-items:center;gap:10px;margin:0 2px 12px}
|
||||
.lane-head .tag{font-family:Poppins;font-weight:600;font-size:14px}
|
||||
.lane-head .cnt{font-size:11.5px;color:var(--muted);background:#fff;border:1px solid var(--line);border-radius:999px;padding:2px 9px;font-weight:600}
|
||||
.lane-head .rule{flex:1;height:1px;background:var(--line)}
|
||||
.lane-mgmt .tag{color:var(--magenta)}
|
||||
.lane-core .tag{color:var(--violet)}
|
||||
.lane-supp .tag{color:var(--info)}
|
||||
|
||||
/* Main process card */
|
||||
.mp{background:var(--card);border:1px solid var(--line);border-left-width:4px;border-radius:14px;box-shadow:var(--shadow);margin-bottom:13px;overflow:hidden}
|
||||
.mp.st-komplett{border-left-color:var(--ok)}
|
||||
.mp.st-teilweise{border-left-color:var(--warn)}
|
||||
.mp.st-offen{border-left-color:#c4c8d2}
|
||||
.mp-head{display:flex;align-items:center;gap:14px;padding:14px 16px;cursor:pointer;user-select:none}
|
||||
.mp-head:hover{background:var(--soft)}
|
||||
.chev{width:16px;height:16px;flex:0 0 16px;color:var(--muted);transition:transform .18s}
|
||||
details[open] .chev{transform:rotate(90deg)}
|
||||
.mp-title{min-width:0;flex:1}
|
||||
.mp-title .nm{font-family:Poppins;font-weight:600;font-size:14.5px;display:flex;align-items:center;gap:9px;flex-wrap:wrap}
|
||||
.mp-title .meta{margin-top:4px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;color:var(--muted);font-size:12px}
|
||||
.owner{display:inline-flex;align-items:center;gap:6px}
|
||||
.owner .av{width:19px;height:19px;border-radius:50%;background:var(--grad-soft);color:#fff;display:grid;place-items:center;font-size:9.5px;font-family:Poppins;font-weight:700}
|
||||
|
||||
/* metrics strip */
|
||||
.metrics{display:flex;gap:8px;flex:0 0 auto}
|
||||
.m{background:var(--soft);border:1px solid var(--line2);border-radius:9px;padding:5px 10px;text-align:center;min-width:58px}
|
||||
.m .k{font-size:9.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);font-weight:700}
|
||||
.m .v{font-family:Poppins;font-weight:600;font-size:13.5px;margin-top:1px}
|
||||
|
||||
/* pills */
|
||||
.pill{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:999px;font-size:11px;font-weight:700;white-space:nowrap}
|
||||
.pill .dot{width:7px;height:7px;border-radius:50%}
|
||||
.crit-1{background:var(--gray-bg);color:#5b6070}
|
||||
.crit-2{background:var(--info-bg);color:var(--info)}
|
||||
.crit-3{background:var(--warn-bg);color:#b9761b}
|
||||
.crit-4{background:var(--risk-bg);color:var(--risk)}
|
||||
.st-pill.komplett{background:var(--ok-bg);color:var(--ok)}
|
||||
.st-pill.teilweise{background:var(--warn-bg);color:#b9761b}
|
||||
.st-pill.offen{background:var(--gray-bg);color:#5b6070}
|
||||
.tag-cat{background:var(--violet-050);color:var(--violet);border:1px solid var(--violet-100);padding:2px 8px;border-radius:6px;font-size:10.5px;font-weight:700}
|
||||
|
||||
/* dependencies row */
|
||||
.deps{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:0 16px 12px 46px}
|
||||
.deps .lab{font-size:11px;color:var(--muted);font-weight:600;display:inline-flex;align-items:center;gap:5px}
|
||||
.dep{display:inline-flex;align-items:center;gap:6px;background:#fff;border:1px solid var(--line);border-radius:999px;padding:3px 10px;font-size:11.5px;font-weight:600;color:#4b4c57}
|
||||
.dep.crossref{border-style:dashed;border-color:var(--violet2);color:var(--violet)}
|
||||
.dep .ic{width:12px;height:12px;opacity:.7}
|
||||
|
||||
/* sub processes tree */
|
||||
.subs{padding:2px 16px 14px 30px;background:var(--soft);border-top:1px dashed var(--line)}
|
||||
.subs-h{font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);font-weight:700;margin:10px 0 8px 16px}
|
||||
.sub{position:relative;display:flex;align-items:center;gap:12px;padding:9px 12px 9px 16px;margin-left:16px;border-radius:10px}
|
||||
.sub:hover{background:#fff}
|
||||
/* tree connector */
|
||||
.sub::before{content:"";position:absolute;left:0;top:-6px;bottom:50%;width:1px;background:#d6dae3}
|
||||
.sub::after{content:"";position:absolute;left:0;top:50%;width:12px;height:1px;background:#d6dae3}
|
||||
.sub:last-child::before{bottom:50%}
|
||||
.sub .sdot{width:9px;height:9px;border-radius:50%;flex:0 0 9px;z-index:1;box-shadow:0 0 0 3px var(--soft)}
|
||||
.sdot.komplett{background:var(--ok)} .sdot.teilweise{background:var(--warn)} .sdot.offen{background:#c4c8d2}
|
||||
.sub .snm{flex:1;min-width:0}
|
||||
.sub .snm .t{font-weight:600;font-size:13px}
|
||||
.sub .snm .s{color:var(--muted);font-size:11.5px;margin-top:1px;display:flex;gap:10px;flex-wrap:wrap}
|
||||
.sub .metrics .m{background:#fff}
|
||||
.sub .right{display:flex;align-items:center;gap:8px}
|
||||
.mini{font-size:11px;color:var(--muted);display:inline-flex;align-items:center;gap:5px}
|
||||
|
||||
.note{margin-top:26px;background:var(--violet-050);border:1px solid var(--violet-100);border-radius:12px;padding:14px 16px;font-size:12.5px;color:#4b4c57;line-height:1.6}
|
||||
.note b{color:var(--violet)}
|
||||
.foot{margin-top:22px;color:var(--muted);font-size:11.5px;text-align:center}
|
||||
@media(max-width:820px){
|
||||
.kpis{grid-template-columns:repeat(2,1fr)}
|
||||
.metrics{display:none}
|
||||
.mp-head{flex-wrap:wrap}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
|
||||
<div class="pagehead">
|
||||
<div>
|
||||
<div class="crumb">Strukturanalyse · GEFIM (TISAX)</div>
|
||||
<h1>Business Impact Analyse — Prozessübersicht</h1>
|
||||
<div class="sub">Prozesse gegliedert nach Haupt- und Teilprozessen. Farbe = BIA-Status, Kritikalität nach Maximumprinzip aus den Teilprozessen abgeleitet. Abhängigkeiten zeigen, welche Prozesse voneinander bzw. von gemeinsamen Diensten abhängen.</div>
|
||||
</div>
|
||||
<div class="head-actions">
|
||||
<div class="toggle">
|
||||
<button class="active" title="Gruppierte Prozesshaus-Ansicht">▤ Prozesshaus</button>
|
||||
<button title="Klassische Tabelle">≣ Tabelle</button>
|
||||
</div>
|
||||
<button class="btn primary">+ Prozess</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- KPIs -->
|
||||
<div class="kpis">
|
||||
<div class="kpi"><div class="lbl">Prozesse gesamt</div><div class="val">24 <small>/ 6 Haupt</small></div><div class="bar"><i style="width:100%;background:var(--grad-soft)"></i></div></div>
|
||||
<div class="kpi"><div class="lbl">Im Scope</div><div class="val">21 <small>/ 24</small></div><div class="bar"><i style="width:87%;background:var(--violet2)"></i></div></div>
|
||||
<div class="kpi"><div class="lbl">BIA vollständig</div><div class="val">13 <small>/ 21</small></div><div class="bar"><i style="width:62%;background:var(--ok)"></i></div></div>
|
||||
<div class="kpi"><div class="lbl">Kritische Prozesse</div><div class="val" style="color:var(--risk)">4</div><div class="bar"><i style="width:19%;background:var(--risk)"></i></div></div>
|
||||
</div>
|
||||
|
||||
<!-- Legend -->
|
||||
<div class="legend">
|
||||
<div class="grp"><b>BIA-Status:</b></div>
|
||||
<div class="grp"><span class="dot" style="background:var(--ok)"></span> komplett</div>
|
||||
<div class="grp"><span class="dot" style="background:var(--warn)"></span> teilweise</div>
|
||||
<div class="grp"><span class="dot" style="background:#c4c8d2"></span> offen</div>
|
||||
<div class="grp" style="margin-left:8px"><b>Kritikalität:</b></div>
|
||||
<div class="grp"><span class="sw crit-1" style="background:#d3d7e0"></span> 1 niedrig</div>
|
||||
<div class="grp"><span class="sw" style="background:var(--info)"></span> 2 mittel</div>
|
||||
<div class="grp"><span class="sw" style="background:var(--warn)"></span> 3 hoch</div>
|
||||
<div class="grp"><span class="sw" style="background:var(--risk)"></span> 4 kritisch</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ MANAGEMENT ============ -->
|
||||
<div class="lane lane-mgmt">
|
||||
<div class="lane-head"><span class="tag">Managementprozesse</span><span class="cnt">1 Hauptprozess · 3 Teilprozesse</span><span class="rule"></span></div>
|
||||
|
||||
<details class="mp st-teilweise" open>
|
||||
<summary class="mp-head">
|
||||
<svg class="chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M9 6l6 6-6 6"/></svg>
|
||||
<div class="mp-title">
|
||||
<div class="nm">Unternehmenssteuerung & ISMS <span class="tag-cat">Management</span></div>
|
||||
<div class="meta">
|
||||
<span class="owner"><span class="av">GF</span> M. Geschäftsführung</span>
|
||||
<span>·</span><span>3 Teilprozesse</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="metrics">
|
||||
<div class="m"><div class="k">RTO</div><div class="v">24 h</div></div>
|
||||
<div class="m"><div class="k">RPO</div><div class="v">24 h</div></div>
|
||||
<div class="m"><div class="k">MTD</div><div class="v">72 h</div></div>
|
||||
</div>
|
||||
<span class="pill crit-2"><span class="dot" style="background:var(--info)"></span> Krit. 2</span>
|
||||
<span class="pill st-pill teilweise">teilweise</span>
|
||||
</summary>
|
||||
|
||||
<div class="deps">
|
||||
<span class="lab">↳ benötigt:</span>
|
||||
<span class="dep crossref"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M13 6l6 6-6 6"/></svg> IT-Betrieb</span>
|
||||
<span class="dep"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M13 6l6 6-6 6"/></svg> Personalmanagement</span>
|
||||
</div>
|
||||
|
||||
<div class="subs">
|
||||
<div class="subs-h">Teilprozesse</div>
|
||||
<div class="sub">
|
||||
<span class="sdot komplett"></span>
|
||||
<div class="snm"><div class="t">Risikomanagement</div><div class="s"><span>Owner: ISB</span><span>Schnittstelle: Risiko-Modul</span></div></div>
|
||||
<div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">48 h</div></div><div class="m"><div class="k">RPO</div><div class="v">24 h</div></div><div class="m"><div class="k">MTD</div><div class="v">1 W</div></div></div>
|
||||
<div class="right"><span class="pill crit-2">Krit. 2</span></div>
|
||||
</div>
|
||||
<div class="sub">
|
||||
<span class="sdot teilweise"></span>
|
||||
<div class="snm"><div class="t">Interne Audits</div><div class="s"><span>Owner: ISB</span></div></div>
|
||||
<div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">1 W</div></div><div class="m"><div class="k">RPO</div><div class="v">1 W</div></div><div class="m"><div class="k">MTD</div><div class="v">2 W</div></div></div>
|
||||
<div class="right"><span class="pill crit-1">Krit. 1</span></div>
|
||||
</div>
|
||||
<div class="sub">
|
||||
<span class="sdot offen"></span>
|
||||
<div class="snm"><div class="t">Managementbewertung</div><div class="s"><span>Owner: GF</span><span style="color:var(--warn)">BIA offen</span></div></div>
|
||||
<div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">—</div></div><div class="m"><div class="k">RPO</div><div class="v">—</div></div><div class="m"><div class="k">MTD</div><div class="v">—</div></div></div>
|
||||
<div class="right"><span class="mini">BIA erfassen →</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<!-- ============ KERNPROZESSE ============ -->
|
||||
<div class="lane lane-core">
|
||||
<div class="lane-head"><span class="tag">Kernprozesse</span><span class="cnt">2 Hauptprozesse · 8 Teilprozesse</span><span class="rule"></span></div>
|
||||
|
||||
<details class="mp st-komplett" open>
|
||||
<summary class="mp-head">
|
||||
<svg class="chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M9 6l6 6-6 6"/></svg>
|
||||
<div class="mp-title">
|
||||
<div class="nm">Produktentwicklung / Engineering <span class="tag-cat">Kern</span></div>
|
||||
<div class="meta"><span class="owner"><span class="av">HE</span> H. Entwicklung</span><span>·</span><span>4 Teilprozesse</span></div>
|
||||
</div>
|
||||
<div class="metrics">
|
||||
<div class="m"><div class="k">RTO</div><div class="v">8 h</div></div>
|
||||
<div class="m"><div class="k">RPO</div><div class="v">4 h</div></div>
|
||||
<div class="m"><div class="k">MTD</div><div class="v">24 h</div></div>
|
||||
</div>
|
||||
<span class="pill crit-4"><span class="dot" style="background:var(--risk)"></span> Krit. 4</span>
|
||||
<span class="pill st-pill komplett">komplett</span>
|
||||
</summary>
|
||||
|
||||
<div class="deps">
|
||||
<span class="lab">↳ benötigt:</span>
|
||||
<span class="dep crossref"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M13 6l6 6-6 6"/></svg> IT-Betrieb · CAD-Systeme</span>
|
||||
<span class="dep"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M13 6l6 6-6 6"/></svg> Einkauf · Musterteile</span>
|
||||
<span class="dep" style="border-style:dashed;border-color:var(--magenta);color:var(--magenta)">◆ Prototypenschutz</span>
|
||||
</div>
|
||||
|
||||
<div class="subs">
|
||||
<div class="subs-h">Teilprozesse</div>
|
||||
<div class="sub"><span class="sdot komplett"></span><div class="snm"><div class="t">Konstruktion (CAD)</div><div class="s"><span>Owner: H. Entwicklung</span><span>Assets: CAD-Server, PLM</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">8 h</div></div><div class="m"><div class="k">RPO</div><div class="v">4 h</div></div><div class="m"><div class="k">MTD</div><div class="v">24 h</div></div></div><div class="right"><span class="pill crit-4">Krit. 4</span></div></div>
|
||||
<div class="sub"><span class="sdot komplett"></span><div class="snm"><div class="t">Prototypenbau</div><div class="s"><span>Owner: Werkstattleitung</span><span style="color:var(--magenta)">◆ Prototypenschutz</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">1 T</div></div><div class="m"><div class="k">RPO</div><div class="v">8 h</div></div><div class="m"><div class="k">MTD</div><div class="v">3 T</div></div></div><div class="right"><span class="pill crit-3">Krit. 3</span></div></div>
|
||||
<div class="sub"><span class="sdot komplett"></span><div class="snm"><div class="t">Anforderungsmanagement</div><div class="s"><span>Owner: Projektleitung</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">2 T</div></div><div class="m"><div class="k">RPO</div><div class="v">1 T</div></div><div class="m"><div class="k">MTD</div><div class="v">1 W</div></div></div><div class="right"><span class="pill crit-2">Krit. 2</span></div></div>
|
||||
<div class="sub"><span class="sdot teilweise"></span><div class="snm"><div class="t">Erprobung & Test</div><div class="s"><span>Owner: QS</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">2 T</div></div><div class="m"><div class="k">RPO</div><div class="v">1 T</div></div><div class="m"><div class="k">MTD</div><div class="v">1 W</div></div></div><div class="right"><span class="pill crit-2">Krit. 2</span></div></div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="mp st-teilweise">
|
||||
<summary class="mp-head">
|
||||
<svg class="chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M9 6l6 6-6 6"/></svg>
|
||||
<div class="mp-title">
|
||||
<div class="nm">Auftragsabwicklung <span class="tag-cat">Kern</span></div>
|
||||
<div class="meta"><span class="owner"><span class="av">VL</span> Vertriebsleitung</span><span>·</span><span>4 Teilprozesse</span></div>
|
||||
</div>
|
||||
<div class="metrics">
|
||||
<div class="m"><div class="k">RTO</div><div class="v">4 h</div></div>
|
||||
<div class="m"><div class="k">RPO</div><div class="v">1 h</div></div>
|
||||
<div class="m"><div class="k">MTD</div><div class="v">24 h</div></div>
|
||||
</div>
|
||||
<span class="pill crit-4"><span class="dot" style="background:var(--risk)"></span> Krit. 4</span>
|
||||
<span class="pill st-pill teilweise">teilweise</span>
|
||||
</summary>
|
||||
<div class="deps">
|
||||
<span class="lab">↳ benötigt:</span>
|
||||
<span class="dep crossref"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M13 6l6 6-6 6"/></svg> IT-Betrieb · ERP</span>
|
||||
<span class="dep"><svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14M13 6l6 6-6 6"/></svg> Einkauf & Lieferanten</span>
|
||||
</div>
|
||||
<div class="subs">
|
||||
<div class="subs-h">Teilprozesse</div>
|
||||
<div class="sub"><span class="sdot komplett"></span><div class="snm"><div class="t">Fertigung</div><div class="s"><span>Owner: Produktionsleitung</span><span>Assets: MES, Maschinen</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">4 h</div></div><div class="m"><div class="k">RPO</div><div class="v">1 h</div></div><div class="m"><div class="k">MTD</div><div class="v">24 h</div></div></div><div class="right"><span class="pill crit-4">Krit. 4</span></div></div>
|
||||
<div class="sub"><span class="sdot teilweise"></span><div class="snm"><div class="t">Produktionsplanung</div><div class="s"><span>Owner: Arbeitsvorbereitung</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">8 h</div></div><div class="m"><div class="k">RPO</div><div class="v">4 h</div></div><div class="m"><div class="k">MTD</div><div class="v">2 T</div></div></div><div class="right"><span class="pill crit-3">Krit. 3</span></div></div>
|
||||
<div class="sub"><span class="sdot komplett"></span><div class="snm"><div class="t">Versand & Logistik</div><div class="s"><span>Owner: Logistik</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">1 T</div></div><div class="m"><div class="k">RPO</div><div class="v">8 h</div></div><div class="m"><div class="k">MTD</div><div class="v">3 T</div></div></div><div class="right"><span class="pill crit-2">Krit. 2</span></div></div>
|
||||
<div class="sub"><span class="sdot offen"></span><div class="snm"><div class="t">Angebot & Kalkulation</div><div class="s"><span>Owner: Vertrieb</span><span style="color:var(--warn)">BIA offen</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">—</div></div><div class="m"><div class="k">RPO</div><div class="v">—</div></div><div class="m"><div class="k">MTD</div><div class="v">—</div></div></div><div class="right"><span class="mini">BIA erfassen →</span></div></div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<!-- ============ UNTERSTÜTZEND ============ -->
|
||||
<div class="lane lane-supp">
|
||||
<div class="lane-head"><span class="tag">Unterstützende Prozesse</span><span class="cnt">3 Hauptprozesse · 8 Teilprozesse</span><span class="rule"></span></div>
|
||||
|
||||
<details class="mp st-komplett" open>
|
||||
<summary class="mp-head">
|
||||
<svg class="chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M9 6l6 6-6 6"/></svg>
|
||||
<div class="mp-title">
|
||||
<div class="nm">IT-Betrieb <span class="tag-cat">Support</span> <span class="pill" style="background:var(--violet-050);color:var(--violet);border:1px dashed var(--violet2)">▲ 3 Prozesse hängen hiervon ab</span></div>
|
||||
<div class="meta"><span class="owner"><span class="av">IT</span> IT-Leitung</span><span>·</span><span>4 Teilprozesse</span></div>
|
||||
</div>
|
||||
<div class="metrics">
|
||||
<div class="m"><div class="k">RTO</div><div class="v">4 h</div></div>
|
||||
<div class="m"><div class="k">RPO</div><div class="v">1 h</div></div>
|
||||
<div class="m"><div class="k">MTD</div><div class="v">24 h</div></div>
|
||||
</div>
|
||||
<span class="pill crit-4"><span class="dot" style="background:var(--risk)"></span> Krit. 4</span>
|
||||
<span class="pill st-pill komplett">komplett</span>
|
||||
</summary>
|
||||
<div class="deps">
|
||||
<span class="lab">▲ wird benötigt von:</span>
|
||||
<span class="dep crossref">Produktentwicklung</span>
|
||||
<span class="dep crossref">Auftragsabwicklung</span>
|
||||
<span class="dep crossref">Unternehmenssteuerung</span>
|
||||
</div>
|
||||
<div class="subs">
|
||||
<div class="subs-h">Teilprozesse</div>
|
||||
<div class="sub"><span class="sdot komplett"></span><div class="snm"><div class="t">Netzwerk & Infrastruktur</div><div class="s"><span>Owner: Netzwerkadmin</span><span>Assets: Core-Switch, FW</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">4 h</div></div><div class="m"><div class="k">RPO</div><div class="v">1 h</div></div><div class="m"><div class="k">MTD</div><div class="v">24 h</div></div></div><div class="right"><span class="pill crit-4">Krit. 4</span></div></div>
|
||||
<div class="sub"><span class="sdot komplett"></span><div class="snm"><div class="t">Backup & Recovery</div><div class="s"><span>Owner: IT-Betrieb</span><span>VA-08</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">8 h</div></div><div class="m"><div class="k">RPO</div><div class="v">1 h</div></div><div class="m"><div class="k">MTD</div><div class="v">24 h</div></div></div><div class="right"><span class="pill crit-4">Krit. 4</span></div></div>
|
||||
<div class="sub"><span class="sdot komplett"></span><div class="snm"><div class="t">Client-/Server-Betrieb</div><div class="s"><span>Owner: IT-Betrieb</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">8 h</div></div><div class="m"><div class="k">RPO</div><div class="v">4 h</div></div><div class="m"><div class="k">MTD</div><div class="v">2 T</div></div></div><div class="right"><span class="pill crit-3">Krit. 3</span></div></div>
|
||||
<div class="sub"><span class="sdot teilweise"></span><div class="snm"><div class="t">Berechtigungsverwaltung</div><div class="s"><span>Owner: IT + ISB</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">1 T</div></div><div class="m"><div class="k">RPO</div><div class="v">8 h</div></div><div class="m"><div class="k">MTD</div><div class="v">3 T</div></div></div><div class="right"><span class="pill crit-3">Krit. 3</span></div></div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="mp st-offen">
|
||||
<summary class="mp-head">
|
||||
<svg class="chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4"><path d="M9 6l6 6-6 6"/></svg>
|
||||
<div class="mp-title">
|
||||
<div class="nm">Einkauf & Lieferantenmanagement <span class="tag-cat">Support</span></div>
|
||||
<div class="meta"><span class="owner"><span class="av">EK</span> Einkaufsleitung</span><span>·</span><span>2 Teilprozesse</span><span>·</span><span style="color:var(--warn)">BIA offen</span></div>
|
||||
</div>
|
||||
<div class="metrics">
|
||||
<div class="m"><div class="k">RTO</div><div class="v">—</div></div>
|
||||
<div class="m"><div class="k">RPO</div><div class="v">—</div></div>
|
||||
<div class="m"><div class="k">MTD</div><div class="v">—</div></div>
|
||||
</div>
|
||||
<span class="pill crit-1"><span class="dot" style="background:#c4c8d2"></span> offen</span>
|
||||
<span class="pill st-pill offen">offen</span>
|
||||
</summary>
|
||||
<div class="subs">
|
||||
<div class="subs-h">Teilprozesse</div>
|
||||
<div class="sub"><span class="sdot offen"></span><div class="snm"><div class="t">Lieferantenauswahl</div><div class="s"><span>Owner: Einkauf</span><span style="color:var(--warn)">BIA offen</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">—</div></div><div class="m"><div class="k">RPO</div><div class="v">—</div></div><div class="m"><div class="k">MTD</div><div class="v">—</div></div></div><div class="right"><span class="mini">BIA erfassen →</span></div></div>
|
||||
<div class="sub"><span class="sdot offen"></span><div class="snm"><div class="t">Wareneingang / QS</div><div class="s"><span>Owner: QS</span><span style="color:var(--warn)">BIA offen</span></div></div><div class="metrics"><div class="m"><div class="k">RTO</div><div class="v">—</div></div><div class="m"><div class="k">RPO</div><div class="v">—</div></div><div class="m"><div class="k">MTD</div><div class="v">—</div></div></div><div class="right"><span class="mini">BIA erfassen →</span></div></div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div class="note">
|
||||
<b>Was ist neu ggü. der heutigen Ansicht?</b> Statt einer flachen Tabelle aller Prozesse werden sie nach <b>Prozesskategorie</b> (Management / Kern / Support) gruppiert und in <b>Haupt- → Teilprozesse</b> aufgeklappt. Jeder Hauptprozess rollt Kritikalität (Maximumprinzip) und die schärfsten RTO/RPO/MTD-Werte seiner Teilprozesse zusammen. <b>Abhängigkeiten</b> („↳ benötigt" / „▲ wird benötigt von") machen sichtbar, welche Prozesse auf gemeinsame Dienste wie den IT-Betrieb angewiesen sind — ein Ausfall dort trifft alle abhängigen Prozesse. Datenbasis ist bereits vorhanden (<code>Process.parentId</code>, <code>category</code>, <code>biaStatus</code>, <code>BiaEntry</code>); es ist reine Darstellung, kein Datenmodell-Umbau.
|
||||
</div>
|
||||
<div class="foot">Mockup · certvia BIA-Prozessübersicht · Beispieldaten (GEFIM) · nicht verbindlich</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,67 @@
|
||||
# Onboarding-Prompt für einen neuen Claude-Code-Agenten
|
||||
|
||||
> Diesen Prompt dem neuen Agenten als erste Nachricht geben. Er enthält bewusst **keinen**
|
||||
> inhaltlichen Projektstand — der steht in `docs/STAND-dev-branch.md` und wird nur dort
|
||||
> gepflegt (kein doppelter, veraltender Stand im Prompt).
|
||||
|
||||
---
|
||||
|
||||
```text
|
||||
Du übernimmst die Weiterentwicklung des ISMS-Tools (Multi-Tenant-SaaS für
|
||||
ISO 27001:2022 / TISAX / VDA-ISA 2027). Mach dich zuerst mit dem Stand vertraut.
|
||||
Beginne noch KEINE Aufgabe — lies ein, bestätige dein Verständnis und warte dann
|
||||
auf meine Anweisung.
|
||||
|
||||
## Repo & Umgebung
|
||||
- Arbeitsverzeichnis: das lokale Repo `ISMS-Tool` (kein Gitea-/Remote-Zugang!).
|
||||
- Du kannst NICHT pushen. Arbeite auf Branch `dev`, committe lokal. Pushen mache ich selbst.
|
||||
Prüfe mit `git branch --show-current`, dass du auf `dev` bist (NICHT `main`).
|
||||
- Stack: Next.js 16 (App Router, Turbopack, Server Actions), React 19, TypeScript strict,
|
||||
Prisma 7 (+ @prisma/adapter-pg), PostgreSQL + pgvector, NextAuth v5, Tailwind.
|
||||
|
||||
## Zuerst lesen (in dieser Reihenfolge) — das ist die maßgebliche Statusquelle
|
||||
1. `docs/STAND-dev-branch.md` — konsolidierter Gesamtstand (PM + Technik): was fertig/offen
|
||||
ist, wo was liegt, Datenmodelle, Migrationen, Fallstricke, Demo-Logins.
|
||||
2. `docs/HANDOVER-DEV.md` — Setup, Stack, Konventionen, Migrations-Flow (§1–§10).
|
||||
3. `docs/SPEC.md` — fachliche Spezifikation.
|
||||
Verlasse dich auf diese Dokumente statt zu raten. Den inhaltlichen Projektstand NICHT aus
|
||||
diesem Prompt ableiten — er steht ausschließlich in der Doku (Single Source of Truth).
|
||||
|
||||
## Arbeitskonventionen (verbindlich)
|
||||
- Commits auf Deutsch, granular pro Thema, mit Trailer:
|
||||
`Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>`
|
||||
- Neue mutierende Server-Action → über `moduleGuard("<key>")` und in
|
||||
`scripts/check-module-guards.ts` eintragen (sonst failt der Build).
|
||||
- Neue mandantengebundene Prisma-Modelle → in `TENANT_MODELS` (`src/server/db.ts`)
|
||||
UND RLS-Policy in der Migration (`tenant_isolation` via `current_setting('app.tenant_id')`).
|
||||
- Migrations-Flow Prisma 7:
|
||||
`npx prisma migrate diff --from-config-datasource prisma.config.ts --to-schema prisma/schema.prisma --script`
|
||||
→ RLS-DO-Block manuell anhängen → `npx prisma migrate deploy` → `npx prisma generate`.
|
||||
(tsx-Skripte brauchen `import "dotenv/config"`.)
|
||||
- Zentrale Richtlinien-Variablen (Organisation/Rollen/Schutzbedarf) sind nur in `/settings`
|
||||
pflegbar und serverseitig geschützt — nicht im Richtlinien-Editor.
|
||||
- Editier-UIs immer als Popup/Modal (Muster: Assets/Lieferanten/Software/Projekte).
|
||||
- Doku mitpflegen: Nach jeder abgeschlossenen Arbeit `docs/STAND-dev-branch.md`
|
||||
aktualisieren (Executive Summary, PM-Statustabelle, ggf. neue Modelle/Migrationen,
|
||||
„Wo liegt was", Commit-Übersicht, offene Punkte). Das ist die Single Source of Truth —
|
||||
sie muss den `dev`-Stand jederzeit korrekt widerspiegeln. Der Doku-Update gehört in einen
|
||||
eigenen Commit (oder denselben Themen-Commit), nicht separat vergessen.
|
||||
|
||||
## Jede Iteration abschließen mit
|
||||
`npx tsc --noEmit` → `npm run lint` → `npm run build` (führt `prebuild`-Guard-Check aus).
|
||||
Bei Änderungen am Vorlagenpaket zusätzlich `python3 seed/isms-vorlagenpaket-v2/_verify.py`
|
||||
(muss `OK` liefern). Wo im Browser sichtbar: Dev-Server (`npm run dev`, Port 3000) und selbst
|
||||
verifizieren — nicht den Nutzer manuell prüfen lassen. Hinweis: geänderte Server-Actions
|
||||
greifen im Turbopack-Dev teils erst nach Neustart des Dev-Servers. Voraussetzung: lokale
|
||||
Postgres-DB läuft und `.env` mit `DATABASE_URL` ist vorhanden (siehe HANDOVER-DEV.md).
|
||||
|
||||
## Lokale Demo-Daten
|
||||
Seed: `npx tsx prisma/seed.ts` (idempotent). Demo-Logins Passwort `Demo1234!`:
|
||||
`admin@demo.example` (Mandanten-Admin+ISB), `bea.approver@demo.example` (2. Freigeber für
|
||||
Vier-Augen), `auditor@`, `owner@`, `user@`. Plattform-Login unter `/platform/login`.
|
||||
|
||||
## Ablauf jetzt
|
||||
Lies die drei Dokumente, fasse mir in wenigen Sätzen zusammen, was der aktuelle Stand ist
|
||||
und was als Nächstes offen wäre, und WARTE dann auf meine konkrete Aufgabe. Fang nichts
|
||||
Eigenes an. Bei Unklarheiten: gezielt nachfragen.
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
# Kickoff-Prompt — Lane Konfigurierbarer Backup-Zielspeicher (certvia)
|
||||
|
||||
> Diesem Prompt einem Entwickler/Claude-Code-Agenten geben. Bootstrapt in certvia + diese Lane.
|
||||
|
||||
```text
|
||||
Du übernimmst die Lane „Konfigurierbarer Backup-Zielspeicher" am Produkt „certvia" (ISMS-Tool,
|
||||
Multi-Tenant Next.js-16 / Prisma-7 / Postgres+RLS / Auth.js-v5). Repo: ~/Projects/ISMS-Tool, Branch `dev`.
|
||||
|
||||
WICHTIG: certvia ist strikt getrennt von jedem anderen Produkt (insb. „visitvia"). Nichts vermischen.
|
||||
|
||||
BRANCH/CHECKOUT:
|
||||
Arbeits-Branch: `lane-backup-target` (KEIN `feature/`-Prefix — origin-Namespace-Konflikt).
|
||||
git fetch origin && git checkout dev && git checkout -b lane-backup-target.
|
||||
Remotes: origin = https://git.certvia.de/msolarczek/certvia.git · local-gitea (intern).
|
||||
|
||||
1) PFLICHTLEKTÜRE:
|
||||
- docs/HANDOVER-DEV.md, docs/SPEC.md, docs/STAND-dev-branch.md
|
||||
- docs/KONZEPT-backup-target.md ← dein Fahrplan
|
||||
- docs/KONZEPT-backup-restore.md §9 ← Verschlüsselung/Secrets-Kohärenz
|
||||
- Bestand ansehen: src/server/storage/backup-store.ts (BackupStore, S3-/Local-Store, createBackupStore)
|
||||
|
||||
2) AUFTRAG:
|
||||
Den Backup-Zielspeicher im Betreiber-Portal konfigurierbar machen + lokale (persistente) Option.
|
||||
a) DATENMODELL: PlatformSetting erweitern (backupTarget local|s3, backupLocalDir, backupS3Endpoint/
|
||||
Bucket/Region/AccessKey, backupS3SecretKeyEnc). Additive Migration (nullable, Default local).
|
||||
b) FACTORY: statisches `backupStore` → `getBackupStore(): Promise<BackupStore>`, liest PlatformSetting,
|
||||
entschlüsselt den S3-Key (secret-crypto). Präzedenz DB → Env (S3_*/BACKUP_LOCAL_DIR) → lokaler
|
||||
Default `.backups`. Cachen + bei Settings-Änderung invalidieren. Die 3 Nutzer umstellen:
|
||||
src/server/backup/export.ts, restore.ts, ops.ts.
|
||||
c) UI: Seite im Plattform-Portal (z. B. /admin/backup): Ziel wählen (Lokal/S3), Config, „Verbindung
|
||||
testen" (Probe put/get/remove). Gated requirePlatformFullAdmin + MFA-Step-up. Speichern via Action
|
||||
analog setPlatformMfaRequired (platformSetting.upsert); S3-Secret VOR dem Schreiben verschlüsseln.
|
||||
d) PERSISTENZ: docker-compose.coolify.yml — persistentes Volume `backups:` (wie pgdata/miniodata) in
|
||||
app+worker mounten (Pfad = backupLocalDir, z. B. /app/.backups).
|
||||
e) TESTS: scripts/test-backup-* erweitern (Store-Auflösung DB local/s3, Präzedenz, Test-Verbindung,
|
||||
fail-secure bei unvollständiger S3-Config, Export→Restore gegen beide Backends).
|
||||
|
||||
3) VERBINDLICHE REGELN:
|
||||
- S3-Secret NUR verschlüsselt in der DB (src/server/secret-crypto.ts: encryptSecret/decryptSecret) — nie Klartext.
|
||||
- Fail-secure: backupTarget=s3 mit unvollständiger Config → klarer Fehler, NICHT still auf lokal fallen.
|
||||
- Env-Fallback erhalten (Rückwärtskompatibilität bestehender Deployments).
|
||||
- BACKUP_ENC_KEY (Artefakt-Verschlüsselung) bleibt GETRENNT vom Zielspeicher — nicht vermischen.
|
||||
- RLS/Mandanten-Isolation der Artefakt-Keys (`<tenantId>/backups/…`) unverändert lassen.
|
||||
- Config-Bearbeitung nur Full-Admin + Step-up, auditiert.
|
||||
|
||||
4) ARBEITSWEISE:
|
||||
- Gate vor JEDEM Merge: npx tsc --noEmit · npm run lint · npm run build · ALLE scripts/test-*.ts.
|
||||
- migrate reset gegen lokale DB braucht Nutzer-Zustimmung (Prisma-Guard).
|
||||
- UI im Browser verifizieren: Ziel umschalten Lokal↔S3, „Verbindung testen", Export→Restore lokal.
|
||||
- DevOps: lane-backup-target → git merge --no-ff nach dev → Gate grün → Push auf BEIDE Remotes →
|
||||
docs/STAND-dev-branch.md pflegen.
|
||||
|
||||
5) NICHT TUN: kein Umbau am Auth-/RLS-Kern; keine Mehrfachziele/Offsite-Profile (Phase 2); Artefakt-
|
||||
Verschlüsselung (crypto.ts) nicht anfassen.
|
||||
|
||||
Erste Schritte: (a) Pflichtlektüre + backup-store.ts lesen, 10-Zeilen-Zusammenfassung + Fragen,
|
||||
(b) PR-Plan (Schema+Migration, getBackupStore-Refactor, UI, Compose-Volume, Tests), (c) nach Freigabe
|
||||
umsetzen. Warte nach (a)/(b) auf Bestätigung.
|
||||
```
|
||||
@@ -0,0 +1,57 @@
|
||||
# Kickoff-Prompt — Lane Backup/Restore/DSGVO (certvia)
|
||||
|
||||
> Diesem Prompt einem Entwickler/Claude-Code-Agenten geben. Bootstrapt in certvia + diese Lane.
|
||||
|
||||
```text
|
||||
Du übernimmst die Lane „Datensicherung, Wiederherstellung & DSGVO" am Produkt „certvia"
|
||||
(ISMS-Tool, Multi-Tenant Next.js-16 / Prisma-7 / Postgres+RLS / Auth.js-v5). Repo:
|
||||
~/Projects/ISMS-Tool, Integrationsbranch `dev`.
|
||||
|
||||
WICHTIG: certvia ist strikt getrennt von jedem anderen Produkt (insb. „visitvia"). Nichts vermischen.
|
||||
|
||||
BRANCH/CHECKOUT:
|
||||
Arbeits-Branch: `lane-backup` (KEIN `feature/`-Prefix — auf origin blockiert der Branch
|
||||
`feature` diesen Namespace). Aus `dev` erstellen: git fetch origin && git checkout dev &&
|
||||
git checkout -b lane-backup.
|
||||
Remotes: origin = https://git.certvia.de/msolarczek/certvia.git · local-gitea (intern).
|
||||
|
||||
1) PFLICHTLEKTÜRE (erst lesen, nicht sofort coden):
|
||||
- docs/HANDOVER-DEV.md, docs/SPEC.md, docs/STAND-dev-branch.md
|
||||
- docs/KONZEPT-backup-restore.md ← dein Fahrplan (Schicht A/B, Portal, DSGVO, §9 Verschlüsselung)
|
||||
- docs/KONZEPT-haertung.md §3 ← operativer Bezug „verschlüsselte Backups"
|
||||
|
||||
2) AUFTRAG (Phasen aus dem Konzept §11):
|
||||
(1) Schicht A: pgBackRest/wal-g + PITR, client-seitig AES-256 (§9) — Ops-nah, sofort möglich.
|
||||
(2) Tenant-scoped Export/Restore-Engine über TENANT_MODELS (FK-Reihenfolge), REPEATABLE READ.
|
||||
(3) Betreiber-Portal-Restore (Worker-Job, Kontrollen §4/§10).
|
||||
(4) DSGVO-Export (per-Mandant + per-Person).
|
||||
(5) DSGVO-Löschung (Anonymisieren vs. Hard-Delete + Löschnachweis + Tombstone-on-Restore).
|
||||
|
||||
3) VERBINDLICHE REGELN:
|
||||
- Engine läuft über den Owner-`prisma`-Client (BYPASSRLS), NIE den RLS-Client.
|
||||
- Jede Operation `tenant_id`-gescopt (Export SELECT, Restore DELETE+INSERT, Löschung) →
|
||||
beweisbar keine Fremdmandanten berührt. cuid-PKs: Reinsert kollisionsfrei.
|
||||
- `Identity` ist GLOBAL: Tenant-Restore holt Mitgliedschaften (`User`), NICHT den globalen
|
||||
Credential-Store (der liegt in Schicht A). Fehlende Identity beim Reinsert sauber behandeln.
|
||||
- Verschlüsselung = §9-Primitiv: client-seitig AES-256, Keys pro Umgebung. Backup-Artefakte
|
||||
enthalten KEINE Umgebungs-Secrets (Pepper/MFA_ENC_KEY) → Restore-Kohärenz dokumentieren.
|
||||
- MinIO-Dateien (Prefix je Mandant) gehören zu Export/Restore/Löschung dazu.
|
||||
- Destruktive Portal-Aktionen: requirePlatformFullAdmin + MFA-Step-up + getippte Bestätigung
|
||||
+ Mandant-Sperre + Pre-Restore-Snapshot + Audit.
|
||||
|
||||
4) ARBEITSWEISE:
|
||||
- Gate vor JEDEM Merge: npx tsc --noEmit · npm run lint · npm run build · ALLE scripts/test-*.ts.
|
||||
Jede Story bringt ihren Test mit (Isolation: Restore/Export/Löschung berührt nur den Zielmandanten).
|
||||
- DevOps: lane-backup → git merge --no-ff nach dev → Gate grün → Push auf BEIDE Remotes →
|
||||
docs/STAND-dev-branch.md pflegen.
|
||||
|
||||
5) KOORDINATION:
|
||||
- §9-Verschlüsselung ist gemeinsam mit Lane Härtung: Mechanismus/Keys sind entschieden
|
||||
(client-seitig AES-256, Keys pro Umgebung) — nur EINMAL abstimmen, dann unabhängig.
|
||||
- prisma migrate reset gegen Test/Coolify braucht Nutzer-Zustimmung (Prisma-Guard).
|
||||
|
||||
6) NICHT TUN: keine Änderung am Auth-/RLS-Kern; TENANT_MODELS bleibt Quelle der tenant-Tabellen.
|
||||
|
||||
Erste Schritte: (a) Pflichtlektüre + 10-Zeilen-Zusammenfassung/Fragen, (b) FK-Reihenfolge aus
|
||||
TENANT_MODELS ableiten + Engine-PR-Plan skizzieren, (c) nach Freigabe umsetzen. Warte nach (a)/(b).
|
||||
```
|
||||
@@ -0,0 +1,120 @@
|
||||
# Kickoff-Prompt — B1: Assessment und Readiness für zwei Frameworks
|
||||
|
||||
Du baust die **Bewertungs- und Readiness-Schicht** für ISO 27001 neben TISAX. Alles andere steht bereits: Der Dokumentensatz trägt beide Normen, `mapping-iso.json` liefert 120 ISO-Anforderungen, die Framework-Dimension im Datenmodell ist gebaut (AP1–AP5), ein ISO-Mandant hat SoA, Kennzahlen, Managementbewertung und Korrekturmaßnahmen.
|
||||
|
||||
**Was fehlt:** `maturity.ts`, `scope-filter.ts`, `assessment-level.ts` und `readiness.ts` kennen kein Framework und rechnen durchgängig VDA ISA — AL2/AL3, Prüfziele, Reifegrad 0–3, MUSS/SOLL. Der belegte Bruch: `src/server/soa-context.ts:151` und `src/server/export-context.ts:49` lesen `controlAssessment`; **keine einzige Stelle liest `soaEntry`**. Das SoA-Modul ist von der Auswertung abgekoppelt.
|
||||
|
||||
**Pflichtlektüre vor der ersten Zeile Code:** `docs/FEINDESIGN-framework-assessment.md` — vollständig, insbesondere §1 (Leitentscheidung) und §7a (Priorisierung). Hintergrund: `docs/FRAMEWORK-MAPPING-ISO27001.md`, `docs/UEBERGABE-framework-iso27001.md`.
|
||||
|
||||
## Repo & Branch
|
||||
- **origin:** `git.certvia.de/msolarczek/certvia`; zweiter Remote `local-gitea`.
|
||||
- **Basis ist `feature/iso27001-framework-mapping`**, nicht `dev`.
|
||||
- Arbeite auf `feature/framework-assessment`, PR gegen den Basis-Branch.
|
||||
|
||||
## Kundenlage — sie bestimmt, was jetzt gebaut wird
|
||||
|
||||
Die Mehrzahl der Mandanten führt **TISAX**, **ein** Mandant **ISO**, **keiner beide**.
|
||||
|
||||
Daraus folgt: **Das Regressionsrisiko dominiert dieses Paket.** Der gefährlichste Teil ist nicht die ISO-Logik — die ist schlank — sondern die verhaltensgleiche Extraktion der bestehenden TISAX-Logik. Sie betrifft jeden Bestandsmandanten. Schritt 1 ist deshalb keine Kür.
|
||||
|
||||
**Zurückgestellt** (betrifft ausschließlich den Doppel-Mandanten, den es heute nicht gibt):
|
||||
- Vorbelegung über `ISO_TO_ISA` (Übernahmevorschlag zwischen den Frameworks)
|
||||
- Reiter-UI in `/soa` und `/audit-readiness` — bei einem aktiven Framework wird direkt angezeigt
|
||||
|
||||
**Nicht zurückstellen:** die **Strategie-Schnittstelle** und den **Framework-Parameter** in `buildAssessment`. Beides kostet jetzt fast nichts und ist später teuer, weil sonst sieben Aufrufstellen erneut angefasst werden. Die Architektur bleibt zweigleisig, die Oberfläche zeigt vorerst ein Gleis.
|
||||
|
||||
## Die eine Leitentscheidung
|
||||
|
||||
**Die Belegbasis liegt unterhalb der Framework-Strategie.** Ob R08 freigegeben ist, ist eine Tatsache über die Organisation, keine Frage der Norm. `ControlEvidence` (`src/lib/maturity.ts:54`) wird geteilt; nur Scope, Zielwert, Bewertung und Vokabular sind framework-eigen.
|
||||
|
||||
```
|
||||
Schicht 3 Sichten /soa · /audit-readiness · Exporte → je Framework (Reiter später)
|
||||
Schicht 2 Strategie Scope · Zielwert · Bewertung → je Framework
|
||||
Schicht 1 Belegbasis loadEvidenceResolver → ControlEvidence → GETEILT
|
||||
Schicht 0 Fachdaten PolicyDocument · Evidence · Asset … → GETEILT
|
||||
```
|
||||
|
||||
**Review-Kriterium, hart:** `loadEvidenceResolver` darf `FrameworkKey` nicht kennen. Sobald die Belegauflösung anfängt, das Framework zu fragen, ist der Schnitt gerissen und wir bekommen zwei Bewertungen derselben Realität, die auseinanderlaufen.
|
||||
|
||||
## Nicht anfassen
|
||||
|
||||
- **`seed/isms-vorlagenpaket-v2/**` und `-en/**`** — generiert. Änderungen nur über `_iso_crosswalk.json` / `_iso_sections.json` / `_iso_texts_en.json` + `python3 _generate_iso.py [--lang en]`.
|
||||
- **Die VDA-ISA-Fachlogik inhaltlich** — `suggestMaturity`, `targetMaturity`, `openPoints`, `activeRequirements` werden **verschoben, nicht verändert**.
|
||||
- **`readiness.ts` und `gap-consolidation.ts`** — numerisch standard-agnostisch, werden von beiden Strategien gefüttert.
|
||||
|
||||
## Arbeitsschritte
|
||||
|
||||
### 1 — Snapshot der heutigen TISAX-Ausgabe *(zuerst, vor jeder Änderung)*
|
||||
`buildControlRows` für den Demo-Mandanten festhalten: Reifegradvorschlag, Zielwert, Belegstatus und offene Punkte je Control, als JSON im Repo. Ablage als `scripts/test-framework-assessment.ts` in der Hausform der übrigen `test-*.ts`.
|
||||
**DoD:** Test läuft grün gegen den unveränderten Stand und ist als Merge-Gate gesetzt.
|
||||
|
||||
### 2 — `ControlSpec` einführen
|
||||
`C5ControlSpec` (`src/lib/maturity.ts:16`) auf ein neutrales `ControlSpec` reduzieren (`control`, `title`, `policy[]`, `verfahren[]`, `needsAsset`, `needsRisk`); `C5ControlSpec` erweitert es um `target`. `loadEvidenceResolver` (`src/server/soa-context.ts:50`) nimmt künftig `ControlSpec`.
|
||||
**DoD:** Snapshot unverändert grün, `tsc` sauber.
|
||||
|
||||
### 3 — ISO-Specs generieren
|
||||
`_generate_iso.py` erzeugt zusätzlich `src/lib/control-specs-iso.ts` — analog zu `control-titles-iso.ts` und `iso-isa-crosswalk.ts`. Quelle ist `mapping-iso.json` (`policy` und `verfahren` stehen dort je Anforderung); `needsAsset`/`needsRisk` über `ISO_TO_ISA` vom ISA-Spec erben, für die 33 ISO-eigenen Abschnitte explizit setzen — sinnvoll nur bei A.5.9 (`needsAsset`) sowie 6.1.2/6.1.3/8.2/8.3 (`needsRisk`).
|
||||
**DoD:** Generator idempotent, `_verify_iso.py` DE und EN grün, keine handgepflegte Zweitliste.
|
||||
|
||||
### 4 — `FrameworkStrategy` + `TisaxStrategy` *(reine Extraktion)*
|
||||
Interface nach §3 des Feindesigns. `TisaxStrategy` verdrahtet die vorhandenen Funktionen um: `loadScopeInput` + `controlsInScope` → `controlsInScope`, `suggestMaturity` + `targetMaturity` → `evaluate`, `openPoints` → `gaps`, `computeReadiness` → `summarise`.
|
||||
**DoD:** Snapshot bitgenau grün. Jede Abweichung ist eine Regression, kein „ist besser geworden".
|
||||
|
||||
### 5 — `IsoStrategy`
|
||||
| Aspekt | Regel |
|
||||
|---|---|
|
||||
| Scope | `SoaEntry.applicable = true`; Klauseln 4–10 immer im Scope |
|
||||
| Zielwert | `implementationStatus = "umgesetzt"`, keine Stufung |
|
||||
| Vorschlag | Richtlinie *und* Verfahren `validiert` + geforderte Verknüpfungen → `umgesetzt`; teilweise → `teilweise`; sonst `geplant` |
|
||||
| Bestätigung | `SoaEntry.implementationStatus`; der Vorschlag überschreibt ihn nie |
|
||||
| Lücken | fehlende Begründung, fehlender Nachweis, Status ≠ „umgesetzt" bei anwendbarem Control |
|
||||
|
||||
**DoD:** ISO-Mandant bekommt eine Bewertung über alle anwendbaren Controls; leere SoA meldet „Anwendbarkeit noch nicht erklärt" statt 0 %.
|
||||
|
||||
### 6 — `buildAssessment(db, tenantId, framework)`
|
||||
Ersetzt `buildControlRows` (`src/server/soa-context.ts:146`) und delegiert an die Strategie. Sieben Dateien rufen es direkt; insgesamt hängen 13 an der Assessment-Logik.
|
||||
**DoD:** Alle Aufrufstellen umgestellt, Snapshot grün, `tsc`/`lint`/`build` grün.
|
||||
|
||||
### 7 — ISO-Readiness-Bänder und Beschriftung
|
||||
`REIFEGRAD_BANDS` (`src/lib/readiness.ts:16`) ist TISAX-Sprache („Assessment-reif", „AL-Ziel"). ISO bekommt eigene Bänder auf Basis des Umsetzungsgrads: < 50 % Aufbau · 50–79 % In Umsetzung · 80–99 % Zertifizierungsnah · 100 % Zertifizierungsreif.
|
||||
**DoD:** In der ISO-Sicht erscheint kein AL-, Prüfziel- oder Reifegradbegriff. Ein ISO-Bericht argumentiert mit „umgesetzt, hier ist der Beleg", nicht mit „Reifegrad 2,4".
|
||||
|
||||
### 8 — ISO-Exporte
|
||||
SoA-Export und Annex-A-Gap-Report. Der VDA-ISA-Export bleibt TISAX-only und unverändert.
|
||||
**DoD:** Der ISO-Mandant kann die Eingaben für seine Managementbewertung aus dem Tool ziehen.
|
||||
|
||||
**Zusatznutzen, bitte mitnehmen:** Die 33 ISO-Anforderungen ohne ISA-Gegenstück als eigene Liste ausweisbar machen. Das ist genau die Delta-Arbeit, die ISO gegenüber TISAX zusätzlich verlangt — die erste Frage jedes TISAX-Kunden, der über ISO nachdenkt.
|
||||
|
||||
## Validierungs-Gate vor jedem PR
|
||||
|
||||
```bash
|
||||
npx tsc --noEmit && npm run lint && npm run build
|
||||
npx tsx scripts/test-framework-assessment.ts # Snapshot TISAX → 0 Abweichungen
|
||||
npx tsx scripts/test-framework-dryrun.ts # Paket + Import → alle Prüfungen bestanden
|
||||
cd seed/isms-vorlagenpaket-v2
|
||||
python3 _generate_iso.py && python3 _generate_iso.py --lang en # beide idempotent
|
||||
python3 _verify.py && python3 _verify_iso.py && python3 _verify_iso.py --lang en
|
||||
python3 _render_diff.py HEAD # TISAX-Renderdiff → 0 Abweichungen
|
||||
```
|
||||
|
||||
Weitere Konventionen: Migrationsflow Prisma 7 mit manuell angehängtem RLS-DO-Block (`docs/HANDOVER-DEV.md:100`); neue mandantengebundene Modelle in `TENANT_MODELS` (`src/server/db.ts:81`) **und** RLS-Policy in der Migration; jede neue Datei unter `src/server/actions/` in `scripts/check-module-guards.ts` eintragen, sonst schlägt der Build fehl.
|
||||
|
||||
## Definition of Done (gesamt)
|
||||
|
||||
| Prüfung | Erwartung |
|
||||
|---|---|
|
||||
| Snapshot TISAX | 0 Abweichungen zur Ausgabe vor dem Umbau |
|
||||
| Bestandsmandant (TISAX) | Verhalten und Beschriftung unverändert |
|
||||
| ISO-Mandant | Readiness und SoA rechnen; kein TISAX-Vokabular in der Oberfläche |
|
||||
| Architektur | Strategie-Schnittstelle und Framework-Parameter vorhanden, auch wenn die UI nur ein Gleis zeigt |
|
||||
| Belegbasis | `loadEvidenceResolver` kennt `FrameworkKey` nicht |
|
||||
| Kennzahlen | je Framework eine eigene, **keine** gemischte Gesamtzahl |
|
||||
| Gate | alle Prüfungen oben grün |
|
||||
|
||||
## Aufwand
|
||||
|
||||
4–6 PT im vorgezogenen Umfang. Schritte 1–4 hängen aneinander und sind Pflicht; 5–8 sind danach teilbar. Schwerpunkt liegt auf Schritt 4, nicht auf der ISO-Logik.
|
||||
|
||||
## Nicht dein Scope
|
||||
|
||||
Vorbelegung zwischen den Frameworks und die Reiter-UI (siehe Kundenlage). Ebenso Paket- und Freigabearbeit: `REVIEW_CYCLE`-Split an 32 Bestandsstellen, ISB-Freigabe der 19 ISO-Abschnittstexte, Review des Crosswalks.
|
||||
@@ -0,0 +1,151 @@
|
||||
# Kickoff-Prompt — Framework-Dimension: ISO 27001 neben TISAX
|
||||
|
||||
Du übernimmst den **Anwendungsumbau** für die Mehr-Framework-Fähigkeit. Die **Inhaltsseite ist fertig**: `seed/isms-vorlagenpaket-v2` trägt seit Branch `feature/iso27001-framework-mapping` **zwei Framework-Mappings auf einem Dokumentensatz** — `mapping.json` (VDA ISA, 321 Anforderungen) und `mapping-iso.json` (ISO/IEC 27001:2022, 120 Anforderungen). Die Anwendung kennt das zweite Mapping nicht: `parsePackageFiles` liest `mapping.json` fest verdrahtet.
|
||||
|
||||
**Pflichtlektüre vor der ersten Zeile Code:** `docs/UEBERGABE-framework-iso27001.md` — insbesondere **§1 „Die vier Fallen"**. Hintergrund und Begründung der Entscheidung: `docs/FRAMEWORK-MAPPING-ISO27001.md`. Gesamtarchitektur: `docs/KONZEPT-framework-iso27001.md` (D4 und Lane 2 sind dort per Nachtrag korrigiert).
|
||||
|
||||
## Repo & Branch
|
||||
- **origin:** `git.certvia.de/msolarczek/certvia`; zweiter Remote `local-gitea`.
|
||||
- **Basis ist `feature/iso27001-framework-mapping`**, nicht `dev` — dort liegt die Vorarbeit (Commits `492d315`, `bbde804`, `7769908`, `b28d0f0`).
|
||||
- AP1 auf `feature/framework-core`, PR gegen den Basis-Branch. AP2–AP5 danach je eigener Branch, parallelisierbar.
|
||||
|
||||
## Nicht anfassen
|
||||
- **`seed/isms-vorlagenpaket-v2/**`** — generiert. Inhaltliche Änderungen laufen ausschließlich über `_iso_crosswalk.json` / `_iso_sections.json` + `python3 _generate_iso.py`, nie direkt in den Markdown-Dateien (der Generator überschreibt sentinel-begrenzte Blöcke).
|
||||
- **Die TISAX-Logik verhaltensgleich lassen:** `src/lib/maturity.ts`, `src/lib/scope-filter.ts`, `src/server/assessment-level.ts`, `src/lib/control-titles.ts`, `src/lib/export/vda-isa*.ts`. Wenn du sie hinter eine `FrameworkStrategy` ziehst, muss das Verhalten identisch bleiben.
|
||||
|
||||
## Vier Invarianten — hier geht es sonst schief
|
||||
|
||||
1. **`reconcilePackage` archiviert fremde Anforderungen.** `prisma/import-policies.ts:368-371` setzt `archivedAt` auf jede `PolicyRequirement`, deren `reqId` nicht im importierten Paket steht. Ein ISO-Import in einen TISAX-Mandanten legt damit **alle 321 VDA-ISA-Anforderungen still** — und umgekehrt. Lösung: `PolicyRequirement.framework` ergänzen (Backfill `TISAX`) und den Archivierungslauf auf `where: { tenantId, framework }` einschränken. Für Dokumente, Variablen, Baseline und Nachweisregister gilt das **nicht** — die sind geteilt und identisch, sie dürfen genau einmal je Mandant abgeglichen werden.
|
||||
2. **Zwei Unique-Constraints brechen.** `PolicyTemplateVersion.version @unique` (`prisma/schema.prisma:1639`) → `@@unique([framework, version])`, sonst kollidieren ISO 2.1 und TISAX 2.1. `PolicyPackageState.tenantId @unique` (`:1614`) → `@@unique([tenantId, framework])`, sonst merkt sich ein Mandant nur eine Paketversion.
|
||||
3. **TISAX darf sich nicht verändern.** Messlatte ist `python3 seed/isms-vorlagenpaket-v2/_render_diff.py HEAD` → 0 Abweichungen.
|
||||
4. **Den Fail-Safe in `src/lib/policy-render.ts` nicht entfernen.** `buildContext` belegt fehlende Framework-Flags vor (`FLAG_FW_TISAX = true`, `FLAG_FW_ISO27001 = false`), damit Bestandsmandanten vor dem Paket-Re-Import keine leeren Anforderungsblöcke sehen.
|
||||
|
||||
## AP1 — Framework-Dimension *(Fundament, blockiert alles)*
|
||||
|
||||
**Schema, additiv:**
|
||||
```prisma
|
||||
enum Framework { ISO_27001 TISAX }
|
||||
|
||||
model TenantFramework {
|
||||
id String @id @default(cuid())
|
||||
tenantId String @map("tenant_id")
|
||||
framework Framework
|
||||
isPrimary Boolean @default(false) @map("is_primary")
|
||||
config Json? // z. B. { tisaxLevel: "AL3" } bzw. { certScope }
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
@@unique([tenantId, framework])
|
||||
@@index([tenantId])
|
||||
@@map("tenant_frameworks")
|
||||
}
|
||||
```
|
||||
Dazu `PolicyRequirement.framework`, `PolicyTemplateVersion.framework`, `PolicyPackageState.framework`. Backfill aller Bestandsdaten auf `TISAX`. `TenantFramework` gehört in **`TENANT_MODELS`** (`src/server/db.ts:81`) und braucht eine **RLS-Policy in der Migration**.
|
||||
|
||||
**Code:**
|
||||
| Datei | Änderung |
|
||||
|---|---|
|
||||
| `prisma/import-policies.ts` | `parsePackageFiles(seedDir, mappingFile = "mapping.json")`; Requirements framework-scoped reconcilen |
|
||||
| `prisma/template-store.ts:147` | `resolvePackageForTenant(prisma, tenantId, seedDir, framework)`; `loadPublishedPackage(prisma, locale, framework)`; `getAvailableVersion` ebenso |
|
||||
| `scripts/sync-policy-templates.ts:23` | über **Frameworks × Sprachen** iterieren |
|
||||
|
||||
Die vier Aufrufer bekommen den Parameter durchgereicht: `src/server/provision.ts:139`, `src/server/actions/policy-package.ts:28`, `src/server/actions/admin.ts`, `src/app/(app)/policies/updates/page.tsx:44`. **Das Seed-Verzeichnis bleibt für beide Frameworks dasselbe** — die fünf `SEED_DIR`-Konstanten ändern sich nicht, nur der Mapping-Dateiname.
|
||||
|
||||
**DoD:** Bestandsmandanten laufen unverändert als TISAX; ein Mandant lässt sich mit `["ISO_27001"]`, `["TISAX"]` oder beiden provisionieren; bei Doppel-Framework koexistieren 321 + 120 Anforderungen und **keine** ist fälschlich archiviert.
|
||||
|
||||
## AP2 — Provisionierung und Flags *(klein, direkt nach AP1)*
|
||||
|
||||
`ProvisionOpts` (`src/server/provision.ts:37`) um `frameworks: Framework[]`. `provisionTenant` schreibt die `TenantFramework`-Zeilen, importiert je Framework das passende Mapping und setzt die Sichtbarkeits-Flags als `PolicyVariable`: nur TISAX → `true/false`, nur ISO → `false/true`, beides → `true/true`.
|
||||
|
||||
**Reihenfolge beachten:** `reconcilePackage` erhält nutzergepflegte Variablenwerte und überschreibt sie nicht — die Flags also **nach** dem Import setzen, sonst bleibt der Schema-Default stehen und ein ISO-Mandant sieht die VDA-ISA-Sicht. `tisaxLevel` bleibt auf `TenantSettings`, ist aber TISAX-scoped; bei einem reinen ISO-Mandanten keine AL-Flags setzen.
|
||||
|
||||
**DoD:** Frisch provisionierter ISO-Mandant öffnet `/policies` und sieht je Abschnitt `*Anforderungsbezug:* ISO/IEC 27001 …` plus die 19 ISO-only-Abschnitte; keine VDA-ISA-Anforderungen.
|
||||
|
||||
## AP3 — SoA-Modul *(das fehlende ISO-Kernartefakt)*
|
||||
|
||||
Der Modul-Key `soa` (`src/lib/modules.ts:19`) zeigt auf `/soa`, **die Route existiert nicht**; die heutige Logik liegt als Wizard-Schritt in `src/server/actions/soa.ts` und ist ein VDA-ISA-Reifegrad-Assessment (0–3), nicht die ISO-Anwendbarkeitserklärung.
|
||||
|
||||
```prisma
|
||||
model SoaEntry {
|
||||
id String @id @default(cuid())
|
||||
tenantId String @map("tenant_id")
|
||||
framework Framework
|
||||
control String // "A.5.15"
|
||||
applicable Boolean @default(true)
|
||||
justification String // Begründung Einbeziehung ODER Ausschluss
|
||||
source String? // Risiko-ID / gesetzliche / vertragliche Anforderung
|
||||
implementationStatus String @default("geplant") // umgesetzt | teilweise | geplant
|
||||
ownerId String? @map("owner_id")
|
||||
policyCode String? @map("policy_code")
|
||||
evidenceId String? @map("evidence_id")
|
||||
@@unique([tenantId, framework, control])
|
||||
@@index([tenantId])
|
||||
@@map("soa_entries")
|
||||
}
|
||||
```
|
||||
|
||||
`applicable`, `justification`, `implementationStatus` und die Ausschlussbegründung sind **normative Pflichtangaben** (ISO/IEC 27001:2022, 6.1.3 d) — ohne sie ist die SoA im Zertifizierungsaudit angreifbar. Vorbefüllung aus `mapping-iso.json` (93 Controls); das Feld `condition` steuert die Default-Anwendbarkeit. Fachliche Vorlage für Aufbau und Spalten: `seed/isms-vorlagenpaket-v2/Statement-of-Applicability-ISO.md`.
|
||||
|
||||
**DoD:** SoA vollständig pflegbar und als PDF/XLSX exportierbar; ein Control ohne Begründung wird als unvollständig markiert.
|
||||
|
||||
## AP4 — Kennzahlen, Managementbewertung, Korrekturmaßnahmen
|
||||
|
||||
| Klausel | Modell | Inhalt |
|
||||
|---|---|---|
|
||||
| 9.1 | `Kpi` / `KpiValue` | Kennzahl, Datenquelle, Zielwert, Turnus, Verantwortlicher, Messwerte je Periode |
|
||||
| 9.3 | `ManagementReview` | Datum, Eingaben nach 9.3.2, Ergebnisse nach 9.3.3, Beschlüsse mit Verantwortlichem und Termin |
|
||||
| 10.2 | `Nonconformity` + `CorrectiveAction` | Herkunft, Sofortkorrektur, Ursachenanalyse, Maßnahme, Wirksamkeitsbewertung |
|
||||
|
||||
Aufsetzen auf Vorhandenes: `Task.recurrence` (RRULE), `Task.remindAt`, `Task.effectiveUntil` (Wirksamkeitsintervall, gekoppelt an `Evidence.validUntil`), `TaskParticipant` (RACI), `AuditLog`. Datenquellen für Kennzahlen liegen bereits im Tool: Aufgabenfristen und Überfälligkeit, Incident-SLA und Meldefristen (`src/lib/incident-deadlines.ts`), Reifegrade je Control, Maßnahmenstatus. Die Feldinhalte stehen fachlich in R03 der Bibliothek (`ISO-MS-MESSUNG`, `ISO-MS-MGMTREVIEW`, `ISO-MS-CAPA`).
|
||||
|
||||
**DoD:** Kennzahlenblatt mit Zielwerten über zwei Perioden auswertbar; Management-Review entlang der 9.3.2-Agenda protokollierbar; ein Maßnahmenfall inklusive dokumentierter Wirksamkeitsprüfung abschließbar.
|
||||
|
||||
## AP5 — Dokumentenlenkung *(klein, hohe Auditwirkung)*
|
||||
|
||||
- `PolicyDocument.reviewCycle` + `nextReviewAt` — heute führt nur `ManagedRegister` einen `reviewCycle`; A.5.1 verlangt die Überprüfung „in geplanten Abständen".
|
||||
- `PolicyAcknowledgement { tenantId, policyDocumentId, version, userId, acknowledgedAt }` — Lesebestätigung, in `SPEC.md` §4.6 vorgesehen und bis heute nicht gebaut. Zugleich der einfachste Nachweis für Klausel 7.3 und Control A.6.3.
|
||||
- Änderungshistorie je Dokumentversion — aus `AuditLog` (Vorher/Nachher) ableitbar oder eigene Tabelle.
|
||||
|
||||
**DoD:** Übersicht „Prüfung fällig"; Auswertung der Lesebestätigungen je Richtlinienversion; Dokumenthistorie über mindestens zwei Versionen sichtbar.
|
||||
|
||||
## Validierungs-Gate vor jedem PR
|
||||
|
||||
```bash
|
||||
npx tsc --noEmit && npm run lint && npm run build
|
||||
cd seed/isms-vorlagenpaket-v2
|
||||
python3 _verify.py # TISAX-Sicht → OK
|
||||
python3 _verify_iso.py # ISO-Sicht → OK (0 Befunde)
|
||||
python3 _render_diff.py HEAD # TISAX-Regression → 0 Abweichungen
|
||||
```
|
||||
|
||||
Zusätzlich beachten:
|
||||
- **Migrationsflow Prisma 7** (`docs/HANDOVER-DEV.md:100`): `migrate diff --from-config-datasource … --to-schema … --script`, danach den **RLS-DO-Block manuell** an die `migration.sql` anhängen, dann `migrate deploy`.
|
||||
- **`scripts/check-module-guards.ts`** läuft als `prebuild`-Gate: jede neue Datei unter `src/server/actions/` dort eintragen (Modul-Key oder `EXEMPT`), sonst schlägt der Build fehl.
|
||||
- Bei paralleler Lane-Entwicklung teilen sich die Worktrees dieselbe lokale Postgres-DB: beim Erzeugen einer Migration nur die **eigenen** DDL-Blöcke übernehmen, Fremd-Drops von Hand entfernen.
|
||||
|
||||
## Definition of Done (gesamt)
|
||||
|
||||
| Prüfung | Erwartung |
|
||||
|---|---|
|
||||
| Bestandsmandant (TISAX) nach Deploy | Readiness und Exporte identisch zum Snapshot vor dem Umbau |
|
||||
| Import ISO in Mandant mit TISAX | 120 neue Anforderungen, **0 archivierte** ISA-Anforderungen |
|
||||
| Import ISO, Umsetzungstexte | 120 von 120 gefüllt |
|
||||
| Dokumente bei Doppel-Framework | 39 Dokumente, **nicht** doppelt |
|
||||
| Parallelbetrieb im Dokument | beide Anforderungssichten unter einem gemeinsamen Umsetzungstext |
|
||||
| Gate | tsc, lint, build, beide `_verify*`, `_render_diff` grün |
|
||||
|
||||
`parsePackageFiles` ist reine Dateiarbeit und ohne Datenbank testbar; für den Mandanten-Import gibt es `reconcilePackage(..., { dryRun: true })` — Änderungsreport ohne Schreibzugriff, geeignet als Freigabebedingung.
|
||||
|
||||
## Reihenfolge und Aufwand
|
||||
|
||||
```
|
||||
AP1 Framework-Dimension 4–6 PT ← blockiert alles
|
||||
├─ AP2 Provisionierung 1–2 PT
|
||||
├─ AP3 SoA-Modul 5–8 PT
|
||||
├─ AP4 Managementkl. 5–8 PT
|
||||
└─ AP5 Dok.-Lenkung 2–3 PT
|
||||
```
|
||||
|
||||
AP3–AP5 sind nach AP1 parallelisierbar. **Feature-Flag:** ISO bleibt laut Entscheidung D7 hinter einem Plattform-Schalter, bis AP3 abgenommen ist.
|
||||
|
||||
## Nicht dein Scope
|
||||
|
||||
Diese Punkte gehören dem ISB bzw. der Redaktion: Nachweisregister um Zeilen für Kennzahlenblatt, Management-Review-Protokoll und Maßnahmenregister ergänzen; VA-15 trennen und ein Verfahren für Korrekturmaßnahmen ergänzen (**Nummer ab VA-21**, VA-20 ist belegt); `REVIEW_CYCLE` an den 33 Bestandsstellen auf die getrennten Zyklus-Variablen umstellen; ISB-Freigabe der 19 neuen Abschnittstexte.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Kickoff-Prompt — Lane D: Test, Cutover & Abnahme
|
||||
|
||||
Du übernimmst **Lane D** (Integration/Abnahme) der Umstellung **MinIO → Garage**. Lies `docs/KONZEPT-garage-migration.md` (v. a. §7 Runbook, §8 Rollback, §9 Abnahmekriterien). **Randbedingung:** nur Test-Instanzen, keine Datenmigration — Neu-Deploy.
|
||||
|
||||
## Repo & Branch
|
||||
- **origin:** `git.certvia.de/msolarczek/certvia` — Basis-Branch **`dev`**.
|
||||
- Zweiter Remote (interner Coolify-Test): `local-gitea` = `gitea.192.168.1.155.sslip.io/msolarczek/ISMS-Tool`. Push auf `dev` löst den Test-Deploy aus.
|
||||
- Deploy-Ziel: interne Coolify-Instanz, `certvia.192.168.1.155.sslip.io`.
|
||||
|
||||
## Ziel
|
||||
Die integrierten Ergebnisse aus Lane A–C auf der Test-Instanz **per Neu-Deploy** in Betrieb nehmen und **formal abnehmen** — plus abgenommenes Runbook (auch für spätere Prod).
|
||||
|
||||
## Aufgaben
|
||||
1. **Cutover (Runbook §7)** an der Test-Instanz durchspielen:
|
||||
- Im Compose `minio` → `garage` + `garage-provision`; Volumes `garage_meta`/`garage_data`.
|
||||
- Coolify-Env: `S3_ENDPOINT=http://garage:3900`, `S3_REGION=us-east-1`, `GARAGE_RPC_SECRET`, `GARAGE_ADMIN_TOKEN` (literal!), `S3_ACCESS_KEY/S3_SECRET_KEY` = provisionierter Garage-Key.
|
||||
- Deploy; Garage „ready", `garage-provision` legt Bucket/Key/Rechte an.
|
||||
- Optional DB-Reset (wie in bisherigen Deploys), falls alte Objekt-Referenzen stören.
|
||||
2. **End-to-End-Abnahme (§9)** — alle grün:
|
||||
- Upload (Richtlinie/Nachweis) → Objekt in Garage, `<tenantId>/uploads/…`-Präfix korrekt.
|
||||
- Download (`/files/[...key]`) inkl. korrektem Dateinamen/Content-Type.
|
||||
- Backup-Export `.cvb` (CVB1-Header), Persistenz + Download.
|
||||
- DSGVO-ZIP erzeugt + lesbar.
|
||||
- Restore → Datenintegrität + **Mandanten-Isolation**.
|
||||
- Backup-Historie: List + Aufräumen (Delete-Prefix).
|
||||
- Negativfall: fehlender Bucket → sprechender Konfigfehler (kein stiller CreateBucket).
|
||||
- `scripts/test-backup-*.ts` + `scripts/test-garage-storage.ts` grün gegen die Instanz.
|
||||
3. **Runbook & Rollback** in `docs/DEPLOY-COOLIFY.md` finalisieren (Schritt-für-Schritt, inkl. „`garage_meta` sichern").
|
||||
4. **`minio`-Service + Volumes** erst nach erfolgreicher Abnahme entfernen (bis dahin Rollback-Sicherheitsnetz).
|
||||
|
||||
## Vorgaben
|
||||
- **Keine echten Secrets in Chat/Repo/Logs** (`GARAGE_*`, S3-Key). In Coolify **literal** setzen (Interpolationsfalle).
|
||||
- Bei „Container weg ohne Logs" die bekannte **Log-Capture-Technik** nutzen (Logs während des Deploys in Dateien mitschreiben; siehe Deployment-Erfahrungen).
|
||||
- Gefundene Bugs an die jeweilige Lane (A/B/C) zurückspielen, nicht selbst quer patchen.
|
||||
|
||||
## Definition of Done
|
||||
- Test-Instanz läuft auf Garage, alle Abnahmekriterien (§9) abgehakt.
|
||||
- Runbook + Rollback dokumentiert und einmal real durchgespielt.
|
||||
- `minio` entfernt (oder bewusst als Netz belassen, dokumentiert). Freigabe für spätere Prod.
|
||||
|
||||
## Abhängigkeiten
|
||||
Integriert **Lane A + B + C**. PM koordiniert Reihenfolge (A→B, C parallel) und Go für die Abnahme.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Kickoff-Prompt — Lane C: App-Code Garage-tauglich
|
||||
|
||||
Du übernimmst **Lane C** der Umstellung **MinIO → Garage**. Lies `docs/KONZEPT-garage-migration.md` (v. a. §3 und §4 D3). **Kern:** Der S3-Code bleibt inhaltlich gleich (AWS SDK v3, `forcePathStyle`), aber die Selbstheilung `ensureBucket()` (HeadBucket→**CreateBucket**) muss weg — Garage unterstützt S3-`CreateBucket` nicht; Buckets werden von Lane B vorab provisioniert.
|
||||
|
||||
## Repo & Branch
|
||||
- **origin:** `git.certvia.de/msolarczek/certvia` — Basis-Branch **`dev`**.
|
||||
- Zweiter Remote: `local-gitea` = `gitea.192.168.1.155.sslip.io/msolarczek/ISMS-Tool`.
|
||||
- Arbeite auf `feature/garage-code` (aus `dev`), PR nach `dev`. **Unabhängig von Lane A/B** entwickelbar (gegen einen lokalen Garage-Container testen).
|
||||
|
||||
## Scope (genau diese Dateien)
|
||||
- `src/server/storage/adapter.ts` — `ensureBucket()` anpassen.
|
||||
- `src/server/storage/backup-store.ts` — `ensureBucket()` anpassen.
|
||||
- `.env.coolify.example` + `.env.example` — Kommentare MinIO → Garage, `S3_ENDPOINT`-Beispiel `http://garage:3900`, `forcePathStyle`-Begründung bleibt gültig.
|
||||
- Tests unter `scripts/` (neuer Smoke-Test).
|
||||
- **Nicht anfassen:** Compose/Infra (Lane A), Provisioning (Lane B), Fachlogik/UI.
|
||||
|
||||
## Aufgaben
|
||||
1. **`ensureBucket()` in beiden Stores** von „HeadBucket→CreateBucket" auf **nur prüfend** umstellen:
|
||||
- `HeadBucketCommand` → wenn ok, weiter.
|
||||
- Wenn Bucket fehlt/kein Zugriff → **klarer Konfigurationsfehler** werfen: „Bucket `<name>` nicht provisioniert/kein Zugriff — Garage-Provisioning (Lane B) ausführen." **Kein** `CreateBucketCommand` mehr.
|
||||
- `CreateBucketCommand`-Import entfernen, wenn ungenutzt (tsc/lint sauber halten).
|
||||
- Beachte: `backup-store.ts` schluckt heute den Fehler still — das durch die neue, sprechende Variante ersetzen.
|
||||
2. **Region/Endpoint-Doku** aktualisieren (Default `S3_REGION=us-east-1` bleibt, passend zu Garage-`s3_region`).
|
||||
3. **Smoke-Test** (`scripts/test-garage-storage.ts` o. ä.): gegen einen lokalen Garage-Container Put→Get→(List/Delete beim Backup-Store) grün; plus Negativfall „Bucket fehlt → sprechender Fehler".
|
||||
|
||||
## Vorgaben
|
||||
- **API der Storage-Abstraktion unverändert** (`StorageAdapter`/`BackupStore`-Interfaces, Key-Schema, Local-/Stub-Fallback bleiben).
|
||||
- Keine neuen Pflicht-Env; `S3_*`-Kontrakt bleibt.
|
||||
- **Validierungs-Gate vor PR:** `npx tsc --noEmit`, Lint, `npm run build`, alle `scripts/test-*.ts` grün (inkl. neuem Test). Denk an die bekannte Falle: **nichts, was Secrets liest, auf Modulebene aufrufen** (Build-Kompatibilität).
|
||||
|
||||
## Definition of Done
|
||||
- Beide `ensureBucket()` prüfen nur noch, mit sprechendem Fehler bei fehlendem Bucket.
|
||||
- Doku aktualisiert; Smoke-Test grün gegen lokale Garage; Gate grün.
|
||||
|
||||
## Abhängigkeiten
|
||||
Zur **Laufzeit** auf **Lane B** angewiesen (Bucket muss existieren), aber **Code + Tests unabhängig** entwickelbar (lokaler Garage-Container).
|
||||
@@ -0,0 +1,35 @@
|
||||
# Kickoff-Prompt — Lane A: Garage Infra & Deployment
|
||||
|
||||
Du übernimmst **Lane A** der Objektspeicher-Umstellung **MinIO → Garage**. Lies zuerst das Gesamtkonzept: `docs/KONZEPT-garage-migration.md` (v. a. §3 Reibungspunkt, §5 Zielarchitektur, §6 Lane A, §7 Runbook). **Randbedingung:** nur Test-Instanzen, keine Datenmigration — kompletter Neu-Deploy.
|
||||
|
||||
## Repo & Branch
|
||||
- **origin:** `git.certvia.de/msolarczek/certvia` — Basis-Branch **`dev`**.
|
||||
- Zweiter Remote (interner Coolify-Test): `local-gitea` = `gitea.192.168.1.155.sslip.io/msolarczek/ISMS-Tool`. Ein Push auf `dev` löst den Test-Deploy aus.
|
||||
- Arbeite auf `feature/garage-infra` (aus `dev`), PR nach `dev`. Nach Merge `dev` auf **beide** Remotes pushen.
|
||||
|
||||
## Ziel
|
||||
Garage als Compose-Service, der `minio` in `docker-compose.coolify.yml` ersetzt — lauffähig auf der Test-Instanz, Admin-API erreichbar, Single-Node-Layout „ready".
|
||||
|
||||
## Scope (nur diese Dateien/Bereiche)
|
||||
- `docker-compose.coolify.yml`: `minio`-Service durch `garage` ersetzen (nicht sofort löschen — auskommentiert/parallel lassen, bis Lane D abnimmt).
|
||||
- `garage.toml` (neu, als Config-Mount oder über Env) + ggf. `docs/DEPLOY-COOLIFY.md` ergänzen.
|
||||
- Keine App-Code-Änderung (das ist Lane C).
|
||||
|
||||
## Vorgaben
|
||||
- **Image pinnen** auf eine aktuelle stabile Garage-Version (`dxflrs/garage:vX.Y.Z`), nicht `latest`.
|
||||
- **Ports:** 3900 = S3-API (von der App genutzt), 3903 = Admin-API (clusterintern, für Healthcheck/Provisioning), 3902 = Web optional. **Nichts nach außen (Traefik) freigeben** — genau wie MinIO bisher.
|
||||
- **`garage.toml`:** `replication_factor = 1` (Single-Node), `metadata_dir`, `data_dir`, `rpc_secret` (aus `GARAGE_RPC_SECRET`), Block `[s3_api] s3_region = "us-east-1"`, `api_bind_addr = "[::]:3900"`, Block `[admin] api_bind_addr = "[::]:3903"`, `admin_token` (aus `GARAGE_ADMIN_TOKEN`).
|
||||
- **Volumes:** `garage_meta → /var/lib/garage/meta` (KRITISCH), `garage_data → /var/lib/garage/data`.
|
||||
- **Security analog Bestand:** `security_opt: no-new-privileges`, `cap_drop: ALL`, Resource-Limits, `restart: unless-stopped`.
|
||||
- **Healthcheck** gegen Admin-API `/health` (3903).
|
||||
- **Layout-Bootstrap** dokumentieren: nach erstem Start Node einer Zone mit Kapazität zuweisen (`garage layout assign …` → `garage layout apply`). Falls möglich, an Lane B (Provisioning-Job) delegieren — dann hier nur vorbereiten.
|
||||
- **Secrets:** `GARAGE_RPC_SECRET` (32-byte hex) und `GARAGE_ADMIN_TOKEN` als Coolify-Env, **literal** setzen (nicht über `${…}` referenzieren — bekannte Coolify-Interpolationsfalle). **Keine echten Secrets ins Repo oder in Logs.**
|
||||
|
||||
## Definition of Done
|
||||
- Garage-Container startet in der Test-Instanz, Admin-`/health` grün, Layout „ready".
|
||||
- `S3_ENDPOINT=http://garage:3900` intern erreichbar (kurzer `aws s3 ls`/curl-Nachweis).
|
||||
- `garage_meta` als zu sicherndes Volume in `docs/DEPLOY-COOLIFY.md` vermerkt.
|
||||
- Übergabepunkt an Lane B (Provisioning) klar dokumentiert (wie CLI/Admin-API erreichbar ist).
|
||||
|
||||
## Abhängigkeiten
|
||||
Lane B (Provisioning) baut direkt auf dir auf. Stimme das CLI-/Admin-API-Zugriffsmodell mit Lane B ab.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Kickoff-Prompt — Lane B: Garage Provisioning (Bucket/Key/Rechte)
|
||||
|
||||
Du übernimmst **Lane B** der Umstellung **MinIO → Garage**. Lies `docs/KONZEPT-garage-migration.md` (v. a. §3 „einziger Reibungspunkt", §4 D3, §6 Lane B). **Kern:** Garage legt Buckets/Keys **nicht** über S3-`CreateBucket` an, sondern über **Admin-API/CLI** — das automatisieren wir hier, idempotent.
|
||||
|
||||
## Repo & Branch
|
||||
- **origin:** `git.certvia.de/msolarczek/certvia` — Basis-Branch **`dev`**.
|
||||
- Zweiter Remote: `local-gitea` = `gitea.192.168.1.155.sslip.io/msolarczek/ISMS-Tool` (Push auf `dev` = Test-Deploy).
|
||||
- Arbeite auf `feature/garage-provision` (aus `dev`), PR nach `dev`.
|
||||
|
||||
## Ziel
|
||||
Ein **idempotenter Init-Job `garage-provision`** (Compose-Service, `restart: no`, analog `migrate`), der aus einer frisch gestarteten Garage reproduzierbar den betriebsbereiten Zustand herstellt.
|
||||
|
||||
## Scope
|
||||
- Neuer Compose-Service `garage-provision` in `docker-compose.coolify.yml` (mit Lane A abstimmen; `depends_on: garage`).
|
||||
- Provisioning-Skript (`scripts/garage-provision.*` oder Shell im Job) — CLI **oder** Admin-API (HTTP). Entscheidung im Skript-Kommentar begründen.
|
||||
- Doku in `docs/DEPLOY-COOLIFY.md`.
|
||||
|
||||
## Aufgaben (alle idempotent — mehrfach ausführbar ohne Fehler)
|
||||
1. **Layout** sicherstellen (falls Lane A das nicht schon macht): Node zuweisen + `layout apply`.
|
||||
2. **Bucket(s)** anlegen: `isms-documents` (Uploads); Backup-Bucket nur, falls Backup-Store auf S3 statt `BACKUP_LOCAL_DIR` läuft.
|
||||
3. **Access-Key** bereitstellen — **deterministisch**: bevorzugt vorhandenen Key **importieren** (`garage key import` mit den Werten aus `S3_ACCESS_KEY`/`S3_SECRET_KEY` der Coolify-Env), damit App-Env und Garage garantiert synchron sind. (Alternative: Key erzeugen und Ausgabe in Coolify-Secrets übernehmen — nur wenn Import nicht praktikabel; Trade-off dokumentieren.)
|
||||
4. **Rechte** setzen: Key → Bucket read/write (owner nach Bedarf).
|
||||
5. **Verifikation:** am Ende prüfen, dass Bucket existiert und der Key Schreib-/Leserecht hat; bei Fehlkonfiguration mit klarer Meldung + Exit ≠ 0 abbrechen.
|
||||
|
||||
## Vorgaben
|
||||
- **Idempotenz zwingend:** vor jedem `create` Existenz prüfen; „already exists" als Erfolg werten (der Job läuft bei JEDEM Deploy).
|
||||
- **Kein Secret in Logs** (Key/Secret nicht ausgeben). `GARAGE_ADMIN_TOKEN` aus Env.
|
||||
- Nicht crash-loopen bei fehlender Config: klare Fehlermeldung, definierter Exit (der Job ist `restart:no`, kein Dauerdienst).
|
||||
- **Keine App-Code-Änderung** (Lane C).
|
||||
|
||||
## Definition of Done
|
||||
- Aus „leerer Garage" stellt ein einziger Job-Lauf Bucket + Key + Rechte her; zweiter Lauf ist ein sauberer No-Op.
|
||||
- Danach greift `HeadBucket` der App erfolgreich (Übergabe an Lane C/D).
|
||||
- Runbook-Schritt in `docs/DEPLOY-COOLIFY.md` dokumentiert.
|
||||
|
||||
## Abhängigkeiten
|
||||
Braucht **Lane A** (Garage-Service + Admin-Zugriff). Liefert die Vorbedingung für **Lane C** (`ensureBucket` prüft nur) und **Lane D** (Abnahme).
|
||||
@@ -0,0 +1,55 @@
|
||||
# Kickoff-Prompt — Lane Sicherheitshärtung (certvia)
|
||||
|
||||
> Diesem Prompt einem Entwickler/Claude-Code-Agenten geben. Bootstrapt in certvia + diese Lane.
|
||||
|
||||
```text
|
||||
Du übernimmst die Lane „Sicherheitshärtung" am Produkt „certvia" (ISMS-Tool, Multi-Tenant
|
||||
Next.js-16 / Prisma-7 / Postgres+RLS / Auth.js-v5). Repo: ~/Projects/ISMS-Tool, Branch `dev`.
|
||||
|
||||
WICHTIG: certvia ist strikt getrennt von jedem anderen Produkt (insb. „visitvia"). Nichts vermischen.
|
||||
|
||||
BRANCH/CHECKOUT:
|
||||
Arbeits-Branch: `lane-haertung` (KEIN `feature/`-Prefix — origin-Namespace-Konflikt).
|
||||
git fetch origin && git checkout dev && git checkout -b lane-haertung.
|
||||
Remotes: origin = https://git.certvia.de/msolarczek/certvia.git · local-gitea (intern).
|
||||
|
||||
1) PFLICHTLEKTÜRE:
|
||||
- docs/HANDOVER-DEV.md, docs/SPEC.md, docs/STAND-dev-branch.md
|
||||
- docs/KONZEPT-haertung.md ← dein Fahrplan
|
||||
- docs/KONZEPT-backup-restore.md §9 ← das gemeinsame Verschlüsselungs-Primitiv
|
||||
|
||||
2) AUFTRAG (Phasen aus dem Konzept §7):
|
||||
(1) PEPPER (App) — JETZT, solange test/dev-DBs frisch/leer sind.
|
||||
(2) Host-Encryption (LUKS/Volume) + verschlüsselte Backups (Ops, mit Backup-Lane).
|
||||
(3) Secrets-Register formalisieren.
|
||||
(4) DB-TLS (sslmode) + Vault/KMS = Phase 2.
|
||||
|
||||
3) VERBINDLICHE REGELN:
|
||||
- PEPPER: über Argon2-`secret` bei hash() UND jeder verify()-Stelle. Env `PASSWORD_PEPPER`
|
||||
(32-Byte hex). Nach Option C ist der verify-Pfad zentral (Login gegen Identity) → wenn nötig
|
||||
einen verifyPassword(hash,pw)-Wrapper einführen, damit Pepper EINE Stelle ist.
|
||||
- ⚠ Pepper ist NICHT rotierbar ohne Passwort-Reset für alle (wie MFA_ENC_KEY) → bewusst
|
||||
JETZT setzen, leere DBs nutzen. Restore-Kohärenz: Pepper ist Umgebungs-Secret, nicht im Artefakt.
|
||||
- Argon2-PARAMETER sind ERLEDIGT (src/server/password.ts, ARGON2_OPTIONS) — nicht anfassen,
|
||||
nur den `secret` ergänzen.
|
||||
- Host-Encryption/Backup-Verschlüsselung sind OPS-Runbook (kein App-Code) → in
|
||||
docs/DEPLOY-PROD-CONTABO.md als Go-Live-Punkte ergänzen; §9-Mechanismus (AES-256 client-seitig,
|
||||
Keys pro Umgebung) verwenden.
|
||||
- Secrets-Register: AUTH_SECRET · MFA_ENC_KEY · PASSWORD_PEPPER · pgBackRest-Key · age-Keypair;
|
||||
je Umgebung getrennt, nie im Artefakt-Bucket, Offline-Kopie versiegelt.
|
||||
|
||||
4) ARBEITSWEISE:
|
||||
- Gate vor JEDEM Merge: tsc · lint · build · ALLE scripts/test-*.ts. Der Pepper braucht einen Test
|
||||
(hash+verify mit gesetztem Pepper; verify schlägt fehl bei falschem/fehlendem Pepper).
|
||||
- DevOps: lane-haertung → git merge --no-ff nach dev → Gate grün → Push auf BEIDE Remotes →
|
||||
STAND pflegen.
|
||||
|
||||
5) KOORDINATION: §9-Verschlüsselung gemeinsam mit Lane Backup (Mechanismus/Keys entschieden — einmal
|
||||
abstimmen). Pepper-Rollout NUR auf Umgebungen mit leerer/frischer DB (sonst Passwort-Reset nötig).
|
||||
|
||||
6) NICHT TUN: keine Auth-Logik-Änderung außer dem Pepper; keine Rotation eines gesetzten Peppers/
|
||||
MFA_ENC_KEY ohne expliziten Reset-Plan; Argon2-Parameter unverändert lassen.
|
||||
|
||||
Erste Schritte: (a) Pflichtlektüre + Fragen, (b) Pepper-PR-Plan (Env, verify-Wrapper, Test) +
|
||||
Bestätigung „Pepper jetzt setzen, DBs leer" einholen, (c) umsetzen. Warte nach (a)/(b).
|
||||
```
|
||||
@@ -0,0 +1,58 @@
|
||||
# Kickoff-Prompt — Lane Betreiber-Konsole-UX + i18n (certvia)
|
||||
|
||||
> Diesem Prompt einem Entwickler/Claude-Code-Agenten geben. Bootstrapt in certvia + diese Lane.
|
||||
|
||||
```text
|
||||
Du übernimmst die Lane „Betreiber-Konsole-UX + vollständige i18n" am Produkt „certvia" (ISMS-Tool,
|
||||
Multi-Tenant Next.js-16 / Prisma-7 / Postgres+RLS / Auth.js-v5). Repo: ~/Projects/ISMS-Tool, Branch `dev`.
|
||||
|
||||
WICHTIG: certvia ist strikt getrennt von jedem anderen Produkt (insb. „visitvia"). Nichts vermischen.
|
||||
|
||||
BRANCH/CHECKOUT:
|
||||
Arbeits-Branch: `lane-ui-i18n` (KEIN `feature/`-Prefix — origin-Namespace-Konflikt).
|
||||
git fetch origin && git checkout dev && git checkout -b lane-ui-i18n.
|
||||
Remotes: origin = https://git.certvia.de/msolarczek/certvia.git · local-gitea (intern).
|
||||
|
||||
1) PFLICHTLEKTÜRE:
|
||||
- docs/HANDOVER-DEV.md, docs/SPEC.md, docs/STAND-dev-branch.md
|
||||
- docs/KONZEPT-ui-i18n.md ← dein Fahrplan (Bugfix 1+2, Ergänzungen A/B)
|
||||
|
||||
2) AUFTRAG:
|
||||
BUGFIX 1 — Betreiber-Konsole (src/app/(platform)/admin/[id]/page.tsx):
|
||||
- Module → Popup (searchParam `?modules=1`, <Modal>); Benutzer → Popup (`?users=1`).
|
||||
Muster existiert bereits auf der Seite (?new/?edit/?audit) — analog kapseln.
|
||||
- Hauptfenster stattdessen: Stammdaten (aus TenantSettings) + Hauptkontakt sichtbar.
|
||||
Offene Kleinentscheidung: Hauptkontakt = neue Felder in TenantSettings vs. Ableitung aus
|
||||
tenant-admin — mit PM klären.
|
||||
BUGFIX 2 — Vollständige UI-Sprache + per-Mitarbeiter-Umschaltung:
|
||||
- BEFUND: messages/en.json existiert (~95%), aber src/i18n/request.ts ist HART auf "de"
|
||||
(Zeile 8). TenantSettings.locale steuert nur die Richtlinien-Import-Sprache, NICHT die UI.
|
||||
- Neu: Identity.uiLocale (de|en, Default de) — persönliche Präferenz, folgt der Person.
|
||||
- request.ts liest uiLocale der aktiven Session-Identity (Fallback de).
|
||||
- Umschalter im Nutzer-Menü (Header/Profil) → Server-Action setUiLocale → speichern + reload.
|
||||
- messages/en.json auf 100% prüfen/auffüllen; hartkodierte deutsche Strings in Komponenten
|
||||
aufspüren und in den Katalog überführen.
|
||||
ERGÄNZUNG A — Login: Organisationsfeld (`tenant`) aus src/app/login/page.tsx ENTFERNEN
|
||||
(nach Option C überflüssig; Mandant kommt über /select-tenant). login-ticket-Signaturen entschlacken.
|
||||
|
||||
3) VERBINDLICHE REGELN:
|
||||
- UI-Sprache (Identity.uiLocale, Person) und Vorlagen-Import-Sprache (TenantSettings.locale,
|
||||
Inhalt) sind ZWEI getrennte Achsen — nicht vermischen.
|
||||
- Popups über das bestehende searchParam/<Modal>-Muster, KEINE neue Modal-Infrastruktur.
|
||||
- Stammdaten haben EINE Quelle (TenantSettings) — keine Doppelpflege einführen.
|
||||
- RLS/Datenpfade unverändert; das ist eine reine UI-/Präferenz-Lane.
|
||||
|
||||
4) ARBEITSWEISE:
|
||||
- Gate vor JEDEM Merge: tsc · lint · build · ALLE scripts/test-*.ts.
|
||||
- UI-Verifikation im Browser: Betreiber-Popups (Module/Benutzer), Sprachumschaltung DE↔EN
|
||||
(Menü + Beschreibungen wechseln), Login ohne Organisationsfeld, /select-tenant unverändert.
|
||||
- DevOps: lane-ui-i18n → git merge --no-ff nach dev → Gate grün → Push auf BEIDE Remotes →
|
||||
STAND pflegen.
|
||||
|
||||
5) NICHT TUN: keine Änderung am Auth-Kern/an /select-tenant-Logik; Identity.uiLocale nur als
|
||||
Präferenzfeld ergänzen (keine Auth-Semantik).
|
||||
|
||||
Erste Schritte: (a) Pflichtlektüre + Fragen (v.a. Hauptkontakt-Feld), (b) PR-Plan je Bugfix
|
||||
(Migration Identity.uiLocale, request.ts, Menü-Switcher; Popup-Umbau admin/[id]), (c) umsetzen.
|
||||
Warte nach (a)/(b).
|
||||
```
|
||||
@@ -0,0 +1,71 @@
|
||||
# Übergabe-Prompt — Auth-Umbau „Zentrale Identität + Mandanten-Mitgliedschaften"
|
||||
|
||||
> Diesen Prompt einem neuen Entwickler bzw. dessen Claude-Code-Agenten geben. Er bootstrapt in certvia und diese Aufgabe. Zugehörige Dokumente liegen im selben Branch.
|
||||
|
||||
```text
|
||||
Du übernimmst Entwicklungsarbeit am Produkt „certvia" (ISMS-Tool, Multi-Tenant-
|
||||
Next.js-16 / Prisma-7 / Postgres+RLS / Auth.js-v5 SaaS). Repo: ~/Projects/ISMS-Tool,
|
||||
Integrationsbranch `dev`. Deine Aufgabe: den Auth-Umbau „Zentrale Identität mit
|
||||
Mandanten-Mitgliedschaften" (Option C) umsetzen.
|
||||
|
||||
BRANCH / CHECKOUT:
|
||||
Arbeits-/Doku-Branch: `identity-mandanten`
|
||||
- origin = https://git.certvia.de/msolarczek/certvia.git (Branch: identity-mandanten)
|
||||
- local-gitea = interner Spiegel (Branch: identity-mandanten)
|
||||
Auschecken: git fetch origin && git checkout identity-mandanten
|
||||
Die unten genannten docs/ liegen auf genau diesem Branch.
|
||||
|
||||
WICHTIG: certvia ist strikt getrennt von jedem anderen Produkt (insb. „visitvia").
|
||||
Nichts vermischen.
|
||||
|
||||
1) PFLICHTLEKTÜRE — erst lesen, nicht sofort coden, in dieser Reihenfolge:
|
||||
- docs/HANDOVER-DEV.md, docs/SPEC.md (Projektgrundlagen)
|
||||
- docs/STAND-dev-branch.md (aktueller Entwicklungsstand)
|
||||
- docs/UEBERGABE-identity-mandanten.md (Kurzübergabe zu genau dieser Aufgabe)
|
||||
- docs/FEINDESIGN-identity-mandanten.md (der umsetzbare Bauplan — dein Fahrplan)
|
||||
- docs/KONZEPT-identity-mandanten.md (Warum/was, getroffene Entscheidungen A–E)
|
||||
|
||||
2) AUFTRAG:
|
||||
Setze Option C um. Reihenfolge = die Workstreams/Meilensteine aus dem FEINDESIGN.
|
||||
Beginne mit WS0 (Fundament): neues globales `Identity`-Modell, Schema-Recut von
|
||||
`User` zur Mitgliedschaft (+identityId), Migration, `TENANT_MODELS` anpassen,
|
||||
Reseed. WS0 ist Blocker — bau es als Pairing und lass es reviewen.
|
||||
|
||||
3) VERBINDLICHE REGELN (aus dem FEINDESIGN, nicht verhandelbar):
|
||||
- `User.id` = Mitgliedschaft, STABIL lassen; Auth-Felder wandern auf `Identity`.
|
||||
- `Identity` ist GLOBAL: NICHT in `TENANT_MODELS`, kein tenant_id, keine RLS-Policy.
|
||||
- Genau EIN aktiver Mandant pro Session; `session.user.tenantId` = aktiver Mandant;
|
||||
server-autoritativ; bei Mandantenwechsel Membership+MFA re-validieren.
|
||||
- Nutzeranlage NUR per Einladung (kein „Passwort direkt setzen" mehr).
|
||||
- MFA/Passwort gehören der Identity — KEIN Mandanten-Admin-Reset.
|
||||
- MFA beim Login als 2. Schritt (erst E-Mail+Passwort, dann MFA); dazwischen KEINE
|
||||
volle Session (kurzlebiger MFA-pending-State).
|
||||
- Plattform-Admins (`platform_admins`) bleiben getrennt — nicht anfassen.
|
||||
|
||||
4) ARBEITSWEISE:
|
||||
- Validierungs-Gate vor JEDEM PR/Merge: `npx tsc --noEmit`, `npm run lint`,
|
||||
`npm run build`, und ALLE `scripts/test-*.ts` müssen grün sein. Jede Story bringt
|
||||
ihren eigenen Test mit (Identity-Login, Tenant-Switch-Isolation, MFA-Enforcement
|
||||
multi-tenant, Einladung, Two-Step-Bypass).
|
||||
- DevOps: Feature-Branch → `git merge --no-ff` nach `dev` → Gate grün →
|
||||
Push auf BEIDE Remotes (origin=git.certvia.de, local-gitea) →
|
||||
docs/STAND-dev-branch.md pflegen.
|
||||
- Definition of Done: siehe FEINDESIGN §9.
|
||||
|
||||
5) KOORDINATION:
|
||||
Parallel läuft „Richtlinien-Upload im Adminportal". Funktional unabhängig, ABER
|
||||
beide editieren src/app/(platform)/admin/[id]/page.tsx (Policy-Upload = Module-Karte,
|
||||
Identity-Umbau = Benutzerverwaltung). Reihenfolge auf dieser Datei abstimmen.
|
||||
|
||||
6) NICHT TUN:
|
||||
- Getroffene Entscheidungen A–E nicht umwerfen (bei echtem Problem eskalieren, nicht
|
||||
eigenmächtig ändern).
|
||||
- Phase-2-Punkte (per-Mandant „immer Step-up", E-Mail-Änderung als Identity-Op,
|
||||
PlatformAdmin-Konsolidierung) sind bewusst ausgeklammert — nicht mitbauen.
|
||||
- Keine Datenmigration bauen: es gibt nur Testdaten → Schema-Recut + Reseed.
|
||||
|
||||
Erste Schritte: (a) Pflichtlektüre lesen und mir eine 10-Zeilen-Zusammenfassung +
|
||||
offene Fragen zurückgeben, (b) WS0 als PR-Plan skizzieren (Schema-Diff, Migrationen,
|
||||
TENANT_MODELS-Änderung, Reseed), (c) nach Freigabe umsetzen. Warte nach (a)/(b) auf
|
||||
Bestätigung, bevor du WS0 mergst.
|
||||
```
|
||||
@@ -0,0 +1,43 @@
|
||||
# Übergabe-Prompt: Kundenbetreuung certvia
|
||||
|
||||
**Zweck:** Onboarding eines neuen Kundenbetreuers (Customer Success/Support). Kann direkt gelesen oder einem KI-Assistenten (z. B. Claude) als Kontext-Prompt gegeben werden. Hauptquelle im Detail: `docs/HANDBUCH-KUNDENBETREUUNG.md`.
|
||||
|
||||
---
|
||||
|
||||
Rolle: Du übernimmst die Kundenbetreuung (Customer Success/Support) für „certvia" — ein Multi-Mandanten-ISMS-Tool (Informationssicherheits-Managementsystem als SaaS). Ziel: certvia-Kunden onboarden, betreuen und im Alltag unterstützen.
|
||||
|
||||
Was ist certvia (in einem Satz):
|
||||
Jeder Kunde ist ein eigener Mandant mit strikt getrennten Daten. Das Tool führt Kunden von der Strukturanalyse (Assets/Prozesse/Lieferanten) über Risikomanagement, Richtlinien und Maßnahmen bis zur Audit-Vorbereitung — wahlweise nach TISAX (VDA-ISA) und/oder ISO 27001.
|
||||
|
||||
Deine ersten Schritte (Woche 1):
|
||||
1. Lies das Handbuch: docs/HANDBUCH-KUNDENBETREUUNG.md (im Projekt-Repo). Es ist deine Hauptquelle.
|
||||
2. Klick die Demo-/Testinstanz komplett durch — am besten lernt man das Produkt hands-on:
|
||||
- Mandanten-Login /login: admin@demo.example / Demo1234!
|
||||
- Superadmin /platform/login (MFA-Einrichtung beim ersten Login).
|
||||
- Schau alle Module an: Assets, Prozesse, Risiken, Lieferanten, Maßnahmen, Richtlinien, SoA, Audit-Readiness, Vorfälle, Aufgaben.
|
||||
3. Verstehe die Framework-Wahl: ein Mandant kann ISO 27001 und/oder TISAX führen (in der Admin-Konsole je Mandant aktivierbar). Unterschiede stehen im Handbuch (TISAX = Reifegrad/AL2/AL3; ISO = Anwendbarkeitserklärung/SoA + Managementklauseln).
|
||||
|
||||
Deine Kernaufgaben:
|
||||
- Neue Kunden beim Onboarding begleiten (Stammdaten, Framework-Wahl, Onboarding-Wizard, Erfassung der Bestandsdaten).
|
||||
- Support im Alltag: Login/MFA/Passwort, Rollen & Rechte, Module, Vorlagen/Richtlinien.
|
||||
- Fachliche Beratung „welche Norm passt" (ISO vs. TISAX) auf Basis des Handbuchs.
|
||||
|
||||
Typische Support-Fälle (Details im Handbuch §7):
|
||||
- „Anmeldung fehlgeschlagen": richtige Seite (/login vs /platform/login), Passwort exakt, ggf. kurze Sperre nach 5 Fehlversuchen (15 Min).
|
||||
- „MFA-Gerät verloren": Recovery-Codes; sonst MFA administrativ zurücksetzen.
|
||||
- „Modul fehlt": in der Admin-Konsole für den Mandanten aktivieren.
|
||||
- „ISO/TISAX fehlt": Framework des Mandanten prüfen/aktivieren.
|
||||
|
||||
Grenzen & Eskalation (wichtig):
|
||||
- Niemals Kundendaten zwischen Mandanten kopieren (Mandantentrennung/Datenschutz).
|
||||
- Keine eigenmächtigen Löschungen an Produktivdaten; keine Secrets per E-Mail/Chat weitergeben.
|
||||
- Bei technischen Themen (Deployment, Fehlermeldungen im Betrieb, Backups, TLS/Domain, Datenbank) an das DevOps-/Entwicklerteam eskalieren — nicht selbst am Produktivsystem eingreifen.
|
||||
|
||||
Wo du alles findest:
|
||||
- Handbuch: docs/HANDBUCH-KUNDENBETREUUNG.md
|
||||
- Produkt/Funktionsumfang: docs/SPEC.md, docs/HANDOVER-PM.md
|
||||
- Feature-Konzepte: docs/KONZEPT-framework-iso27001.md (ISO/TISAX)
|
||||
- Kundennahe Mockups (im Browser): docs/ISMS-Prototyp-GEFIM.html, docs/ISMS-Lieferantenmanagement-GEFIM.html
|
||||
- Aktueller Stand: docs/STAND-dev-branch.md
|
||||
|
||||
Arbeitsweise: Wenn du unsicher bist, prüfe zuerst im Handbuch und in der Demo-Instanz. Dokumentiere wiederkehrende Support-Fälle, damit das Handbuch wächst.
|
||||
@@ -0,0 +1,177 @@
|
||||
# SEC1 — SMTP-Mail-Fundament
|
||||
|
||||
> Branch `dev-sec1-mail-smtp` (Basis `dev`) · Grundlage: `docs/sicherheit/SEC1-Mail-Fundament-Detail.md`
|
||||
> Fundament für Passwort-Reset (SEC2), Einladung (SEC4), MFA-Hinweise (SEC3) und
|
||||
> Ticket-/Freigabe-/Fristen-Benachrichtigungen.
|
||||
|
||||
---
|
||||
|
||||
## 1. Architektur
|
||||
|
||||
```
|
||||
Aufrufer (Server-Action / Event)
|
||||
│ enqueueMail({template,to,vars,tenantId,locale,dedupeKey})
|
||||
▼
|
||||
service.ts ──► MailLog(pending) Worker-Prozess (npm run worker:mail)
|
||||
│ (dedupeKey = Sperre) ┌──────────────────────────────────┐
|
||||
├─ Queue erreichbar? ──ja──► Redis ──►│ BullMQ "mail" │
|
||||
│ │ → renderTemplate(locale) │
|
||||
└─ nein ─────────────────────────────►│ → provider.send() (deliver.ts) │
|
||||
(inline, gleicher deliver-Pfad) │ → MailLog(sent|failed) │
|
||||
│ → Retry/Backoff → mail-dead-letter
|
||||
└──────────────────────────────────┘
|
||||
Provider-Interface ← SMTP (nodemailer, Pool + TLS)
|
||||
```
|
||||
|
||||
Vier Schichten, wie im Aufgabenpaket vorgesehen: **Provider** (`provider.ts`,
|
||||
`provider-smtp.ts`), **Templates** (`templates.ts` + `src/lib/email-brand.ts`),
|
||||
**Queue/Worker** (`queue.ts`, `worker.ts`), **Service/Trigger** (`service.ts`,
|
||||
`notifications.ts`).
|
||||
|
||||
---
|
||||
|
||||
## 2. Betriebsmodus (Entscheidung)
|
||||
|
||||
Das Aufgabenpaket verlangt eine Festlegung — hier ist sie:
|
||||
|
||||
| `REDIS_URL` | Modus | Verhalten |
|
||||
|---|---|---|
|
||||
| gesetzt **und** erreichbar | **Queue** (Produktivmodus) | Asynchron über BullMQ; ein **eigener Worker-Prozess** (`npm run worker:mail`, eigener Container in Coolify) stellt zu. Retry mit exponentiellem Backoff (5 Versuche), Dead-Letter-Queue, Limiter (20 Mails/10 s, Concurrency 5), Graceful Shutdown. |
|
||||
| gesetzt, aber **nicht erreichbar** | Inline (degradiert) | Der Versand fällt auf den direkten Pfad zurück, damit bei einem Redis-Ausfall keine Mail verloren geht — **ohne** Retry/DLQ. Wird im Log vermerkt. |
|
||||
| nicht gesetzt | Inline | Lokale Entwicklung und Demo laufen ohne Redis. |
|
||||
|
||||
Die Erreichbarkeit wird **vor** dem Einstellen geprüft (`isQueueReady()`). Ein
|
||||
Fallback *nach* einem fehlgeschlagenen `add()` wäre riskant: der Job könnte
|
||||
angekommen sein und nur die Bestätigung verloren gegangen — das ergäbe einen
|
||||
Doppelversand. Deshalb wird ein Fehler beim Einstellen nur protokolliert.
|
||||
|
||||
Der Worker registriert zusätzlich den **Fristen-Job** (täglich 07:00
|
||||
Europe/Berlin) auf einer **eigenen** Queue `mail-scheduler`. Grund: ein
|
||||
BullMQ-Worker konsumiert alle Jobs *seiner* Queue unabhängig vom Job-Namen —
|
||||
auf einer gemeinsamen Queue könnte der Zustell-Worker den Fristen-Job abgreifen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Konfiguration
|
||||
|
||||
Führend sind die bereits im Repo etablierten Namen; die im Aufgabenpaket
|
||||
genannten Aliasse werden zusätzlich akzeptiert.
|
||||
|
||||
| Variable | Alias | Zweck |
|
||||
|---|---|---|
|
||||
| `SMTP_HOST`, `SMTP_PORT` | — | Relay |
|
||||
| `SMTP_SECURE` | — | `true` = implizites TLS (465), sonst STARTTLS. Ohne Angabe aus dem Port abgeleitet. |
|
||||
| `SMTP_USER`, `SMTP_PASSWORD` | `SMTP_PASS` | Authentifizierung (optional) |
|
||||
| `SMTP_FROM` | `MAIL_FROM` | Absenderadresse |
|
||||
| `MAIL_FROM_NAME` | — | Anzeigename (Default `Certvia`) |
|
||||
| `MAIL_REPLY_TO` | — | optionale Antwortadresse |
|
||||
| `APP_BASE_URL` | `AUTH_URL` | Basis für absolute Links in Mails |
|
||||
|
||||
**Fehlt die Konfiguration, wird nicht still versendet:** `getMailConfig()`
|
||||
liefert `null` samt Begründung, das MailLog bleibt `pending` mit Fehlertext, und
|
||||
die Admin-Konsole zeigt „Nicht konfiguriert". TLS wird erzwungen — gelockert nur
|
||||
gegen `localhost`/`mailpit`/`mailhog`, weil der lokale Test-SMTP kein gültiges
|
||||
Zertifikat hat.
|
||||
|
||||
---
|
||||
|
||||
## 4. Datenmodelle
|
||||
|
||||
- **`MailLog`** — Versandprotokoll: Empfänger, Template, Locale, Status
|
||||
(`pending|sent|failed|bounced|suppressed`), `providerMessageId`, Fehlertext,
|
||||
Versuchszähler, `dedupeKey` (unique). `tenantId` nullable für Plattform-Mails
|
||||
(`scope=platform`, analog `AuditLog`).
|
||||
**Bewusst nicht gespeichert:** Mail-Inhalt und jegliche Tokens.
|
||||
- **`NotificationPreference`** — je Nutzer und Ereignistyp. **Default opt-in:**
|
||||
fehlt die Zeile, wird versendet; erst ein ausdrückliches `email = false`
|
||||
unterdrückt. Die Pflege-UI folgt später — Modell und Auflösung stehen.
|
||||
|
||||
Beide in `TENANT_MODELS` und unter RLS (ENABLE + FORCE + `USING`/`WITH CHECK`,
|
||||
Migration `20260730180000_mail_fundament`, inkl. `GRANT` für `isms_app`).
|
||||
|
||||
---
|
||||
|
||||
## 5. Templates
|
||||
|
||||
Acht Templates, jeweils **de und en**, **HTML und Text**:
|
||||
`invitation`, `password_reset`, `password_changed`, `email_change_verify`,
|
||||
`email_changed_notice`, `mfa_changed`, `notification`, `test`.
|
||||
|
||||
Layout, Farben und die Fußzeile „Certvia — ein Produkt von GEFIM" kommen aus
|
||||
`src/lib/email-brand.ts` (Inline-Styles, Tabellenlayout für Outlook, absolute
|
||||
Asset-URLs).
|
||||
|
||||
**i18n-Abweichung mit Begründung:** die Sprachen liegen in einem eigenen
|
||||
Katalog (`src/server/mail/templates.ts`), nicht in `messages/*.json`. Die Mails
|
||||
werden im **Worker** gerendert — außerhalb eines Requests; die
|
||||
next-intl-Server-APIs (`getTranslations`) setzen einen Request-Scope voraus und
|
||||
stehen dort nicht zur Verfügung.
|
||||
|
||||
**Tokens:** Templates bekommen fertige `actionUrl`s. Erzeugt werden die Tokens
|
||||
in SEC2/SEC3/SEC4 — sie erscheinen weder im MailLog noch im Server-Log.
|
||||
|
||||
---
|
||||
|
||||
## 6. Benachrichtigungen
|
||||
|
||||
| Ereignis | Auslöser | Empfänger |
|
||||
|---|---|---|
|
||||
| `task_assigned` | `createTask`, `updateTask` (nur bei **Wechsel** des Zuständigen) | neuer Zuständiger |
|
||||
| `task_approval_requested` | `submitForApproval` (Richtlinien) | ausgewählter Freigeber |
|
||||
| `task_decided` | `approveTask` / `rejectTask` | Einreicher |
|
||||
| `task_due` | Fristen-Job (täglich) | Zuständiger |
|
||||
|
||||
Regeln: strikt mandantenisoliert, Sprache je Empfänger (Präferenz → Mandanten-
|
||||
Locale → `de`), **kein Selbstversand** über die eigene Handlung, Idempotenz über
|
||||
`dedupeKey` (der Fristen-Job hängt das Datum an → höchstens eine Erinnerung je
|
||||
Aufgabe und Tag). Fehler beim Versand werden geloggt, kippen aber nie die
|
||||
auslösende Fachaktion.
|
||||
|
||||
Benachrichtigungen tragen einen Präferenzhinweis in der Fußzeile;
|
||||
sicherheitsrelevante Transaktionsmails (Reset, Passwortwechsel) bewusst **nicht**
|
||||
— sie sind nicht abbestellbar.
|
||||
|
||||
---
|
||||
|
||||
## 7. Admin-Testversand
|
||||
|
||||
`/admin` zeigt Konfigurationszustand, Modus (Queue/inline) und die letzten zehn
|
||||
MailLog-Zeilen; der Button „Test-Mail senden" schickt an die **eigene** Adresse
|
||||
des angemeldeten Plattform-Admins (kein Empfängerfeld — die Funktion ist eine
|
||||
Zustellprüfung, kein Relay). Autorisierung über `requirePlatformSession()`;
|
||||
`mail.ts` ist in `scripts/check-module-guards.ts` als `EXEMPT` registriert.
|
||||
|
||||
---
|
||||
|
||||
## 8. Verifikation
|
||||
|
||||
```bash
|
||||
docker compose up -d mailhog # SMTP :1025, Weboberfläche :8025
|
||||
npx tsx scripts/test-mail.ts # Abnahmetest
|
||||
```
|
||||
|
||||
Der Test prüft: Rendering aller Templates in de/en (HTML + Text, Branding +
|
||||
Dachmarken-Fußzeile), Präferenzhinweis nur bei Benachrichtigungen, echten
|
||||
Versand mit `MailLog=sent` + `providerMessageId`, Idempotenz über `dedupeKey`
|
||||
und das Verhalten bei fehlender SMTP-Konfiguration.
|
||||
|
||||
Nachgewiesen am 30.07.2026 gegen Mailhog: alle Prüfungen grün, Nachricht kommt
|
||||
als `multipart/alternative` (HTML + Text) mit Absender `Certvia <…>`,
|
||||
`Auto-Submitted: auto-generated` und korrekter Fußzeile an.
|
||||
|
||||
Zusätzlich: `npx tsc --noEmit` → `npm run lint` → `npm run build` (Guard-Check).
|
||||
|
||||
---
|
||||
|
||||
## 9. Offene Punkte / Vorbedingungen
|
||||
|
||||
- **DNS:** SPF, DKIM und DMARC für die Absenderdomain müssen **vor** dem ersten
|
||||
Produktivversand aktiv sein (Ops, kein Code).
|
||||
- **Bounce-Verarbeitung:** `MailLog.status` kennt `bounced`, es gibt aber noch
|
||||
keinen Rückkanal (Webhook/IMAP). Erst mit einem Provider sinnvoll, der
|
||||
Bounces meldet.
|
||||
- **Präferenz-UI:** `NotificationPreference` ist modelliert und wird ausgewertet;
|
||||
die Pflegeoberfläche im Profil fehlt noch.
|
||||
- **Worker-Deployment:** `npm run worker:mail` muss in
|
||||
`docker-compose.coolify.yml` als eigener Service ergänzt werden (der
|
||||
vorhandene `worker`-Service im lokalen Compose zeigt noch auf keinen Befehl).
|
||||
@@ -0,0 +1,154 @@
|
||||
# SEC2 — Passwort-Self-Service, E-Mail-Änderung, Sessions
|
||||
|
||||
> Branch `dev-sec2-auth-selfservice` (Basis `dev-sec1-mail-smtp`) · Grundlage:
|
||||
> `docs/sicherheit/SEC2-Auth-SelfService-Detail.md` · **Abhängigkeit: SEC1**
|
||||
> (Templates `password_reset`, `password_changed`, `email_change_verify`).
|
||||
|
||||
Gilt durchgängig für **beide** Auth-Domänen: Mandanten-Nutzer (`/login`) und
|
||||
Plattform-Admins (`/platform/login`).
|
||||
|
||||
---
|
||||
|
||||
## 1. Token (`AuthToken`)
|
||||
|
||||
| Eigenschaft | Umsetzung |
|
||||
|---|---|
|
||||
| Erzeugung | 32 Byte CSPRNG, base64url |
|
||||
| Speicherung | **nur** SHA-256-Hash (`token_hash`, unique) — das Rohtoken existiert ausschließlich im Link |
|
||||
| Vergleich | konstante Zeit (`timingSafeEqual`) |
|
||||
| Gültigkeit | 60 Minuten (Reset und E-Mail-Verify) |
|
||||
| Single-use | `usedAt` per bedingtem `updateMany` (`usedAt: null`) → zwei parallele Einlösungen können nicht beide gewinnen |
|
||||
| Neuanforderung | entwertet offene Tokens desselben Typs |
|
||||
| Domänen | `principalType` = `tenant_user` \| `platform_admin`; `tenantId` nur bei Mandanten-Nutzern (trägt die RLS) |
|
||||
|
||||
Der Lookup beim Einlösen läuft über den **rohen** `prisma`-Client: Der Nutzer ist
|
||||
zu diesem Zeitpunkt nicht angemeldet, es gibt also keinen Mandantenkontext. Die
|
||||
RLS-Policy bleibt als zweite Verteidigungslinie bestehen (Migration
|
||||
`20260730190000_auth_tokens_sessions`).
|
||||
|
||||
---
|
||||
|
||||
## 2. Session-Invalidierung (`sessionsValidAfter`)
|
||||
|
||||
NextAuth v5 arbeitet hier mit **JWT (stateless)** — es gibt keine Session-Tabelle
|
||||
zum Leeren. Stattdessen trägt jedes Konto eine Versionsmarke:
|
||||
|
||||
- `sessionsValidAfter` wird gesetzt → jedes JWT mit älterem `iat` gilt als ungültig.
|
||||
- Geprüft dort, wo der Kontostatus **ohnehin** aus der DB gelesen wird — ohne
|
||||
zusätzliche Abfrage:
|
||||
`(app)/layout.tsx` (Seitenaufrufe), `moduleGuard` (Mutationen),
|
||||
`requirePlatformSession()` (Plattform).
|
||||
- Ohne `iat` wird **fail-closed** entschieden.
|
||||
|
||||
| Funktion | Wirkung |
|
||||
|---|---|
|
||||
| `invalidateSessions()` | alle Sitzungen — Passwort-Reset, E-Mail-Änderung, Deaktivierung |
|
||||
| `invalidateOtherSessions()` | Marke auf *eine Sekunde vor jetzt* → alle älteren Tokens fallen, die laufende Sitzung überlebt (Selbständerung) |
|
||||
|
||||
Der Sekundenversatz ist kein Zufall: `iat` hat Sekundenauflösung. Ohne ihn würde
|
||||
sich ein Nutzer bei der eigenen Passwortänderung selbst aussperren.
|
||||
|
||||
*Offen (P1, bewusst nicht in SEC2):* „aktive Sitzungen anzeigen und einzeln
|
||||
abmelden" — dafür bräuchte es Session-Records statt reiner JWTs.
|
||||
|
||||
---
|
||||
|
||||
## 3. Abläufe
|
||||
|
||||
### 3.1 Passwort vergessen (`/forgot-password`, `?domain=platform`)
|
||||
|
||||
- Antwort **immer identisch**, unabhängig davon, ob das Konto existiert.
|
||||
- Rate-Limit: 5 pro Stunde, je **IP** und je **Konto** getrennt gezählt.
|
||||
- Reset nur bei aktivem, nicht gesperrtem Konto. Deaktivierte Konten bekommen
|
||||
weder Mail noch abweichende Meldung.
|
||||
- Mandantenseite: existiert die Adresse in **mehreren** Mandanten, ist sie nicht
|
||||
eindeutig auflösbar → kein Reset (nach außen nicht unterscheidbar).
|
||||
|
||||
### 3.2 Einlösung (`/reset?token=…`)
|
||||
|
||||
- Die Seite **prüft** den Token nur; verbraucht wird er erst beim Absenden —
|
||||
sonst würde ein Link-Scanner im Mailserver den Link entwerten.
|
||||
- Ein **Policy-Verstoß entwertet den Link nicht**: geprüft wird vor dem
|
||||
Verbrauch, sonst wäre der Nutzer nach einem Tippfehler ausgesperrt.
|
||||
- Danach: Argon2id-Hash setzen, `mustChangePassword` löschen, Fehlversuchszähler
|
||||
und Sperre zurücksetzen, **alle Sessions invalidieren**, Bestätigungsmail,
|
||||
Audit (ohne Token).
|
||||
- **Kein Auto-Login** — der Nutzer meldet sich neu an.
|
||||
|
||||
### 3.3 Passwort selbst ändern (`/account`, `/platform/profile`)
|
||||
|
||||
Alt-Passwort verifizieren (generische Fehlermeldung, Rate-Limit), Policy prüfen,
|
||||
danach **andere** Sitzungen abmelden — die aktuelle bleibt. Bestätigungsmail + Audit.
|
||||
|
||||
### 3.4 E-Mail-Änderung (Double-Opt-in)
|
||||
|
||||
Alt-Passwort bestätigen → Verifizierungslink an die **neue** Adresse → Klick
|
||||
setzt die Adresse, entwertet alle Sessions (die Adresse ist die Login-Identität)
|
||||
und informiert die **alte** Adresse. Die Kollisionsprüfung läuft zweimal (bei
|
||||
Anforderung und bei Bestätigung), weil die Adresse zwischenzeitlich vergeben
|
||||
worden sein kann. Ob sie frei ist, wird nach außen nie gemeldet.
|
||||
|
||||
---
|
||||
|
||||
## 4. Rate-Limiting
|
||||
|
||||
`src/server/rate-limit.ts`, je Aktion getrennte Fenster, Schlüssel gehasht
|
||||
abgelegt (kein Klartext von Adressen oder IPs im Speicher):
|
||||
|
||||
| Aktion | Limit |
|
||||
|---|---|
|
||||
| Reset-Anfrage | 5 / Stunde |
|
||||
| Reset-Einlösung | 10 / 15 Min |
|
||||
| Alt-Passwort-Prüfung | 10 / 15 Min |
|
||||
| E-Mail-Änderung anfordern | 5 / Stunde |
|
||||
|
||||
**Bewusste Einschränkung:** Die Zähler liegen im Prozessspeicher, sind bei
|
||||
mehreren App-Instanzen also pro Instanz. Das ist vertretbar, weil der Limiter
|
||||
hier nur eine erste Bremse ist — die eigentlichen Garantien (single-use-Tokens,
|
||||
Enumeration-Neutralität, Konto-Lockout aus F-05) hängen nicht daran. Ein
|
||||
geteilter Redis-Zähler gehört zu **SEC5**.
|
||||
|
||||
---
|
||||
|
||||
## 5. Erreichbarkeit
|
||||
|
||||
`/forgot-password`, `/reset` und `/verify-email` sind in `src/proxy.ts` als
|
||||
öffentliche Pfade eingetragen — der Nutzer ist dort per Definition nicht
|
||||
angemeldet. Ihre Absicherung sind Rate-Limit, Enumeration-Neutralität und
|
||||
single-use-Tokens, nicht das Route-Gate.
|
||||
|
||||
---
|
||||
|
||||
## 6. Verifikation
|
||||
|
||||
```bash
|
||||
npx tsx scripts/test-auth-selfservice.ts # Token-, Limit- und Session-Eigenschaften
|
||||
npx tsx scripts/test-reset-flow.ts # End-to-End gegen ein Wegwerf-Konto
|
||||
```
|
||||
|
||||
Nachgewiesen am 30.07.2026, alle Prüfungen grün:
|
||||
|
||||
- Token liegt nur gehasht in der DB (SHA-256, 64 Hex), Rohtoken nie.
|
||||
- Single-use, Ablauf, Manipulation, Typ-Verwechslung und Neuanforderung greifen.
|
||||
- Rate-Limit blockt ab dem 6. Versuch, auch von wechselnder IP bei gleichem Konto.
|
||||
- Session-Marke: älteres JWT ungültig, neueres gültig, ohne `iat` fail-closed.
|
||||
- Kompletter Reset-Zyklus: Passwort gewechselt, altes ungültig, Sessions
|
||||
entwertet, Bestätigungsmail versendet, Audit ohne Token, zweite Einlösung
|
||||
abgewiesen, deaktiviertes Konto ohne Token.
|
||||
- Browser: `/reset` mit gültigem Link zeigt das Formular samt Mandanten-Policy,
|
||||
mit manipuliertem Link die generische Ablehnung.
|
||||
|
||||
Dazu `npx tsc --noEmit` → `npm run lint` → `npm run build` (Guard-Check).
|
||||
|
||||
---
|
||||
|
||||
## 7. Offene Punkte
|
||||
|
||||
- **Step-up-Re-Auth** für die E-Mail-Änderung und weitere kritische Aktionen →
|
||||
**SEC3** (aktuell reicht die Alt-Passwort-Bestätigung).
|
||||
- **Breach-Check** (HaveIBeenPwned) beim Setzen eines Passworts → **SEC5**; der
|
||||
Aufrufpunkt liegt in `redeemPasswordReset`/`changePasswordSelf` bereit.
|
||||
- **Geteiltes Rate-Limit** über Redis → SEC5.
|
||||
- **Aktive Sitzungen anzeigen/einzeln abmelden** (braucht Session-Records) → P1.
|
||||
- **Wartungsjob** für `purgeExpiredTokens()` ist implementiert, aber noch nicht
|
||||
eingeplant (passt in den SEC1-Scheduler).
|
||||
@@ -0,0 +1,78 @@
|
||||
# Secrets-Register — restore-/betriebs-kritische Schlüssel (certvia)
|
||||
|
||||
> Produkt: **certvia** (ISMS-Tool). Umsetzung der Härtung §5 (`docs/KONZEPT-haertung.md`)
|
||||
> und Backup-Konzept §9 (`docs/KONZEPT-backup-restore.md`). **Ops-/Governance-Dokument, kein Code.**
|
||||
> Strikt getrennt von jedem anderen Produkt (insb. „visitvia") — eigene Secrets, eigener Tresor-Bereich.
|
||||
|
||||
Dieses Register ist die **einzige verbindliche Übersicht**, welche Secrets es gibt, wer sie besitzt,
|
||||
wie (und ob) sie rotiert werden und wo sie liegen. **Führung: ISB.** Ablageort der Werte:
|
||||
**Org-Passwortmanager** (je Umgebung getrennter Ordner) **+ versiegelte Offline-Kopie**.
|
||||
|
||||
## Grundregeln (gelten für ALLE Einträge)
|
||||
|
||||
1. **Je Umgebung getrennt** — `test` / `dev` / `prod` haben **eigene, unterschiedliche** Werte.
|
||||
Niemals einen prod-Wert in test/dev wiederverwenden (oder umgekehrt).
|
||||
2. **Nie im Artefakt-Bucket** — Secrets liegen **niemals** im selben Bucket/Speicher wie die
|
||||
verschlüsselten Backups oder DSGVO-Exporte. **Verlust des Keys = Verlust der Wiederherstellbarkeit.**
|
||||
3. **Nie im Repo / nie im Backup-Artefakt** — kein Secret ins Git, keins ins Backup-Payload.
|
||||
Verteilung nur als Coolify-Env-Secret + Passwortmanager.
|
||||
4. **Versiegelte Offline-Kopie** — pro Umgebung eine versiegelte Offline-Kopie (z. B. verschlossener
|
||||
Umschlag / getrennter Offline-Tresor) für den Totalausfall des Passwortmanagers.
|
||||
5. **Rotation protokollieren** — jede Rotation mit Datum, Auslöser und ausführender Person im
|
||||
Passwortmanager-Eintrag vermerken.
|
||||
|
||||
## Register
|
||||
|
||||
| Secret | Zweck | Eigentümer (Owner) | Rotierbar? | Rotationsregel je Umgebung |
|
||||
|---|---|---|---|---|
|
||||
| `AUTH_SECRET` | Session-/JWT-Signatur (Auth.js) | ISB / Betrieb | **Ja** | Rotation invalidiert alle aktiven Sessions (Nutzer müssen neu einloggen). Bei Verdacht auf Kompromittierung sofort, sonst periodisch (z. B. jährlich). Je Umgebung eigener Wert. |
|
||||
| `MFA_ENC_KEY` | Verschlüsselung der TOTP-Secrets at-rest (AES-256-GCM) | ISB | **NEIN**¹ | **Nicht rotierbar ohne MFA-Neueinrichtung.** „Rotation" = Reset: alle Nutzer müssen MFA neu einrichten (alte TOTP-Secrets werden unlesbar). Nur bei Kompromittierung mit geplantem Reset. |
|
||||
| `PASSWORD_PEPPER` | Passwort-Pepper (Argon2-`secret`, Phase 1) | ISB | **NEIN**¹ | **Nicht rotierbar ohne Passwort-Reset für alle** (kein Rehash-on-Login). „Rotation" = Reset: erzwungener Passwort-Neusatz aller Konten. Bewusst **einmalig** gesetzt (leere DBs). |
|
||||
| `BACKUP_ENC_KEY` | Client-seitige Verschlüsselung des App-Backup-Exports (AES-256-GCM); Fallback `AUTH_SECRET` | ISB / Betrieb | **Bedingt**² | Neuer Key gilt nur für **neue** Artefakte; alte Backups bleiben nur mit dem **alten** Key entschlüsselbar → Altschlüssel bis Ablauf der Retention **aufbewahren**. Je Umgebung eigener Wert. |
|
||||
| pgBackRest-Repo-Key (`repo-cipher-pass`) | AES-256-Verschlüsselung des Cluster-Backup-Repos (Postgres WAL/Base) | Betrieb | **Ja**³ | Rotierbar mit Repo-Rekey; alte Repos/Artefakte brauchen den Altschlüssel → bis Retention-Ende aufbewahren. Je Umgebung eigenes Repo + eigener Key. |
|
||||
| `age`-Keypair | Verschlüsselung Per-Tenant-Export + DSGVO-Pakete (X25519) | ISB / DSB | **Ja**³ | Neuer Recipient gilt für **neue** Artefakte; Private Key der Alt-Keys bis Retention-Ende aufbewahren (sonst Alt-Exporte nicht entschlüsselbar). Je Umgebung eigenes Keypair. |
|
||||
| restic-Repo-Passwort | Verschlüsselung des MinIO-Objekt-Backups (restic, AES-256) | Betrieb | **Ja**³ | Rotierbar (`restic key add/remove`); Altschlüssel bis Retention-Ende gültig halten. Je Umgebung eigenes Repo + eigenes Passwort. |
|
||||
|
||||
¹ **Nicht-rotierbar markiert:** `PASSWORD_PEPPER` und `MFA_ENC_KEY` sind **keine** rotierbaren
|
||||
Secrets im üblichen Sinn — eine „Rotation" bedeutet einen **Reset/Neuverschlüsselung** mit
|
||||
Benutzer-Impact (Passwort- bzw. MFA-Neueinrichtung für alle). Deshalb **bewusst einmalig** setzen
|
||||
(solange DBs leer/frisch) und wie einen Wiederherstellungsschlüssel behandeln.
|
||||
|
||||
² `BACKUP_ENC_KEY` ist technisch tauschbar, aber jeder alte Backup-Stand bleibt an seinen
|
||||
Erzeugungs-Key gebunden → nicht „rotieren und alten Key wegwerfen".
|
||||
|
||||
³ Backup-Keys (pgBackRest / `age` / restic) sind rotierbar, aber **Altschlüssel müssen bis zum
|
||||
Ende der jeweiligen Retention aufbewahrt** werden, sonst werden ältere Backups unwiederherstellbar.
|
||||
|
||||
## ⚠ Restore-Kohärenz (verbindliche Vorbedingung)
|
||||
|
||||
**`PASSWORD_PEPPER`, `MFA_ENC_KEY` und `BACKUP_ENC_KEY` sind Umgebungs-Secrets und stehen NICHT
|
||||
im Backup-Artefakt.** Ein Restore in eine Umgebung mit **anderen** Secrets bricht:
|
||||
|
||||
- **anderer `PASSWORD_PEPPER`** → **alle** Passwort-Prüfungen schlagen fehl (kein Login möglich).
|
||||
- **anderes `MFA_ENC_KEY`** → TOTP-Secrets nicht entschlüsselbar → MFA-Prüfung bricht.
|
||||
- **anderes `BACKUP_ENC_KEY`** → das AES-256-GCM-Backup-Artefakt lässt sich **gar nicht** entschlüsseln.
|
||||
|
||||
**Vorbedingung vor jedem Restore** (auch im Restore-Runbook `docs/DEPLOY-PROD-CONTABO.md` verankert):
|
||||
Die Zielumgebung hält **exakt die Secrets, mit denen das Backup erzeugt wurde** — oder es wird
|
||||
ein **Passwort-/MFA-Reset bzw. eine Neuverschlüsselung eingeplant**. Ein Cross-Environment-Restore
|
||||
(z. B. prod → staging zum Debuggen) läuft nur mit den **prod-Secrets** oder mit anschließendem Reset.
|
||||
|
||||
## Ablage & Zugriff (Runbook-Kurzform)
|
||||
|
||||
- **Primär:** Org-Passwortmanager, je Umgebung getrennter Ordner, Zugriff rollenbasiert (ISB + Betrieb).
|
||||
- **Sekundär:** versiegelte Offline-Kopie je Umgebung (Notfall/DR).
|
||||
- **Verteilung an die App:** ausschließlich als Coolify-Env-Secret (Runtime), nie ins Repo/Image.
|
||||
- **Host-Encryption-Passphrase** (LUKS-Volume, s. `docs/DEPLOY-PROD-CONTABO.md`): ebenfalls hier
|
||||
führen — dieselben Grundregeln (getrennt je Umgebung, offline versiegelt, nie im Backup-Bucket).
|
||||
- **Bei Personalwechsel:** rotierbare Secrets (`AUTH_SECRET`, Backup-Keys) neu setzen; Zugriff im
|
||||
Passwortmanager entziehen. Nicht-rotierbare (`PASSWORD_PEPPER`/`MFA_ENC_KEY`) nur bei begründetem
|
||||
Kompromittierungsverdacht — dann mit geplantem Reset.
|
||||
|
||||
## Bezug / Weiterführendes
|
||||
|
||||
- `docs/KONZEPT-haertung.md` §5 (Register-Anforderung), §1–§3 (Pepper, Host-Encryption, Backups).
|
||||
- `docs/KONZEPT-backup-restore.md` §9 (gemeinsames Verschlüsselungs-Primitiv, Schlüsselverwaltung).
|
||||
- `docs/DEPLOY-PROD-CONTABO.md` (Host-Encryption + verschlüsselte Backups + Restore-Kohärenz, Ops-Runbook).
|
||||
- **Phase 2 (offen):** Upgrade-Pfad auf **HashiCorp Vault** / Provider-**KMS** (Rotation, Audit,
|
||||
Trennung) sowie **DB-Connection-TLS** (`sslmode`) — bewusst zurückgestellt, nicht Teil dieser Lane.
|
||||
+310
@@ -0,0 +1,310 @@
|
||||
# ISMS-Plattform – Umsetzungsspezifikation
|
||||
|
||||
> **Version 1.2** · Ergänzt gegenüber 1.1: **Assets & BIA als ein gemeinsames Modul**, zugeordnete Risiken in Asset-/Prozess-Detailansichten, ausgearbeitete **Risiko-Detailansicht** (Maßnahmen, betroffene Assets, Control-Verknüpfung, Verlauf).
|
||||
>
|
||||
> Diese Datei ist die Projekt-Spec für die Umsetzung durch Claude Code.
|
||||
> Sie beschreibt **Architektur, Datenmodell, Module, Rollen, API und Akzeptanzkriterien**.
|
||||
> Sprache der Anwendung: **Deutsch (i18n-fähig, EN vorbereitet)**.
|
||||
|
||||
## 0. Kontext & Leitentscheidungen
|
||||
|
||||
Es wird eine Web-Applikation zum Betrieb eines Informationssicherheits-Managementsystems (ISMS) entwickelt, die von mehreren Kunden (Mandanten) mit mehreren Nutzern und Rollen genutzt wird. Ausrichtung auf **ISO/IEC 27001:2022** und **TISAX / VDA-ISA 6.0**.
|
||||
|
||||
Getroffene Entscheidungen (aus Anforderungsklärung):
|
||||
|
||||
| Thema | Entscheidung |
|
||||
|---|---|
|
||||
| Betriebsmodell | Zentrale SaaS, **Multi-Tenant** (gemeinsame DB, Mandanten-ID + strikte Row-Level-Trennung) |
|
||||
| Container | Betrieb in Docker (Compose), horizontal skalierbar |
|
||||
| KI / Assistent + Chat | **Cloud-LLM** (Anthropic/OpenAI) über austauschbaren Provider-Adapter |
|
||||
| Tech-Stack | Modernes Web-Frontend, Technologie offen → **empfohlener Stack unten** |
|
||||
| Authentifizierung | **Lokale Accounts (MVP)** mit RBAC; SSO (OIDC/SAML) als spätere Erweiterung vorbereiten |
|
||||
| Umfang | Alle Module gleichwertig (kein hartes Phasing), aber sinnvolle Iterationsreihenfolge |
|
||||
| Norm-Inhalte | **ISO 27001:2022 Annex A (93 Controls)** vorbefüllt + SoA; **VDA-ISA** Struktur/Mapping vorbereitet, Katalog-Inhalte per Import (lizenzrechtlich, siehe §12) |
|
||||
| Sprache | Deutsch, i18n-ready |
|
||||
| UX | Modern, einfach, geringe Komplexität, Drag-and-Drop, grafische Oberflächen |
|
||||
|
||||
## 1. Empfohlener Tech-Stack
|
||||
|
||||
Ziel: **eine** Codebasis, geringe Betriebs- und Wartungskomplexität, moderne UX.
|
||||
|
||||
- **Frontend & Backend:** Next.js 15 (App Router, React 19, TypeScript) — SSR + API in einem Deployment.
|
||||
- **API-Layer:** tRPC (typsicher) oder REST (OpenAPI). Empfehlung: tRPC intern, zusätzlich schlanke REST-Endpunkte für Integrationen/Webhooks.
|
||||
- **ORM/DB:** Prisma + **PostgreSQL 16**. Vektorsuche für den Chat/RAG über **pgvector** (kein zusätzlicher Vektor-DB-Dienst nötig).
|
||||
- **Auth:** Auth.js (NextAuth) mit Credentials-Provider (lokale Accounts), Argon2id-Hashing, TOTP-2FA. OIDC/SAML-Provider als Feature-Flag vorbereitet.
|
||||
- **Hintergrundjobs / wiederkehrende Aufgaben:** BullMQ + Redis (Scheduler für Reviews, Audits, Fristen, Erinnerungen).
|
||||
- **Dateispeicher:** S3-kompatibel (MinIO im Compose-Stack), verschlüsselt.
|
||||
- **UI-Kit:** Tailwind CSS + shadcn/ui, Icons via lucide-react, Diagramme via Recharts.
|
||||
- **Drag-and-Drop:** dnd-kit (Kanban-Boards, Risiko-Matrix-Einordnung, Aufgaben, Datei-Uploads).
|
||||
- **KI-Anbindung:** Provider-Adapter (`AiProvider`-Interface) für Anthropic/OpenAI; RAG-Pipeline auf Dokumenten des Mandanten.
|
||||
- **E-Mail:** SMTP (Benachrichtigungen, Fristen, Eskalationen).
|
||||
- **Tests:** Vitest (Unit), Playwright (E2E). Linting: ESLint + Prettier.
|
||||
|
||||
> Alternative bei starkem KI-/Analytics-Fokus: zusätzlicher **Python-FastAPI-Microservice** nur für RAG/Embedding. Für geringe Komplexität zunächst **nicht** empfohlen — alles in Next.js.
|
||||
|
||||
## 2. Architektur (High-Level)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
Browser ───▶ │ Next.js (App Router) │
|
||||
(DE UI) │ - React UI (Tailwind + shadcn/ui, dnd-kit) │
|
||||
│ - tRPC/REST API │
|
||||
│ - Auth.js (RBAC, Mandanten-Guard) │
|
||||
└───────┬───────────────┬──────────────┬───────┘
|
||||
│ │ │
|
||||
Prisma BullMQ AiProvider
|
||||
│ (Worker) (Adapter)
|
||||
┌───────▼───────┐ ┌───▼────┐ ┌────▼─────────┐
|
||||
│ PostgreSQL 16 │ │ Redis │ │ Anthropic / │
|
||||
│ + pgvector │ │ │ │ OpenAI API │
|
||||
└───────────────┘ └────────┘ └──────────────┘
|
||||
┌───────────────┐
|
||||
│ MinIO (S3) │ Dokumente, Nachweise, Uploads
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
**Mandantenfähigkeit (Multi-Tenant):** Jede fachliche Tabelle trägt `tenant_id`. Zugriff ausschließlich über einen zentralen Prisma-Middleware-/Query-Guard, der `tenant_id` aus der Session erzwingt (Row-Level-Isolation). Zusätzlich Postgres **Row Level Security (RLS)** als zweite Verteidigungslinie. Kein Query ohne Mandantenkontext.
|
||||
|
||||
## 3. Rollen- und Rechtemodell (RBAC)
|
||||
|
||||
Rollen sind pro Mandant vergeben. Ein Nutzer kann mehrere Rollen haben.
|
||||
|
||||
| Rolle | Beschreibung | Kernrechte |
|
||||
|---|---|---|
|
||||
| **Plattform-Admin** (mandantenübergreifend) | Betreiber der SaaS | Mandanten anlegen/sperren, globale Kataloge pflegen, keine Einsicht in Kundendaten außer für Support (protokolliert) |
|
||||
| **Mandanten-Admin** | Kundenadministrator | Nutzer/Rollen im Mandanten verwalten, Stammdaten, Konfiguration |
|
||||
| **ISB / CISO** | Informationssicherheitsbeauftragter | Vollzugriff fachlich: Risiken, Assets, BIA, Maßnahmen, Vorfälle, Freigaben, Chat-Eskalationsziel |
|
||||
| **Auditor** (intern/extern) | Prüfer | Lesezugriff + Audit-Durchführung, Findings anlegen, keine Bearbeitung der Fachdaten |
|
||||
| **Asset-/Risk-Owner** | Fachverantwortliche | Bearbeitung zugewiesener Assets/Risiken/Maßnahmen |
|
||||
| **Mitarbeiter / User** | Standardnutzer | Chat nutzen, Richtlinien lesen, Vorfälle melden, eigene Aufgaben |
|
||||
|
||||
Rechte werden als granulare **Permissions** (`asset:read`, `risk:write`, `incident:manage`, …) implementiert und über Rollen gebündelt. UI blendet nicht-erlaubte Aktionen aus; API prüft serverseitig.
|
||||
|
||||
## 4. Module (funktionaler Kern)
|
||||
|
||||
### 4.1 Assets & BIA (ein gemeinsames Modul)
|
||||
|
||||
Asset-Inventar und Business Impact Analyse bilden **ein zusammenhängendes Modul** (gemeinsamer Navigationsbereich, durchgängige Detailansichten). Assets, Prozesse und deren Kritikalität werden im selben Kontext gepflegt.
|
||||
|
||||
#### 4.1.1 Asset-Inventar
|
||||
Zentrales Verzeichnis aller Werte (Assets): Informationen, Systeme, Anwendungen, Standorte, Lieferanten, Personen/Rollen, Datenkategorien.
|
||||
|
||||
- Attribute: Name, Typ, Owner, Standort/Prozesszuordnung, Klassifizierung (C/I/A — Vertraulichkeit/Integrität/Verfügbarkeit als Schutzbedarf 1–4), Lieferanten/Verantwortliche, Status, Tags.
|
||||
- Beziehungen zwischen Assets (Abhängigkeiten) modellierbar → speist BIA und Risiko.
|
||||
- Import/Export (Excel/CSV), Bulk-Bearbeitung, Versionshistorie.
|
||||
- **Grafische Ansicht:** filterbare Tabelle + optionale Abhängigkeits-/Netzwerkgrafik.
|
||||
- **Asset-Detailansicht** zeigt neben Stammdaten und Beziehungen auch:
|
||||
- **Zugeordnete Risiken** (mit Risikowert, Status, Behandlung) inkl. Absprung in die Risiko-Detailansicht,
|
||||
- zugeordnete Prozesse (mit Rolle primär/sekundär) und daraus vererbter Schutzbedarf,
|
||||
- verknüpfte Maßnahmen, Vorfälle und Nachweise.
|
||||
|
||||
#### 4.1.2 Business Impact Analyse (BIA)
|
||||
Ermittelt Kritikalität von Prozessen/Assets und Wiederanlaufparameter.
|
||||
|
||||
- Erfassung von Geschäftsprozessen, Zuordnung zu Assets.
|
||||
- **Asset-Rollen je Prozess (Detailansicht):** In der Prozess-Detailansicht werden die zugeordneten Assets nach Rolle unterschieden:
|
||||
- **Primäres Asset** = das im Prozess erzeugte/verantwortete Ergebnis-Asset (z. B. der erzeugte Datensatz/das Informationsobjekt). Genau ein oder wenige je Prozess.
|
||||
- **Sekundäre Assets** = alle unterstützenden Assets, die zur Prozessdurchführung benötigt werden (Systeme, Anwendungen, Infrastruktur, Personen/Rollen, Lieferanten).
|
||||
- Die Rollenzuordnung speist die Abhängigkeitsanalyse (siehe 4.11) und die Schutzbedarfsvererbung: Der Schutzbedarf des primären Assets/Prozesses vererbt sich auf die sekundären Assets (max. Prinzip).
|
||||
- Schadensszenarien und Schadenshöhe je Schutzziel und Zeitverlauf.
|
||||
- Kennzahlen: **RTO, RPO, MTD/MTPD**, maximal tolerierbarer Ausfall.
|
||||
- Ergebnis: Kritikalitätsstufe je Prozess/Asset → priorisiert Risikoanalyse und Maßnahmen.
|
||||
- **Prozess-Detailansicht** zeigt zusätzlich die **zugeordneten Risiken** des Prozesses und seiner Assets (aggregiert, mit Risikowert und Status).
|
||||
- Geführter Wizard (Schritt-für-Schritt), Ergebnis als Report exportierbar.
|
||||
|
||||
### 4.2 Risikoanalyse & -behandlung
|
||||
Aufbauend auf Assets + BIA.
|
||||
|
||||
- Risiken = (Asset/Prozess) × Bedrohung × Schwachstelle.
|
||||
- Bewertung: Eintrittswahrscheinlichkeit × Auswirkung → Risikowert; konfigurierbare Skalen (z. B. 5×5).
|
||||
- **Interaktive Risiko-Matrix (Heatmap)** mit Drag-and-Drop-Einordnung/Filter.
|
||||
- Risikobehandlung: Vermeiden / Vermindern / Übertragen / Akzeptieren; Maßnahmen (Controls) verknüpfen.
|
||||
- Rest-Risiko nach Maßnahme, Risikoakzeptanz mit Freigabe-Workflow (ISB/Leitung).
|
||||
- Vererbung: Schutzbedarf aus Asset/BIA wird vorbelegt.
|
||||
- Verknüpfung zu ISO-27001-Annex-A-Controls und VDA-ISA-Zielen (SoA-Bezug).
|
||||
- **Risiko-Detailansicht (vollständig):**
|
||||
- Stammdaten: Beschreibung, Bedrohung/Schwachstelle, Owner, Status, Termine/Reviews.
|
||||
- Bewertung: Brutto-Risiko (Wahrscheinlichkeit × Auswirkung), **Rest-Risiko** nach Maßnahmen, Bewertungshistorie (Verlauf des Risikowerts über Zeit).
|
||||
- **Notwendige/verknüpfte Maßnahmen:** Liste der behandelnden Maßnahmen mit Status, Fälligkeit und Owner; neue Maßnahme direkt aus dem Risiko heraus anlegbar.
|
||||
- **Betroffene Assets/Prozesse:** alle verknüpften Assets und Prozesse mit Schutzbedarf/Kritikalität, Absprung in deren Detailansichten.
|
||||
- Verknüpfte Annex-A-Controls / VDA-ISA-Ziele (SoA-Bezug) und ggf. auslösende Vorfälle.
|
||||
- Freigabe-/Akzeptanz-Workflow mit Kommentar und Audit-Trail.
|
||||
|
||||
### 4.3 Control-Kataloge & Statement of Applicability (SoA)
|
||||
- **ISO 27001:2022 Annex A** mit 93 Controls in 4 Themen (Organisatorisch 37, Personenbezogen 8, Physisch 14, Technologisch 34) **vorbefüllt**.
|
||||
- **SoA:** je Control Anwendbarkeit (ja/nein + Begründung), Umsetzungsstatus, Verweise auf Maßnahmen/Nachweise, Verantwortliche.
|
||||
- **VDA-ISA 6.0**: 9 Kapitel/Prüfziele als Struktur + Mapping-Tabelle ISO↔VDA-ISA (siehe §12 zur Lizenz).
|
||||
- Reifegrad-Bewertung (VDA-ISA-Reifegradmodell 0–5) je Prüfziel.
|
||||
|
||||
### 4.4 Maßnahmenverwaltung (Controls/Tasks)
|
||||
- Maßnahmen mit Owner, Fälligkeit, Status, Priorität, Nachweisen (Dateien).
|
||||
- **Kanban-Board (Drag-and-Drop)** und Listen-/Kalenderansicht.
|
||||
- Verknüpfung zu Risiken, Controls, Vorfällen, Audits.
|
||||
- **Maßnahmen-Detailansicht** zeigt die **zugeordneten Risiken** (welche Risiken behandelt diese Maßnahme, mit Risikowert vor/nach) sowie verknüpfte Controls, Vorfälle und Nachweise.
|
||||
|
||||
### 4.5 Wiederkehrende Aufgaben & Fristen (Scheduler)
|
||||
Automatische Erzeugung/Erinnerung für u. a.:
|
||||
- **Benutzer-/Zugriffs-Review** (z. B. quartalsweise),
|
||||
- **Interne Audits** und **externe Audits/Re-Zertifizierung** (Zyklen),
|
||||
- **Management-Review**, Richtlinien-Review, Risiko-Review, Lieferanten-Review.
|
||||
- Konfigurierbare Wiederholung (cron-artig), Zuweisung, Eskalation bei Überfälligkeit, E-Mail-Benachrichtigung, Dashboard-Fälligkeitsanzeige.
|
||||
|
||||
### 4.6 Richtlinien-Management & Implementierungs-Assistent
|
||||
- Richtlinien-Bibliothek mit Versionierung, Freigabe- und Lese-Bestätigungs-Workflow.
|
||||
- **KI-Assistent** führt Nutzer durch die Anpassung von Muster-Richtlinien an das eigene Unternehmen.
|
||||
- **Zwei Individualisierungs-Ebenen:**
|
||||
1. **Basisdaten/Metadaten:** Firmenname, verantwortliche Rollen, Geltungsbereich, Platzhalter.
|
||||
2. **Inhaltliche Anpassung der Klauseln:** Die KI formuliert und passt die eigentlichen Richtlinientexte (Klauseln/Abschnitte) auf Basis der Unternehmensangaben an (z. B. erlaubte Geräte, Fristen, Verantwortlichkeiten, branchenspezifische Anforderungen). Vorschläge sind akzeptier-/verwerfbar.
|
||||
- **Inline-Editor (WYSIWYG):** Nutzer bearbeiten die generierten Klauseltexte direkt im Tool; KI-Assistenz („umformulieren", „kürzen", „an Control X ausrichten") auf Absatzebene.
|
||||
- **In-Tool-Darstellung:** Die Richtlinie wird innerhalb der Anwendung gerendert lesbar dargestellt (formatierte Ansicht, Inhaltsverzeichnis, verknüpfte Controls), nicht nur als Download.
|
||||
- **Governance:** Versionierung mit Änderungsverlauf/Diff, Freigabe-Workflow, Lesebestätigung durch Mitarbeiter, Verknüpfung zu ISO-/VDA-Controls.
|
||||
- Export als PDF/DOCX; Ablage in der Richtlinien-Bibliothek; Anbindung an den Chat (RAG) als Wissensquelle.
|
||||
|
||||
### 4.7 Interaktiver Chat (RAG + Eskalation)
|
||||
- Nutzer stellen Fragen; der Chat sucht per **RAG** in der Dokumentation/Richtlinien des Mandanten (pgvector) und antwortet mit Quellenangabe.
|
||||
- Wenn keine belastbare Antwort/Berechtigung → **Eskalation/Ticket an den ISB** (Weiterleitung, Benachrichtigung, Nachverfolgung).
|
||||
- Nur mandanten-eigene Dokumente im Kontext; keine mandantenübergreifende Vermischung.
|
||||
|
||||
### 4.8 Sicherheitsvorfall-Management (Incident)
|
||||
- Meldung von Vorfällen (auch niedrigschwellig durch Mitarbeiter, Formular + Chat).
|
||||
- Workflow: Erfassung → Triage/Kategorisierung → Bearbeitung → Eskalation → Abschluss → Lessons Learned.
|
||||
- Schweregrad, betroffene Assets, SLA/Fristen, Aufgaben, Zeitleiste, Nachweise.
|
||||
- Verknüpfung zu Risiken (neue/erhöhte Risiken) und ggf. Meldepflichten-Hinweis.
|
||||
|
||||
### 4.9 Dashboards & Reporting
|
||||
- Rollenbezogene Dashboards (ISB, Auditor, Owner): offene Risiken, überfällige Aufgaben, SoA-Erfüllungsgrad, Reifegrade, Vorfälle.
|
||||
- Exporte: SoA, Risikoregister, Maßnahmenplan, Audit-Report, Management-Review — als PDF/Excel.
|
||||
|
||||
### 4.10 Audit-Management
|
||||
- Audit-Plan (intern/extern), Scope, Prüfpunkte (aus Katalogen), Findings, Maßnahmen aus Findings, Nachverfolgung, Audit-Report.
|
||||
|
||||
### 4.11 Abhängigkeits- & Kritische-Pfade-Analyse
|
||||
Visualisiert die Verkettung von Prozessen und Assets, um Single Points of Failure und kritische Pfade sichtbar zu machen.
|
||||
|
||||
- **Netzwerkgraph:** Knoten = Prozesse und Assets (primär/sekundär), Kanten = Abhängigkeiten (aus Asset-Relationen und BIA-Rollenzuordnung).
|
||||
- **Kritische Pfade** werden anhand von Kritikalität/Schutzbedarf (aus BIA) berechnet und farblich hervorgehoben; Engstellen (Assets, von denen viele kritische Prozesse abhängen) werden markiert.
|
||||
- Interaktiv: Filtern nach Prozess/Kritikalität, Knoten anklicken → Detail/Sprung zum Asset, Hervorheben aller abhängigen Elemente.
|
||||
- Speist Risikoanalyse (Konzentrationsrisiken) und BCM/Notfallplanung.
|
||||
- Umsetzungshinweis: Rendering mit einer Graph-Bibliothek (z. B. Cytoscape.js oder D3-Force); Datenbasis sind `AssetRelation` und die BIA-Primär-/Sekundär-Zuordnung.
|
||||
|
||||
### 4.12 Nachweis- & Dokumentenmanagement
|
||||
- Zentrale, auditfeste Ablage für Nachweise/Evidenzen (Dateien, Screenshots, Protokolle).
|
||||
- Verknüpfung eines Nachweises mit Controls (SoA), Maßnahmen, Audits, Risiken und Vorfällen.
|
||||
- Metadaten: Gültigkeit/Ablaufdatum, Verantwortliche, Version, Vertraulichkeit; Erinnerung bei ablaufenden Nachweisen.
|
||||
- Volltext-/Metadatensuche; Nachweise sind Quelle für den RAG-Chat.
|
||||
|
||||
### 4.13 Lieferanten- & Dienstleister-Management (Third-Party)
|
||||
Für TISAX besonders relevant.
|
||||
|
||||
- Verzeichnis externer Dienstleister/Lieferanten mit Kontakt, Leistungen, Kritikalität.
|
||||
- Sicherheitsbewertung/Fragebögen, Zertifikatsnachweise (z. B. ISO 27001/TISAX-Label), Ablaufüberwachung.
|
||||
- Vertrags-/AV-Verwaltung (DSGVO Art. 28), Wiedervorlage/Review-Zyklen (siehe wiederkehrende Aufgaben).
|
||||
- Verknüpfung zu Assets (welcher Dienstleister betrifft welche Assets) und Risiken (Third-Party-Risiko).
|
||||
|
||||
### 4.14 Management-Review & Kennzahlen (KPIs)
|
||||
ISO-27001-Pflichtthemen zur Wirksamkeitsmessung.
|
||||
|
||||
- Definierbare Kennzahlen/Metriken (z. B. SoA-Erfüllungsgrad, offene Risiken, Reaktionszeiten Vorfälle, überfällige Aufgaben, Reifegradentwicklung) mit Zielwerten und Trend.
|
||||
- Strukturierte **Management-Review**-Vorlage (Eingaben, Ergebnisse, Beschlüsse, Verantwortliche, Termine) mit Historie.
|
||||
- Wirksamkeitsbewertung von Maßnahmen; Export als Management-Report (PDF).
|
||||
|
||||
## 5. Datenmodell (Kern-Entitäten, vereinfacht)
|
||||
|
||||
Alle fachlichen Tabellen enthalten `tenant_id`, `created_at`, `updated_at`, `created_by`.
|
||||
|
||||
- **Tenant**(id, name, status, config)
|
||||
- **User**(id, tenant_id, email, password_hash, name, status, mfa_secret)
|
||||
- **Role**(id, tenant_id, key, name) / **Permission** / **UserRole** / **RolePermission**
|
||||
- **Asset**(id, tenant_id, name, type, owner_id, classification_c/i/a, status, tags)
|
||||
- **AssetRelation**(asset_id, related_asset_id, type)
|
||||
- **Process**(id, tenant_id, name, owner_id) — BIA-Bezug
|
||||
- **ProcessAsset**(id, tenant_id, process_id, asset_id, **role** = `primary` | `secondary`) — Asset-Rolle je Prozess (BIA)
|
||||
- **BiaEntry**(id, tenant_id, process_id, rto, rpo, mtd, impact_scores, criticality)
|
||||
- **Threat** / **Vulnerability** (Kataloge, teils global)
|
||||
- **Risk**(id, tenant_id, asset_id/process_id, threat_id, likelihood, impact, score, treatment, residual_score, owner_id, status)
|
||||
- **RiskAsset**(risk_id, asset_id) — n:m betroffene Assets je Risiko (zusätzlich zum Hauptbezug)
|
||||
- **RiskMeasure**(risk_id, measure_id) — n:m Risiko ↔ behandelnde Maßnahmen
|
||||
- **Control**(id, framework, ref, title, theme) — global (ISO/VDA)
|
||||
- **Soa**(id, tenant_id, control_id, applicable, justification, status, maturity, owner_id)
|
||||
- **Measure/Task**(id, tenant_id, title, owner_id, due_date, status, priority, links[])
|
||||
- **RecurringTask**(id, tenant_id, type, schedule_cron, next_run, assignee)
|
||||
- **Policy**(id, tenant_id, title, version, status, body, ack_required)
|
||||
- **Document/Evidence**(id, tenant_id, name, storage_key, embedding[] via pgvector)
|
||||
- **ChatSession/ChatMessage**(…, sources[], escalated_to_isb)
|
||||
- **Incident**(id, tenant_id, title, severity, status, category, affected_assets[], timeline[])
|
||||
- **Audit**(id, tenant_id, type, scope, planned_date) / **Finding**(…)
|
||||
- **Supplier**(id, tenant_id, name, criticality, contract_ref, av_status, cert_status, cert_expiry, review_cron) / **SupplierAsset**(supplier_id, asset_id)
|
||||
- **Kpi**(id, tenant_id, name, target, unit) / **KpiValue**(kpi_id, period, value)
|
||||
- **ManagementReview**(id, tenant_id, date, inputs, results, decisions, owner_id)
|
||||
- **AuditLog**(id, tenant_id, actor, action, entity, before/after, timestamp)
|
||||
|
||||
## 6. API-Design (Auszug)
|
||||
|
||||
REST-/tRPC-Ressourcen je Modul mit CRUD + Aktionen:
|
||||
`/assets`, `/bia`, `/risks`, `/controls`, `/soa`, `/measures`, `/recurring-tasks`, `/policies`, `/chat`, `/incidents`, `/audits`, `/reports`, `/admin/tenants`, `/admin/users`.
|
||||
|
||||
Querschnitt: `GET /export/{modul}` (Excel/PDF), `POST /import/{modul}` (Excel/CSV), Webhooks für Fristen/Eskalationen. Jede Anfrage: Auth-Guard → Mandanten-Guard → Permission-Check → Handler → AuditLog.
|
||||
|
||||
## 7. Nicht-funktionale Anforderungen
|
||||
|
||||
- **Sicherheit:** Verschlüsselung at-rest (DB/Objektspeicher) und in-transit (TLS), Argon2id-Passwörter, TOTP-2FA, Session-Härtung, CSRF-/XSS-/SQLi-Schutz, striktes RBAC + Mandanten-Isolation (RLS), vollständiges Audit-Log.
|
||||
- **Datenschutz (DSGVO):** Auftragsverarbeitung, Löschkonzept, Datenminimierung; für Cloud-LLM: DPA mit KI-Anbieter, konfigurierbares Opt-out des Trainings, optionale Anonymisierung sensibler Felder vor KI-Aufruf.
|
||||
- **Performance:** Listen mit Server-Pagination/Filter; Zielantwortzeit < 300 ms für Standardabfragen.
|
||||
- **Verfügbarkeit:** Stateless App-Container (horizontal skalierbar), Backups DB + Objektspeicher, Health-/Readiness-Endpunkte.
|
||||
- **Barrierefreiheit & UX:** WCAG-AA-orientiert, responsive, konsistente Komponenten, geringe Klicktiefe.
|
||||
- **i18n:** Alle UI-Texte über Message-Katalog (de default, en vorbereitet).
|
||||
- **Nachvollziehbarkeit:** Versionierung von Richtlinien, Risiken, SoA; lückenloses Änderungsprotokoll (auditfest).
|
||||
|
||||
## 8. Deployment (Docker)
|
||||
|
||||
`docker-compose.yml` mit Services: `app` (Next.js), `worker` (BullMQ), `postgres` (pgvector-Image), `redis`, `minio`, optional `mailhog` (Dev). Konfiguration über `.env` (DB, Redis, S3, SMTP, `AI_PROVIDER`, `AI_API_KEY`). Migrations via Prisma. Seed-Skript befüllt globale Kataloge (ISO Annex A, VDA-ISA-Struktur, Threat-/Vuln-Beispiele) und einen Demo-Mandanten.
|
||||
|
||||
## 9. UX-Leitlinien
|
||||
|
||||
Modern, aufgeräumt, geringe Komplexität. Konsequenter Einsatz von: geführten Wizards (BIA, Richtlinien-Assistent), **Drag-and-Drop** (Kanban für Maßnahmen/Aufgaben, Risiko-Heatmap, Datei-Uploads), grafischen Auswertungen (Heatmaps, Reifegrad-Radar, Fortschrittsbalken), Inline-Bearbeitung und klaren, rollenbezogenen Startseiten. Fachbegriffe mit Tooltips erklärt.
|
||||
|
||||
Das HTML-Mockup (`docs/ISMS-Prototyp-GEFIM.html`) dient als **Orientierung** für Navigation, Layout und Views — die Module werden fachlich darüber hinaus vervollständigt (z. B. Risiko-Verknüpfungen in Detailansichten, siehe §4).
|
||||
|
||||
## 10. Akzeptanzkriterien (Definition of Done je Modul)
|
||||
|
||||
- Ein Nutzer eines Mandanten sieht **niemals** Daten eines anderen Mandanten (durch Test nachgewiesen: RLS + Guard).
|
||||
- RBAC serverseitig erzwungen; UI blendet unerlaubte Aktionen aus.
|
||||
- Asset → BIA → Risiko → SoA/Maßnahme bilden eine durchgängige, verknüpfte Kette — in beide Richtungen navigierbar (Asset zeigt Risiken, Risiko zeigt Maßnahmen/Assets, Maßnahme zeigt Risiken).
|
||||
- Wiederkehrende Aufgaben erzeugen automatisch Instanzen, benachrichtigen und eskalieren bei Überfälligkeit.
|
||||
- Chat beantwortet Fragen mit Quellen aus Mandanten-Dokumenten und eskaliert korrekt an den ISB.
|
||||
- Incident-Workflow von Meldung bis Abschluss inkl. Zeitleiste und Nachweisen.
|
||||
- Exporte (SoA, Risikoregister, Audit-Report) erzeugen valide PDF/Excel.
|
||||
- E2E-Tests (Playwright) für die Kernpfade grün; Audit-Log erfasst alle schreibenden Aktionen.
|
||||
|
||||
## 11. Empfohlene Umsetzungsreihenfolge (Iterationen)
|
||||
|
||||
Auch wenn Module gleichwertig sind, minimiert diese Reihenfolge das Risiko:
|
||||
|
||||
1. **Fundament:** Projektsetup, Docker-Compose, Auth (lokale Accounts), Mandanten-Isolation (RLS + Guard), RBAC, Audit-Log, i18n-Gerüst.
|
||||
2. **Kern-Fachdaten:** Assets & BIA (ein Modul) → Risikoanalyse (inkl. Heatmap + Detailansicht).
|
||||
3. **Compliance:** ISO-Annex-A-Katalog + SoA, VDA-ISA-Struktur + Mapping, Reifegrade.
|
||||
4. **Betrieb:** Maßnahmen-Kanban, wiederkehrende Aufgaben/Scheduler, Benachrichtigungen.
|
||||
5. **Vorfälle:** Incident-Management inkl. Meldeformular.
|
||||
6. **KI:** RAG-Chat mit Eskalation, Richtlinien-Implementierungs-Assistent.
|
||||
7. **Auswertung:** Dashboards, Reporting/Exporte, Audit-Management.
|
||||
8. **Härtung:** Sicherheits-/Datenschutz-Review, Tests, Doku.
|
||||
|
||||
## 12. Lizenz-/Rechtshinweis zu Katalog-Inhalten (empfohlenes Vorgehen)
|
||||
|
||||
- **ISO 27001:2022** Control-**Titel/Referenzen** (Annex A, A.5–A.8) können als Katalog abgebildet werden; der **volle Normtext** ist urheberrechtlich geschützt und darf nicht mitgeliefert werden. → Nur Kurzbezeichnungen + eigene Umsetzungshinweise, Volltext verweist der Kunde auf seine erworbene Norm.
|
||||
- **VDA-ISA 6.0 / TISAX:** Der ISA-Katalog wird vom VDA/ENX bereitgestellt (ISA6 als Excel). Empfehlung: **Struktur (9 Kapitel/Prüfziele) und Mapping** abbilden, die konkreten Katalog-Inhalte per **Import** aus der offiziellen ENX-Datei einspielen (Import-Funktion für `ISA6-EN.xlsx`). So bleibt die Anwendung lizenzkonform und aktualisierbar.
|
||||
- **Mapping ISO 27001 ↔ VDA-ISA** als pflegbare Tabelle vorsehen (Controls beeinflussen mehrere Prüfziele und umgekehrt).
|
||||
|
||||
## 13. Offene Punkte / spätere Erweiterungen
|
||||
|
||||
- SSO (OIDC/SAML, z. B. Entra ID) — Feature-Flag bereits vorgesehen.
|
||||
- Self-hosted-LLM-Option je Mandant (falls Datenschutzanforderungen es verlangen).
|
||||
- Meldepflichten-Assistent (NIS2/DSGVO-Fristen) im Incident-Modul.
|
||||
- Mobile App / PWA für Vorfallmeldung.
|
||||
|
||||
---
|
||||
|
||||
### Quellen
|
||||
- VDA-ISA / TISAX Katalog v6.0: https://portal.enx.com/en-us/TISAX/downloads/
|
||||
- VDA ISA 6.0 verpflichtend: https://vda-isa-berater.com/en/mandatory-vda-isa-catalog-version-6-0-for-all-those-who-order-the-tisax-assessment-now/
|
||||
- VDA Information Security: https://www.vda.de/en/topics/digitization/data/information-security
|
||||
@@ -0,0 +1,404 @@
|
||||
# Entwicklungsstand `dev` — Konsolidierte Übergabe (PM + neue Entwickler)
|
||||
|
||||
> Stand: 2026-07-30 · Branch **`dev`** · **Sync-Hinweis:** lokal **deutlich vor `origin/dev`** (`origin/dev` = `9b479ab`); enthält u. a. Prod-Deployment-Vorbereitung, Wizard-Kickoff + Story A1-1 und diese Doku. `dev` ist auf **`origin` (git.certvia.de)** und **`local-gitea` (intern)** gepusht. Vor dem nächsten Push zuerst `git fetch` und prüfen, ob niemand weitere Commits hat. **Alle Feature-Branches** (Dev A: A1–A8; Dev B: F1–F4, B1–B7 inkl. Prüfziel-Follow-up) sowie **Certvia-Branding**, der **Wizard-Parallelisierungs-Fix** und zuletzt das **Security-Härtungspaket P1/P2/P3 (F-01…F-20, u. a. RLS scharf F-04, moduleGuard-DB-Authz F-06, MFA-Replay, Container-/Supply-Chain-Härtung F-11/F-18)** sowie **SEC1 (Mailversand/Queue)**, **SEC2 (Auth-Self-Service: Passwort-Reset/-Wechsel/E-Mail-Änderung, Session-Invalidierung, Rate-Limit)** und zuletzt die **TISAX-Umstrukturierung (M0–M4: Fundament, Strukturanalyse, Cockpit mit RACI/Evidence, Audit-Wizard, TISAX-Tasks, Wizard-Neustruktur; v3: Prozesshaus + geführtes BIA je Prozess)** sowie **SEC3/SEC4 (MFA pro Mandant erzwingen, WebAuthn/Passkeys, TOTP-Verschlüsselung at rest, Plattform-Admin-Verwaltung)** sind per DevOps-Integration additiv nach `dev` konsolidiert (Gate grün); noch offene Feature-Branches rebasen auf `dev`. **Deployment-Pflichtschritte** aus dem Security-Paket siehe §1a (F-04 RLS scharfschalten, F-06×F-10 `scripts/sync-role-permissions.ts` nach `migrate`). **SEC1/SEC2 fürs Deployment:** eigener **Mail-Worker-Service** (`npm run worker:mail` = `scripts/mail-worker.ts`) nötig, echte **SMTP-Variablen** setzen, und die Queue nutzt **Redis** (`REDIS_URL` mit Passwort, BullMQ/ioredis) — der Worker fehlt noch in `docker-compose.coolify.yml`. · Basis-Doku: `docs/HANDOVER-DEV.md`, `docs/HANDOVER-PM.md`, `docs/SPEC.md`
|
||||
> Zweck: Ein Dokument, das den kompletten Stand der Weiterentwicklung auf `dev` zusammenfasst — fachlich (für PM) und technisch (für einen neuen Entwickler). `dev` ist noch **nicht** nach `main` gemergt.
|
||||
|
||||
> **Neu (2026-08-07):** `feature/settings-roles-platform-ui` integriert (Einstellungen umstrukturiert: Risikokriterien/Rollen als Menü-Karten + Link zur Plattform-Administration; neue Route `/settings/risk-criteria`). Zusätzlich **Audit-Trail einsehbar je Mandant**: wiederverwendbares server-gerendertes Popup (`src/components/audit-trail.tsx`, Muster wie die übrigen Popups über `?audit=1`) an **zwei** Stellen — Mandanten-Einstellungen `/settings` (eigener Mandant, TENANT_MODELS/RLS-gefiltert) und Plattform-Konsole `/admin/[id]` (Superadmin, cross-tenant über Owner-Client auf den Mandanten gefiltert). **Keine neue Migration.** Gate grün (tsc/lint/build + 17/17 Tests), Popup im Browser verifiziert.
|
||||
>
|
||||
> **Fix (2026-08-07):** `dev-fix-platform-admin` integriert — **Proxy-Gate für Plattform-Routen** (`src/proxy.ts`): `/platform/login` + `/api/platform-auth` sind jetzt public, und `/admin`, `/admins`, `/profile`, `/platform` gaten aufs Plattform-Session-Cookie und leiten anonyme Besucher auf **`/platform/login`** statt fälschlich auf die Mandanten-Login-Maske. Plus klarerer Modul-Toggle in `/admin/[id]` (Status-Pill + eigener „Aktivieren/Deaktivieren"-Button). Verifiziert: `/admin|/admins|/profile` → 307 `/platform/login`, `/dashboard` weiterhin → `/login`. Gate grün (17/17).
|
||||
>
|
||||
> **Fix (2026-08-07, 2):** Plattform-Auth bekommt **eigene Cookie-Namen für ALLE** Auth.js-Cookies, nicht nur `sessionToken` (`src/server/platform-auth.ts`): auch `csrfToken` (`__Host-platform-authjs.csrf-token`) und `callbackUrl` (`platform-authjs.callback-url`). Grund: zwei Auth.js-Instanzen auf derselben Domain teilten sich die Default-Cookies `authjs.csrf-token`/`authjs.callback-url`; da ein Nutzer zugleich Mandanten- und Plattform-Konto sein kann, überschrieb die zuletzt aktive Instanz das gemeinsame CSRF-Cookie → CSRF-Validierung der Plattform-Instanz schlug fehl (Sign-out warf, CSRF-POSTs/Session-Erneuerung landeten auf der Login-Maske). Getrennte Cookie-Namen isolieren beide Auth-Domänen vollständig. Gate grün (17/17).
|
||||
>
|
||||
> **Fix (2026-08-07, 3):** Plattform-Cookie-`secure`/Prefix folgt jetzt dem **AUTH_URL-Protokoll** (`https:`) statt `NODE_ENV` (`src/server/platform-auth.ts`, `PLATFORM_SECURE_COOKIES`), exakt wie Auth.js es für die Mandanten-Instanz tut (`useSecureCookies ?? url.protocol === "https:"`). Grund: im Container ist `NODE_ENV=production`, der interne Testserver wird aber ggf. über **http** bedient (AUTH_URL=http bzw. fehlendes `X-Forwarded-Proto`); ein hart auf `__Secure-`/`__Host-`/`secure` gesetztes Cookie wird vom Browser über http verworfen → Plattform-Session bleibt leer (jede Aktion → Login-Maske, Logout wirft), während die Mandanten-Session weiterläuft. **Betriebshinweis:** In Prod `AUTH_URL=https://…` setzen (dann greifen wieder secure-Cookies + `__Host-`/`__Secure-`-Prefixe). Gate grün (17/17).
|
||||
>
|
||||
> **Identity/Mandanten (Option C), WS0 (Fundament) — 2026-08-11:** globales `Identity`-Modell (kein `tenant_id`, **nicht** in `TENANT_MODELS`, keine RLS) + `User.identityId`; Migration `identity_foundation`; Reseed auf Identity+Membership inkl. 2. Mandant `demo2` + Multi-Membership-Fixture `multi@demo.example`. **Expand/Contract** (User-Auth-Felder bleiben vorerst Legacy; Contract-Migration droppt sie am Ende von WS1–WS4). Neuer Test `scripts/test-identity-schema.ts`. Grundlage/Fahrplan: `docs/FEINDESIGN-identity-mandanten.md`, `docs/KONZEPT-identity-mandanten.md`, `docs/UEBERGABE-identity-mandanten.md`, `docs/PROMPT-uebergabe-identity-mandanten.md`. Nächste Schritte: WS1 (Login gegen Identity, Two-Step + MFA-pending) → WS2 (`/select-tenant`), parallel WS3/WS4/WS6; Abschluss = Contract-Migration.
|
||||
>
|
||||
> **Identity/Mandanten (Option C), WS1/WS3/WS4/WS6 — 2026-08-11** (`feature/identity-auth-core` → `dev`, `--no-ff`, Gate grün: tsc/lint/build + **21/21** Tests; **noch nicht auf die Remotes gepusht**):
|
||||
> - **WS1 Auth-Kern:** `auth.ts` authentifiziert gegen die globale `Identity` (Passwort/MFA/Lockout an der Identity); Mitgliedschaften werden geladen, der aktive Mandant per Organisations-Slug oder Single-Membership gewählt (mehrere **ohne** Slug ⇒ noch kein Login → `/select-tenant` = WS2). Login-Kern als `authorizeTenantCredentials()` exportiert. Session/JWT (`next-auth.d.ts`) neu: `identityId`/`activeMembershipId`/`memberships[]` (optional, da Plattform-Auth dieselben Typen nutzt); `tenantId` = aktiver Mandant → **356 dbForTenant-Call-Sites unverändert**. Test `scripts/test-identity-login.ts`.
|
||||
> - **WS4 Passwort/MFA an Identity:** Passwortwechsel, MFA-Enroll/-Disable, Recovery-Codes und der **Session-Kill-Switch** (`sessionsValidAfter`) gehören der Identity (`account.ts`, `account/page.tsx`, `sessions.ts`). Guards (`action-guard.ts`, `(app)/layout.tsx`, `change-password`, `enroll-mfa`) lesen `mustChangePassword`/`sessionsValidAfter`/`mfaEnrolledAt` + globalen `identity.status` aus der Identity; Membership-Status/Rechte weiter aus `User`. Reset-Kette (`auth-recovery`/`auth-selfservice`/`auth-token`) auf `PrincipalType "identity"`. **Mandanten-Admin-Passwort-Reset entfernt** (goldene Regel 5). **E-Mail-Änderung für Mandanten-Konten deaktiviert = Phase 2.** Test `scripts/test-identity-account.ts`. **Abgetrennt (offen): WS4b WebAuthn→Identity** (Schema-Migration + `TENANT_MODELS` + `webauthn.ts`; Passkey-Login läuft bis dahin mandantengebunden).
|
||||
> - **WS3 Einladungs-Lifecycle:** Nutzeranlage **nur per Einladung** (goldene Regel 4) — `TokenType "invitation"` (7 Tage) + neue öffentliche Seite `/invite` + `redeemInvitation`. `createTenantUser`/`createUser`/`inviteFunctionHolder` ohne pwMode „set"; **bekannte Identity → nur Mitgliedschaft ergänzen** (kein Passwort-Reset), unbekannt → Identity + Einladung; **neutrale Rückmeldung** (kein Cross-Tenant-Leak). `user-forms.tsx` = reines Einladungsformular. Test `scripts/test-invitation.ts`.
|
||||
> - **WS6 Seed/Provision/Bootstrap:** bereits durch WS0 abgedeckt (`provisionTenant`/`seed.ts` Identity-fähig, `sync-role-permissions.ts` orthogonal) — kein Netto-neuer Code.
|
||||
> - **Keine neue Migration** (WS1/WS3/WS4/WS6 sind code-only; das WS0-Schema trägt).
|
||||
>
|
||||
> **Identity/Mandanten (Option C) — WS2/WS4b/WS5 + Contract, UMBAU KOMPLETT — 2026-08-11** (`feature/identity-tenant-context` → `dev`, `--no-ff`, Gate grün: tsc/lint/build + **23/23**; **noch nicht gepusht**):
|
||||
> - **WS2 Mandantenkontext:** Multi-Membership-Login ohne Organisations-Slug ergibt eine Session OHNE aktiven Mandanten → `(app)/layout` leitet auf **`/select-tenant`**. Wechsel server-autoritativ über **`setActiveTenant`** (`actions/tenant-switch.ts`, `unstable_update` + async jwt-`update`-Trigger → `resolveActiveMembership`: Rechte je Wechsel NEU aufgelöst). **Sidebar-`TenantSwitcher`** (nur bei >1 Mitgliedschaft). **Browser-verifiziert:** Wechsel demo↔demo2 inkl. Mandantenisolation (demo: 9 Assets, demo2: 0). Test `scripts/test-tenant-switch.ts`.
|
||||
> - **WS4b WebAuthn→Identity:** Passkeys sind identitätsgebunden (Migration `20260811140000_webauthn_identity`: `webauthn_credentials` verliert `tenant_id`/RLS, verweist auf `identities`); `WebAuthnCredential` **raus aus `TENANT_MODELS`**. Passkey-Login/-Verwaltung über `identityId`.
|
||||
> - **Contract-Migration** (`20260811150000_contract_user_auth_columns`): die 10 ungenutzten `User`-Auth-Spalten entfernt (`password_hash, must_change_password, failed_logins, locked_until, mfa_secret, mfa_enrolled_at, recovery_codes, last_totp_step, sessions_valid_after, is_platform_admin`) → **`User` = reine Mitgliedschaft** (`tenantId, identityId, email, name, status`). Expand/Contract abgeschlossen. DROP COLUMN → kein Reset.
|
||||
> - **WS5 Two-Step-Login (Entscheidung A):** `/login` Schritt 1 (E-Mail+Passwort) → bei aktiver MFA kurzlebiger, signierter, einzweckiger `mfa_pending`-Cookie (KEINE Session) → **`/login/mfa`** Schritt 2 → `login-ticket`-Provider prägt die Session. Bausteine `verifyIdentityPassword`/`verifyIdentityMfa`/`finalizeIdentityLogin` (kein Passwort-Orakel, Lockout wie beim vollen Login). `src/server/login-ticket.ts` (HMAC). Runtime-verifiziert. Test `scripts/test-two-step-login.ts`.
|
||||
> - **Damit ist der Umbau „Zentrale Identität mit Mandanten-Mitgliedschaften" vollständig** (alle 5 goldenen Regeln + Entscheidung A). Zwei neue Migrationen. **Offen: nur der Push auf beide Remotes** (origin + local-gitea) — bewusst zurückgehalten. Phase-2 (per-Mandant Step-up, E-Mail-Änderung als Identity-Op, PlatformAdmin-Konsolidierung) bleibt ausgeklammert.
|
||||
>
|
||||
> **Richtlinien-Vorlagen Plattform-Editor + EN-Paket — 2026-08-11:** `dev-fix-platform-admin` integriert — globale Vorlagen-Modelle + Migration `policy_templates`, Plattform-Editor (Entwurf/Veröffentlichen, Editoren für Anforderungen/Variablen), **Sprachwahl je Mandant** (`setTenantLocale`) und das **komplette EN-Übersetzungspaket** der Richtlinien-Vorlagen (Leitlinie, R01–R14, VA-01–VA-20, D01/P01, Baseline/Nachweisregister). Mandanten-Import liest die veröffentlichte DB-Version.
|
||||
>
|
||||
> **Härtung Argon2id — 2026-08-11:** Passwort-Hash-Parameter fixiert/dokumentiert (`src/server/password.ts`, `ARGON2_OPTIONS`: m=19456 KiB, t=2, p=1, outputLen=32; Argon2id = Lib-Default). Salt automatisch pro Hash (PHC-String), **kein** Pepper (dokumentiert). Nur neue Hashes betroffen.
|
||||
>
|
||||
> **Härtung Phase 2–3 (Ops-Doku) — 2026-08-11** (Lane `lane-haertung-ops`, **nur Markdown, kein App-Code/Migration, noch nicht nach `dev` gemergt**): **Phase 1 (Passwort-Pepper) ist erledigt** (Argon2-`secret`, zentral, in `dev`) — unverändert. Phasen 2–3 liegen jetzt als **Ops-Runbook** vor: `docs/DEPLOY-PROD-CONTABO.md` um **Host-Encryption at-rest** (LUKS/dm-crypt fürs Daten-Volume `pgdata`+MinIO, Boot-Unlock-Verfahren A/B, Passphrase im Passwortmanager) und **verschlüsselte Backups** (pgBackRest `aes-256-cbc` + `age` je Umgebung + restic für MinIO, Coolify-Cron/Retention/Restore-Test, Bezug zur App-Backup-Engine `BACKUP_ENC_KEY`/§9) ergänzt; neues **`docs/SECRETS-REGISTER.md`** (Ownership + Rotationsregel je Umgebung für `AUTH_SECRET`/`MFA_ENC_KEY`/`PASSWORD_PEPPER`/`BACKUP_ENC_KEY`/pgBackRest-Key/`age`-Keypair; `PASSWORD_PEPPER`+`MFA_ENC_KEY` als **nicht rotierbar** = Reset markiert). **Restore-Kohärenz-Regel** prominent in beiden Docs: Umgebungs-Secrets stehen nicht im Artefakt → Restore in fremde Umgebung bricht Passwort-/MFA-Prüfung bzw. Entschlüsselung. **DB-TLS (`sslmode`) + Vault/KMS bleiben Phase 2** (offen). Gate: nur `.md`, tsc/lint unberührt.
|
||||
>
|
||||
> **Merge-Zyklus 2026-08-11:** WS0 + Richtlinien/EN-Lane + Argon2 zusammen nach `dev` konsolidiert. Konflikt nur in `schema.prisma` (User-Relationsblock → Union mit `identity`) + `provision.ts` (auto-merge: Identity-Upsert **und** Policy-Variablen). DB neu gebaut (`migrate reset`, **52 Migrationen**, beide neuen koexistieren) + Seed. Gate grün: tsc/lint/build + **18/18 Tests**.
|
||||
>
|
||||
> **Konfigurierbarer Backup-Zielspeicher — 2026-08-17** (`lane-backup-target` → `dev`, `--no-ff`): Backup-/DSGVO-Zielspeicher jetzt **im Betreiber-Portal wählbar** (`/admin/backup`, Full-Admin + MFA-Step-up) — **Lokal** (persistentes Volume) oder **S3/MinIO**. `PlatformSetting` erweitert (`backupTarget`, `backupLocalDir`, `backupS3*`, `backupS3SecretKeyEnc` **verschlüsselt at-rest**), Migration `backup_target_config` (additiv). Statisches `backupStore` → **`getBackupStore()`** mit Präzedenz **DB → Env (`S3_*`/`BACKUP_LOCAL_DIR`) → lokaler Default `.backups`**, fail-secure bei unvollständiger S3-Config; alle Call-Sites umgestellt. **Persistentes `backups`-Volume** (app + backup-worker, `/app/.backups`) — Lokal überlebt Redeploys. Neuer Test `scripts/test-backup-target.ts`. Gate grün (tsc/lint/build + **28/28**), `/admin/backup` im Browser klickgeprüft (Lokal↔S3, Secret-Feld „nie Klartext"). Konzept/Prompt: `docs/KONZEPT-backup-target.md`, `docs/PROMPT-lane-backup-target.md`.
|
||||
>
|
||||
> **Modul „Vorfälle" (Incident-Management) IM-A — 2026-08-17** (`lane-incidents-a` → `dev`, vom Team): Fundament + Kern-Lifecycle/UI (Migration `incidents`, `src/app/(app)/incidents/*`, `src/server/actions/incidents.ts`, `docs/KONZEPT-incidents.md`, Test `scripts/test-incidents.ts`). IM-B (Meldefristen/Notifications) noch **in Arbeit** (eigener Branch `lane-incidents-b`).
|
||||
>
|
||||
> **Direkt-Download der Sicherung + S3-Bucket-Selbstheilung — 2026-08-17** (`lane-backup-download` @ `fe13a84` → `dev`, `--no-ff`): Neue Route `/api/platform/backup/download` (Full-Admin) — `exportTenant(persist:false)` streamt die verschlüsselte `.cvb` **inline in den Browser**, **ohne Worker/Redis/S3** („Sicherung herunterladen"-Button im Export-Popup). `S3BackupStore.ensureBucket()` legt einen fehlenden MinIO-Bucket beim ersten `put` **automatisch** an (behebt „The specified bucket does not exist"). Neuer Test `scripts/test-backup-download.ts`. Gate grün (tsc/lint/build + **30/30**). Merge über isoliertes Worktree (paralleler Team-Arbeitsbaum unberührt).
|
||||
>
|
||||
> **Modul „Vorfälle" IM-B/C/D (komplett) + Backup-Docker-Fix — 2026-08-18** (vom Team nach `dev` gemergt; von mir validiert + gepusht): **IM-B** (Meldefristen/Timer + Meldepflicht + Benachrichtigungen), **IM-C** (Verknüpfungen, Abschluss/Lessons-Learned, Export/Meldevorlagen), **IM-D** (E-Mail-to-Ticket Inbound + Provisionierung; Migration `incident_inbound_d`, Test `scripts/test-incident-inbound.ts`). Damit ist das Modul „Vorfälle" funktional komplett (IM-A…IM-D). **Docker-Fix:** `prisma/schema.prisma` wird jetzt auch in die `runner`-Stage kopiert — der Inline-Backup-Download läuft in der App (standalone), und die Backup-Topologie liest die Schema-Datei zur Laufzeit (Prisma 7 entfernt FK-Relationen aus dem Laufzeit-DMMF); sonst `ENOENT` → „Export fehlgeschlagen". Gate grün (tsc/lint/build + **33/33**).
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
Auf `main` lag das Fundament (Auth/RBAC/Mandanten-Isolation, Assets/BIA, Risiko, Maßnahmen, Abhängigkeiten, Lieferanten, Richtlinien Phase 1/2a, Admin-Konsole Phase 1). Der Branch **`dev`** ergänzt fünf große Blöcke — alle mit `tsc`+`lint`+`build`, Modul-Guard-Check und (wo relevant) Browser-Verifikation abgeschlossen:
|
||||
|
||||
1. **Produktionshärtung Phase 1** — API-seitige Modul-Durchsetzung, getrennter Superadmin-Store mit eigenem Login + MFA, nicht-destruktiver Richtlinien-Re-Import.
|
||||
2. **Benutzer- & Rollenverwaltung** (ohne E-Mail-Flow) — Plattform-Admin verwaltet Nutzer je Mandant; Mandanten-Admin verwaltet Nutzer **und** Rollen intern; Force-Change-Passwort, Passwort-Policy, optionale MFA je Nutzer; Popup-UI wie bei Assets.
|
||||
3. **Freigabe-Workflow + Aufgaben-Modul** — Richtlinien-Freigabe an eine konkrete Person, Bearbeitung im neuen Modul „Aufgaben", Dashboard-Kachel; plus zentralisierte Richtlinien-Governance (zentrale Variablen, Schutzbedarf, Coverage-Filter nach Assessment-Level).
|
||||
4. **GAP-Report-Umsetzung (Richtlinien-Vorlagenpaket)** — WP1–WP4 + E2: sechs neue Verfahrensanweisungen (ISB-Volltexte), Inline-VA-Verlinkung, Rendering-Fix, generisches editierbares Register-Datenmodell.
|
||||
5. **Register-Konsolidierung in Fachmodule** — vier generische Register in die Fachmodule überführt: **Software** und **Projekte** als eigene Asset-Typen (Popups wie bei Assets/Lieferanten), **kritische IT-Dienste** als schreibgeschützte Auto-Sicht aus BIA, REG-NET auf Referenzfeld reduziert; Richtlinien-Links zeigen jetzt auf die Module statt auf Register.
|
||||
6. **Produktions-Deployment-Vorbereitung** (Commits `cc8d486`, `f368d8f`) — Prod-Bootstrap `scripts/bootstrap-admin.ts` (legt Erst-Superadmin im `platformAdmin`-Store + Mandant/Mandanten-Admin idempotent an, ersetzt in Prod den Demo-Seed; per `BOOTSTRAP_*`-Env im `migrate`-Job der `docker-compose.coolify.yml`); `.env.prod.example`; **Fonts selbst gehostet** (`next/font/local`, committete woff2 in `src/app/fonts` → reproduzierbarer Offline-Build, DSGVO); Runbook **`docs/DEPLOY-PROD-CONTABO.md`** (VPS/Coolify/Gitea, TLS `app.certvia.de`, Bootstrap, Backups, Go-Live-Checkliste).
|
||||
|
||||
7. **Branding-Umstellung auf Certvia** — **in `dev` integriert (Gate grün)**: getrennte Token-Ebenen `--brand-*` (Logo/Print/Export) vs. `--ui-*` (Produktpalette, inhaltlich unverändert) mit `src/lib/brand.ts` als JS-Pendant; Certvia-Logo als Inline-SVG-Komponente (`<CertviaLogo>`), Favicon-/PWA-Icons + `site.webmanifest`, Metadaten/OG/i18n/TOTP-Issuer, gebrandete Auth-Seiten sowie **neue 404-/500-Seiten**, Druck-/Dokument-CD (`@media print` + `src/lib/document-brand.ts`) als Andockpunkt für den offenen DOCX/PDF-Export, brandfähige E-Mail-Basis (`src/lib/email-brand.ts`), Mandanten-Branding-Default (`resolveTenantBranding`). **GEFIM bleibt Dachmarke** („Ein Produkt von GEFIM"). Reines Branding, keine Funktionsänderung — Ausnahme: der Route-Gate-Matcher in `src/proxy.ts` musste `.webmanifest` freigeben, sonst lieferte `/site.webmanifest` die Login-HTML. Details: **`docs/BRANDING-CERTVIA.md`**.
|
||||
|
||||
**In Arbeit (parallele Entwicklung, 2-Lane Dev A × Dev B):** **Onboarding-Wizard** (`docs/wizard-uebergabe/`). **Beide Lanes bis hierher in `dev` konsolidiert** (inkl. Dev-B **B4**, per Fast-Forward integriert)**:**
|
||||
- **Dev A:** A1-1 — Wizard-Shell: Modul `onboarding`, Step-Registry (`registerStep`, Keys 1–9, `guard` kann Schritte ausblenden), resumierbarer Fortschritt (`OnboardingProgress`). **F2** — generalisiertes `ObjectReviewStatus` (5 Zustände inkl. `zurueckgewiesen`) als wiederverwendbares Review-Enum; RBAC-Recht `validate_objects` + klonbare Rolle `external_validator`; Wizard-State-Machine mit Rechte-Trennung: Bearbeiter (`onboarding:use`) advance/rework/reset, Validator (`validate_objects`) validieren/zurückweisen (mit Begründung). „Weiter"-Gate: nur `validiert` zählt. Migration `object_review_status`. **A1-2** — Dashboard-Kachel „Onboarding-Fortschritt" (Anteil validierter Schritte + nächster offener Schritt, verlinkt in den Wizard). **A2-1** — Assessment-Level (AL2/AL3) als **einzige** Quelle des Schutzbedarfs: `protectionFlags(level)` (`src/server/assessment-level.ts`) leitet `FLAG_HIGH_PROTECTION`/`FLAG_VERY_HIGH_PROTECTION` zentral ab (Wizard/Provisioning seeden daraus, **nicht** mehr aus dem Fragebogen); Schutzbedarf-Frage `Q-FEAT-01` + Regeln `feat01-*` entfernt. **A2-2** — Scope-Objekt `WizardScope` + Filter-Engine (`src/lib/scope-filter.ts`: `activeRequirements`/`scopeSummary`, client-safe): filtert die Anforderungen nach AL-Baseline, `FLAG_INCLUDE_SHOULD` und Prüfzielen; Grunddaten `seed/scoping/c1-scope.json` (412 Anforderungen, generiert via `scripts/build-c1-scope.ts`); Action `saveScope` (`moduleGuard('onboarding')`) am Wizard-Schritt „scoping"; Migration `wizard_scope`; Tests `scripts/test-scope-filter.ts` (grün). **A3-1** — Validierungs-Workflow generalisiert: wiederverwendbares generisches Objekt-Review (`src/server/object-review.ts`, `src/lib/object-review.ts`, `src/components/object-review.tsx`) über Objekttypen hinweg (u. a. Risiken), an Risk-/Task-Actions angebunden. **A4** — ISMS-Rollen als Wizard-Schritt 3 „roles" inkl. Funktionstrennung FT-01…06 (`src/lib/ft-rules.ts`, Tests `scripts/test-ft-rules.ts`), ISB-Bestellung (`src/lib/isb-bestellung.ts`) und Rollen-Logik (`src/server/roles.ts`). **A5-1** — Asset-Schritt (Wizard-Schritt 5) auf dem Bestandsmodul (`steps/assets/step.tsx`). **A7** — **Control-Assessment** (Wizard-Schritt 7): Reifegrad-Engine R0–R3 + Zielreifegrad (`src/lib/maturity.ts`, Tests `scripts/test-maturity.ts`), Modell `ControlAssessment` (Migration `control_assessments`, RLS, in `TENANT_MODELS`) mit Belegstatus/Reifegrad-Bestätigung/Gap-Aufgaben; SoA-Kontext (`src/server/soa-context.ts`, `actions/soa.ts`), Control-Grunddaten `seed/scoping/c5-controls.json`. **A6** — **Standard-Risikokatalog (C4)**: globaler Katalog `RiskCatalogEntry` (Migration `risk_catalog`, kein RLS) + Import/Übernahme (`prisma/import-risks.ts`, `/risks/catalog`); A6-2 Standardmaßnahme→Aufgabe und **Restrisiko-Akzeptanz** (Migration `risk_acceptance`: Felder `accepted_at/by/rationale` an `risks`, VA-09). **A8** — **Gap-Konsolidierung** (Wizard-Schritt 8): Aggregations-/Priorisierungs-Engine (`src/lib/gap-consolidation.ts`: Dedup, Priorisierung, Quick-Wins), Task-Abgleich + Kontext (`src/server/gap-context.ts`, `src/server/actions/gap.ts`), Tests `scripts/test-gap-consolidation.ts` (keine neue Migration/Modell).
|
||||
- **Dev B:** F1 (Task-Objekt um Wizard-Felder `type/owner/dueDate/priority/status/resources/origin/links` erweitert, Migration `tasks_wizard_fields`), B1 (Auto-Generierung von Aufgaben-Vorschlägen aus Triggern, C2 §8; `src/lib/task-triggers.ts`, `src/lib/tasks.ts`), F4 (Wizard-Flags in `variables.schema.json`: `FLAG_PROTOTYPE_PROTECTION`, `FLAG_ISB_EXTERNAL`, `FLAG_ISB_INTERNAL`; `_verify.py` = OK). **F3+B2** — Regel-/Mapping-Engine: deklarative DSL (`src/lib/rules/dsl.ts`), Auswerter (`engine.ts`, `evaluateCondition`) und C2-§5-Regelwerk (`feature-rules.ts`: Feature-Flags, Schutzbedarf-Ableitung, Control-Scope, Risiko-/Aufgaben-Trigger); Tests `scripts/test-rules.ts` (18 Fälle, grün). **B3** — Fragebogen als Wizard-Schritt 2 „context": Frage-Katalog A–F (`src/lib/onboarding/questions.ts`), Fakten-Ableitung (`facts.ts`, `deriveContext` über die Regel-Engine), Schritt-Komponente + `saveFacts`-Action (`onboarding-facts.ts`), Modell `WizardFact` (Migration `wizard_facts`, RLS, in `TENANT_MODELS`); echte Schritte via Side-Effect-Import `register-steps.ts` in die Registry eingeklinkt (überschreibt Platzhalter). Der Fragebogen schreibt **nur** Fakten/Flags, nie die gesperrten Zentralvariablen. **B4** (Richtlinien-Import/Upload) — **in `dev` integriert (Fast-Forward), Gate grün**: **B4-1** nicht-destruktiver Vorlagen-Import bei Aktivierung des Richtlinien-Moduls + Self-Service-Button (`/policies`, Report-Banner) und Admin-Button (`src/server/actions/policy-package.ts`, Trigger in `toggleTenantModule`); **B4-2** „Eigene Richtlinie hochladen" (`/policies/upload`, `policy-upload.ts`) mit Pflicht-Control-Zuordnung + gekapseltem Storage-Adapter-Stub (`src/server/storage/adapter.ts`, echtes Backend = Epic S1) → EIGENES-Dokument (`EIG-*`) + PolicyRequirement-Zeilen (Coverage/Nachweislage); **B4-3** neue Vorlagen `P01_Prototypenschutz` + `VA-20` (Kap. 8.x) und `D01_Datenschutz` (9.x) + 5 `mapping.json`-Anforderungen (condition-gated per Prüfziel-Flag), `_verify.py` = OK. **Keine neue Migration** (nur String-Status/Seed-Content). **B5** (Umsetzungshinweise C6) — **in `dev` integriert, Gate grün**: **B5-1** Datenmodell `ImplementationHint` (Migration `implementation_hints`; **globaler C6-Katalog**, identisch je Mandant → kein `tenantId`/RLS) + C6-Import (~397 Hinweis-Blöcke via `prisma/import-hints.ts` / `scripts/import-c6-hints.ts`); **B5-2** kontextsensitives Umsetzungshinweis-Panel (`/policies/hints`, `src/server/actions/hints.ts`), aus `/policies` verlinkt. **Prüfziele Single Source** (Follow-up zu A2): der context-Step seedet die Prüfziele aus `WizardScope` statt aus einer zweiten Quelle (Doppelquelle behoben; `feature-rules.ts`/`facts.ts`/`questions.ts`, `test-rules.ts` angepasst). **B6** — Vorlagenpaket-**Versionierung** + kontrollierte **Diff-Übernahme**: Modell `PolicyPackageState` (Migration `policy_package_state`, RLS, in `TENANT_MODELS`) hält je Mandant Paket-Version/-Stand; `stampPackageState` (in `prisma/import-policies.ts`) beim Import; Updates-Ansicht `/policies/updates` zeigt/übernimmt Änderungen kontrolliert. **B7-1** — Assessment-**Readiness-Dashboard** als Wizard-Schritt 9 „readiness" (`src/lib/readiness.ts`, Tests `scripts/test-readiness.ts`) mit Interpretationstexten (C9 §1/§2). **B7-2** — **VDA-ISA-Katalog-Export** (CSV) + **Management-Zusammenfassung** (C9 §3/§4): Export-Route `onboarding/export/route.ts`, Export-Engine `src/lib/export/vda-isa.ts` + `src/server/export-context.ts`, Zusammenfassungs-Seite `onboarding/summary`, Tests `scripts/test-vda-isa.ts`. Damit ist **B7 vollständig** (keine neue Migration). **Wizard-Schritte 4 + 6 (echte Komponenten)** — Richtlinien-Schritt „policies" (Schritt 4, Guard: nur bei aktivem Richtlinien-Modul) und Risiken-Schritt „risks" (Schritt 6, Guard: nur bei aktivem Risiko-Modul) zeigen jetzt den echten Modul-Status statt Platzhalter (`steps/policies/step.tsx`, `steps/risks/step.tsx`, `src/server/actions/onboarding-steps.ts`) — keine Doppel-Datenhaltung. Damit sind **alle Wizard-Schritte 1–9 echte Komponenten**.
|
||||
- **Offen:** **Keine offenen Feature-Branches mehr** — alle bestehenden Lanes in `dev` konsolidiert (Dev A: A1–A8; Dev B: F1/B1/F4/F3+B2/B3/B4/B5/B6/B7 + Prüfziel-Follow-up). Nächste geplante Stories siehe §6.
|
||||
|
||||
**Migrationen (31 neu, laufen beim Deploy automatisch über den Init-Container):**
|
||||
`platform_admins` · `policy_lifecycle_archived` · `user_mgmt_and_platform_settings` · `tasks` · `strip_tool_variable_articles` · `managed_registers` · `software_and_project_assets` · `onboarding_progress` · `tasks_wizard_fields` · `object_review_status` · `wizard_facts` · `wizard_scope` · `implementation_hints` · `policy_package_state` · `control_assessments` · `risk_catalog` · `risk_acceptance` · `task_description` · `control_implementations` · `login_lockout` · `mail_fundament` (SEC1) · `auth_tokens_sessions` (SEC2) · `tisax_m0_foundation` · `tisax_m1_m4_consolidated` · `tisax_rekey_onboarding_steps` · `tisax_v3_process_fields` · `tisax_v4_catalog_parent` · `tisax_v5_audit` · `tisax_v7_policy_domain` · `webauthn_credentials` (SEC3) · `platform_admin_role` (SEC4)
|
||||
|
||||
---
|
||||
|
||||
## 1a. Sicherheitspaket P1/P2 (Branch `dev-security-p1`, Stand 2026-07-30)
|
||||
|
||||
Nach einem externen Secure-Code-Review (AEGIS-SAST, 21 Findings) wurde ein Härtungspaket umgesetzt: **alle P1 (2) und P2 (5) sowie mehrere P3** sind behoben. Das Paket liegt auf **`dev-security-p1`** (von `dev` abgezweigt, Gate grün, noch **nicht** nach `dev` gemergt). Parallelisiert in drei konfliktfreien Lanes plus Vorlauf, danach additiv integriert.
|
||||
|
||||
| Finding | Priorität | Behebung | Kern-Dateien |
|
||||
|---|---|---|---|
|
||||
| **F-01** Auth.js „fail open" + Next.js-CVEs | P1 | `next-auth`→`5.0.0-beta.32` (`@auth/core` 0.41.3), `next`→`16.2.12`; Guards **positiv** statt existenzbasiert; **Fail-Secure-Startprüfung** `assertSecureEnv()` (lazy/memoisiert, build-safe) | `package.json`, `src/server/env.ts`, `auth.ts`, `platform-auth.ts` |
|
||||
| **F-02** Cross-Tenant-Leck bei `findUnique`+`select` | P1 | Tenant-Guard **fail-closed**: skalare `where`→`findFirst` mit `tenantId`-Vorfilter (verhindert statt erkennt), Compound-Unique→`tenantId`-Injektion + harter Abbruch; drei Aufrufstellen zusätzlich explizit gefiltert; Regressionstest | `src/server/db.ts`, `actions/risks.ts`, `actions/risk-catalog.ts`, `scripts/test-tenant-isolation.ts` |
|
||||
| **F-03** Stored XSS im Richtlinien-Rendering | P2 | `renderPolicyHtml` sanitisiert `marked`-Output gegen strikte Allowlist (`sanitize-html`); Variablenwerte + Upload-Titel HTML-kodiert vor `noEscape`-Handlebars | `src/lib/policy-render.ts`, `actions/policy-upload.ts` |
|
||||
| **F-05** Kein Brute-Force-Schutz Mandanten-Login | P2 | Kontosperre (5/15 min) + `denied`-Audit analog Plattform-Login; Enumeration via Dummy-Hash konstanter Laufzeit; DoS-Ausnahme letzter aktiver Admin | `auth.ts`, Migration `login_lockout` (`User.failedLogins/lockedUntil`) |
|
||||
| **F-07** Keine Security-Header/CSP | P2 | CSP + HSTS + `nosniff` + `X-Frame-Options: DENY` + Referrer-/Permissions-Policy; `unsafe-eval`/`ws:` nur im Dev | `next.config.ts` |
|
||||
| **F-08** Kritische Kontoänderung ohne Re-Auth | P2/P3 | Passwortwechsel verlangt aktuelles Passwort (+ TOTP bei aktiver MFA); MFA-Deaktivierung erfordert TOTP-Code; Ausnahme nur beim erzwungenen Erstwechsel | `actions/account.ts`, `actions/platform.ts` |
|
||||
| **F-09** 30-Tage-Sessions | P3 | `maxAge` 8 h (Mandant) / 2 h (Plattform) + `updateAge` | `auth.ts`, `platform-auth.ts` |
|
||||
| **F-12** Weitere verwundbare Abhängigkeiten | P3 | `overrides` für `postcss`/`sharp`/`valibot`; **Produktionsbaum (`--omit=dev`): 0 kritisch / 0 hoch** (vorher 2/5) | `package.json` |
|
||||
| **F-15** Upload ohne Validierung | P3 | Größenlimit vor RAM-Read, Endungs-/MIME-Allowlist, Magic-Byte-Prüfung, kanonischer MIME statt `f.type` | `actions/policy-upload.ts` |
|
||||
| **F-16** (Teil) Isolationsverletzung unsichtbar | P3 | Verletzungen als `[SECURITY]`-Log; zentrale Audit-Anbindung (`action:"denied"`) als Folge-TODO offen (Importzyklus `audit.ts`↔`db.ts`) | `src/server/db.ts` |
|
||||
| **F-19** Unvalidiertes `callbackUrl` | P4 | Allowlist (nur eigene absolute Pfade), doppelt validiert | `src/app/login/page.tsx` |
|
||||
|
||||
**Korrekturen am Bericht** (dessen Codevorschläge waren an drei Stellen falsch): `npm install next-auth@latest` hätte auf **v4** downgegradet (Major-Bruch) — korrekt ist `5.0.0-beta.32`. Der pauschale `findUnique`→`findFirst`-Umbau bricht an den Compound-Unique-Keys (`tenantId_key` etc.) → stattdessen Hybrid-Guard. Das RLS-Snippet aus F-04 funktioniert nicht (Kontext in falscher Transaktion) → F-04 bewusst herausgelöst.
|
||||
|
||||
| **F-06** JWT-Sessions ohne Widerruf | P2 | ✅ **Branch `dev-security-f06-session-auth`** (auf `dev-security-f04-rls`): `moduleGuard` prüft Kontostatus, `mustChangePassword` und effektive Rechte je Mutation **autoritativ aus der DB** statt aus dem JWT → Deaktivierung/Rechteentzug wirkt sofort (vorher bis Token-Ablauf); `requirePlatformSession` prüft Plattform-Admin-Status. Test `test-action-guard-authz.ts` (4 Nachweise), Browser-Regression ok | `src/server/action-guard.ts`, `platform-auth.ts` |
|
||||
| **F-04** RLS definiert, aber wirkungslos | P2 | ✅ **Separates Paket, Branch `dev-security-f04-rls`** (auf `dev-security-p1` aufgesetzt): env-gesteuert (`RLS_ENFORCED`). Zweite Verbindung als `isms_app` (`RLS_DATABASE_URL`, NOBYPASSRLS); `dbForTenant` setzt `app.tenant_id` transaktionslokal auf derselben Connection; Policies mit `USING`+`WITH CHECK` + `FORCE` auf allen **49** Tenant-Tabellen. Owner-Rolle (Superuser/BYPASSRLS) bleibt für Migrationen/Seed/Login und lokal unberührt → Default-Betrieb unverändert. Test `test-rls-enforcement.ts` (5 Nachweise) | `src/server/db.ts`, Migration `rls_enforce`, `docker-compose.coolify.yml`, `.env*.example`, `DEPLOY-PROD-CONTABO.md` |
|
||||
|
||||
**Gate (kombinierter Stand A+B+C):** `tsc`=0 · `lint` sauber · `build` grün · `_verify.py`=OK · `test-tenant-isolation`=OK (15 Fälle) · Browser-Smoke (Login, Dashboard, Richtlinien-Register, CSP-Header, Guard-Redirect) verifiziert. **F-04 separat:** `tsc`/`lint`/`build` grün · `test-rls-enforcement`=OK (5/5, inkl. Nachweis „Owner-Betrieb heil unter FORCE") · Owner-Pfad-Smoke verifiziert.
|
||||
|
||||
### P3/P4-Paket (Branch `dev-security-p3`, auf `dev-security-f06-session-auth`, Stand 2026-07-30)
|
||||
|
||||
Vier dateidisjunkte Lanes, additiv gemergt, kombiniertes Gate grün. **Nur die MFA-Lane migriert.**
|
||||
|
||||
| Finding | Prio | Behebung | Kern-Dateien |
|
||||
|---|---|---|---|
|
||||
| **F-10** Aufgaben-Modul ohne Rechteprüfung | P3 | Neues Recht `task:write`; `guard("task:write")` in `createTask`/`proposeTasksFromTriggers`/`claimTask`/`updateTask`; `CreateTaskInput` per Zod (Längen-/Größenlimits); `owner`/`assignee` gegen aktiven Mandanten-Nutzer geprüft | `rbac.ts`, `actions/tasks.ts` |
|
||||
| **F-13** Privilege Escalation über `role:manage` | P3 | **Pragmatische Variante** (Entscheidung): Delegation erlaubt (Admin darf fachliche/geklonte Rollen für andere anlegen), aber **Selbstzuweisung** höher privilegierter Rollen gesperrt → Selbst-Eskalation ausgeschlossen; volle Auditierung | `actions/tenant-users.ts` |
|
||||
| **F-20** Schwache Passwort-Policy bei Provisionierung | P3 | `validatePassword(…, DEFAULT_PASSWORD_POLICY)` statt `min(8)` | `actions/admin.ts` |
|
||||
| **F-16-zentral** Sicherheitsereignisse nur im Log | P3 | Importzyklus per Lazy-Import gelöst → Isolationsverletzung wird echter `denied`-Audit; Error-Boundary `withActionErrors` (generische Außenmeldung, volles internes Log) bereitgestellt | `db.ts`, neu `action-error.ts` |
|
||||
| **F-17** Recovery-Codes SHA-256, TOTP-Replay | P3 | Recovery-Codes → Argon2id, Entropie 40→80 Bit (Alt-Codes per Kompatibilitätspfad bis Neuausstellung); TOTP-Replay-Schutz via `lastTotpStep` (User+PlatformAdmin) | `mfa.ts`, `auth.ts`, `platform-auth.ts`, `account.ts`, `platform.ts`, Migration `mfa_totp_replay` |
|
||||
| **F-11** Supply Chain | P3 | `npm ci` (Base-Image → `node:22.14.0-slim`/glibc, npm 11 gepinnt), alle Images auf feste Tags/Digests, schlanke `migrate`-Stage, SBOM dokumentiert; lokaler `docker build` grün (386 MB) | `Dockerfile`, `docker-compose*.yml` |
|
||||
| **F-18** Container-Härtung | P3/P4 | Redis-Passwort, internes Netz (`internal: true`), `no-new-privileges`/`cap_drop: ALL`/Ressourcenlimits, Dev-Compose auf `127.0.0.1` gebunden | `docker-compose*.yml`, `.env*.example` |
|
||||
| **CI/Renovate** (Begleitmaßnahmen) | — | `.gitea/`+`.github/workflows/ci.yml` (tsc/lint/build + `npm audit --omit=dev --audit-level=high`-Gate), `renovate.json` (Auth-Updates manuell) | `.gitea/`, `.github/`, `renovate.json` |
|
||||
|
||||
**Gate (kombiniert):** `tsc`=0 · `lint` · `build` · `_verify.py`=OK · 7 Sicherheitstests grün (`tenant-isolation`, `rls-enforcement`, `action-guard-authz`, `tenant-users-authz`, `mfa-hardening`, `action-error`) · Browser-Smoke (Task-Anlage F-10) verifiziert.
|
||||
|
||||
> ✅ **Deployment-Schritt (F-06 × F-10) — automatisiert:** Da F-06 Rechte **DB-autoritativ** prüft, wirkt eine neue Permission (z. B. `task:write`) erst, wenn `scripts/sync-role-permissions.ts` gegen die Ziel-DB läuft (legt Permission + Rolle→Recht-Verknüpfung an; additiv, idempotent). Ein reiner Re-Login genügt NICHT. Das läuft jetzt **bei jedem Deploy automatisch im `migrate`-Init-Job** (`docker-compose.coolify.yml`, direkt nach `prisma migrate deploy`, über die Owner-`DATABASE_URL`) — deckt jede künftig neu eingeführte Permission ab. Betroffene Nutzer danach neu einloggen. Manuell nachziehen nur, falls ohne Redeploy nötig: `npx tsx scripts/sync-role-permissions.ts`.
|
||||
|
||||
**Noch offen:** **F-14** (Demo-Seed-Härtung — auf Wunsch bewusst zurückgestellt), **F-21** (Monitoring/Log-Aggregation/Tamper-Schutz Audit-Trail — eigenes Betriebspaket). Damit sind **alle P1, alle P2 und die adressierten P3** behoben. Details: AEGIS-Bericht.
|
||||
|
||||
**Aktivierung F-04 in Prod:** Rolle `isms_app` LOGIN+starkes Passwort geben, `RLS_DATABASE_URL` setzen, `RLS_ENFORCED=true` am `app`-Service; Migrations-/Owner-Rolle muss BYPASSRLS/Superuser sein. Anleitung in `docs/DEPLOY-PROD-CONTABO.md`. Lokal bewusst **aus**.
|
||||
|
||||
---
|
||||
|
||||
## 2. Für das Projektmanagement — fachlicher Status
|
||||
|
||||
### ✅ Neu fertig auf `dev`
|
||||
|
||||
| Thema | Nutzen | Status |
|
||||
|-------|--------|--------|
|
||||
| **API-seitige Modul-Durchsetzung** | Deaktiviertes Modul sperrt jetzt auch Schreibzugriffe serverseitig (nicht nur Navigation); automatischer Vollständigkeitscheck als Build-Gate | ✅ |
|
||||
| **Getrennter Superadmin-Login** | Betreiber-Zugang unter `/platform/login` mit eigenem Store, ohne Mandantenkontext; Kundenfachdaten für Superadmin gesperrt | ✅ |
|
||||
| **MFA (optional)** | TOTP für Plattform-Admins **und** Mandanten-Nutzer freiwillig; Policy-Flag „MFA-Pflicht" kann Erzwingung wiederherstellen; Recovery-Codes | ✅ |
|
||||
| **Benutzerverwaltung (Superadmin)** | Superadmin legt je Kunde Nutzer an (Initial-/Einmal-Passwort), weist Rollen zu, deaktiviert/reaktiviert, setzt Passwörter zurück | ✅ |
|
||||
| **Benutzer- & Rollenverwaltung (Kunde)** | Mandanten-Admin verwaltet **intern** Nutzer und Rollen (eigene Rollen + granulare Rechte, Standardrollen klonbar); strikt mandantengetrennt; Lockout-Schutz | ✅ |
|
||||
| **Nutzer-Onboarding ohne E-Mail** | Start mit Initialpasswort + erzwungenem Wechsel beim ersten Login; E-Mail-Einladung (Paket 4) später nahtlos ergänzbar | ✅ |
|
||||
| **Popup-Bedienung** | Anlegen/Bearbeiten von Nutzern über Popups wie bei Assets; Tabelle nur Anzeige | ✅ |
|
||||
| **Zuständigkeiten geklärt** | Superadmin steuert Kern-Einstellungen (Module, TISAX-Tiefe); Mandanten-Admin nur seinen Bereich (Stammdaten, Nutzer/Rollen) | ✅ |
|
||||
| **Richtlinien-Governance zentral** | Zentrale Variablen (Unternehmensname, Rollen, Schutzbedarf) nur in Einstellungen pflegbar; Coverage-Matrix zeigt nur Controls des aktiven Assessment-Levels (AL2 ohne „sehr hoch") | ✅ |
|
||||
| **Scoping & zentraler Schutzbedarf (A2)** | Anforderungs-Scope leitet sich zentral aus Assessment-Level (AL2/AL3), `FLAG_INCLUDE_SHOULD` und den Prüfzielen ab — nicht mehr aus dem Fragebogen; Schutzbedarf hat damit eine einzige, konsistente Quelle (AL → Flags). Scope-Filter (`scope-filter.ts`) + `c1-scope.json` (412 Anforderungen) | ✅ |
|
||||
| **Umsetzungshinweise (B5)** | Kontextsensitive C6-Umsetzungshinweise (~397 Blöcke) zu den Controls, als eigenes Panel unter `/policies/hints` und aus den Richtlinien verlinkt — praktische Hilfestellung bei der Umsetzung | ✅ |
|
||||
| **Validierungs-Workflow generalisiert (A3)** | Das Vier-Augen-/Review-Muster ist jetzt objekttyp-übergreifend nutzbar (nicht nur Aufgaben) — z. B. für Risiken | ✅ |
|
||||
| **ISMS-Rollen & Funktionstrennung (A4)** | Wizard-Schritt „Rollen": ISMS-Rollen zuweisen, Funktionstrennungs-Regeln FT-01…06 prüfen (z. B. ISB ≠ IT-Leitung), ISB-Bestellung | ✅ |
|
||||
| **Vorlagen-Versionierung & Diff (B6)** | Das Vorlagenpaket ist versioniert; Updates werden je Mandant kontrolliert per Diff-Ansicht (`/policies/updates`) übernommen statt blind überschrieben | ✅ |
|
||||
| **Assessment-Readiness & Export (B7)** | Readiness-Dashboard (Reifegrad-Interpretation, C9) **plus** VDA-ISA-Katalog-Export (CSV) und Management-Zusammenfassung — Grundlage für Reporting/Abschluss | ✅ |
|
||||
| **Wizard-Schritte Richtlinien & Risiken (B)** | Onboarding-Schritte 4 (Richtlinien) und 6 (Risiken) zeigen den echten Modul-Status statt Platzhaltern — der Wizard ist damit über alle 9 Schritte durchgängig | ✅ |
|
||||
| **Umsetzungshinweise im Control-Schritt (#10)** | Je Control-Anforderung lassen sich die Umsetzungshinweise **dokumentieren, abhaken und in eine Aufgabe überführen**; der Umsetzungsstatus je Spiegelstrich fließt in den Reifegrad ein (`ControlImplementation`) | ✅ |
|
||||
| **Aufgaben/Maßnahmen-Vereinheitlichung (7-9)** | Aufgaben und Maßnahmen im selben Bedien-Design (gemeinsamer Anlage-Dialog); Standardmaßnahmen aus dem Risikokatalog werden zu echten, verknüpften Maßnahmen; neue Rolle **`pm`** mit Voll-Sicht auf Aufgaben (`task:read_all`) | ✅ |
|
||||
| **Wizard-UX-Feinschliff (#1/#3/#6)** | Interne Identifier aus den Wizard-Texten entfernt, Assets-Schritt gibt Rückmeldung beim „Aufgaben anlegen", Aufgaben-Sichtbarkeit als Pool-Popup | ✅ |
|
||||
| **Asset-Schritt (A5)** | Wizard-Schritt 5 bindet das Bestands-/Asset-Modul ein — Assets werden im Onboarding erfasst statt separat | ✅ |
|
||||
| **Control-Assessment & Reifegrad (A7)** | Wizard-Schritt 7: Controls bewerten (Belegstatus, Reifegrad R0–R3, Zielreifegrad); offene Punkte erzeugen automatisch Gap-Aufgaben | ✅ |
|
||||
| **Standard-Risikokatalog (A6)** | Vorgefertigter Risikokatalog (C4) zum Übernehmen; Standardmaßnahmen erzeugen Aufgaben; dokumentierte **Restrisiko-Akzeptanz** (VA-09) | ✅ |
|
||||
| **Gap-Konsolidierung (A8)** | Wizard-Schritt 8 bündelt alle offenen Punkte/Gaps aus den Schritten — dedupliziert, priorisiert (Quick-Wins) und gleicht sie mit Aufgaben ab | ✅ |
|
||||
| **Freigabe-Workflow + Aufgaben** | Einreicher wählt Freigeber → Aufgabe; Freigeben/Ablehnen (mit Kommentar) im Modul „Aufgaben" (Vier-Augen); Dashboard-Kachel für offene Freigaben | ✅ |
|
||||
| **Nicht-destruktiver Re-Import** | Richtlinien-Paket-Updates erhalten Status/Freigabe/Overrides/Variablenwerte; entfernte Einträge werden deaktiviert statt gelöscht; Änderungsreport | ✅ |
|
||||
| **GAP-Report Richtlinien** | 6 neue Verfahrensanweisungen (VA-14..19), alle zuständigen VAs inline verlinkt, Rendering-Fehler behoben, verwaltete Register editierbar | ✅ |
|
||||
| **Software-Verwaltung** | Software ist ein Asset (Typ SOFTWARE) und wird im Lieferantenbereich unter „Software" gepflegt (Popups wie IT-Services): Anbieter/Lieferant, Version/Patch-Stand, Freigabestatus, Freigeber, Review. Ersetzt die frühere „Software-Whitelist" | ✅ |
|
||||
| **Projekte** | Projekte sind Assets (Typ PROJECT) im Assetinventar: bewertbar wie Assets (Kritikalität C/I/A), Risiken zuordenbar, IS-Klassifizierung, ISB-Einbindung, Projektstatus — Bedienung als Popup | ✅ |
|
||||
| **Kritische IT-Dienste** | Schreibgeschützte Auto-Sicht (`/assets?view=critical`): leitet kritische Dienste automatisch aus Verfügbarkeit und BIA ab, mit RTO/RPO aus den verknüpften Prozessen und Abhängigkeiten — keine gepflegte Doppelliste mehr | ✅ |
|
||||
| **Register-Konsolidierung** | Doppelte Register (externe IT-Dienste, Software-Whitelist, kritische Dienste, Projekte) entfernt und in die Fachmodule überführt; Richtlinien-Verweise zeigen jetzt auf die Module. REG-NET (Netzplan) auf ein Referenz-/Speicherort-Feld reduziert | ✅ |
|
||||
| **Produktmarke Certvia** | Die Anwendung heißt und erscheint durchgängig als **Certvia** — Logo und Wortmarke, Tab-/App-Icon, Seitentitel, Anmelde- und Fehlerseiten, Druckansicht. GEFIM bleibt als Dachmarke sichtbar („Ein Produkt von GEFIM"). Ohne eigenes Mandanten-Logo zeigt jeder Kunde Certvia. Reine Design-Umstellung ohne Funktionsänderung | ✅ |
|
||||
| **Wizard-Parallelisierung (Fix)** | Bearbeitung und Validierung im Onboarding-Wizard entkoppelt — Schritte können parallel bearbeitet werden, statt streng nacheinander; dazu `scripts/sync-role-permissions.ts` zum Nachziehen neuer Rechte für bestehende Mandanten | ✅ |
|
||||
|
||||
### 🟥 Bewusst zurückgestellt / offen
|
||||
|
||||
| Thema | Anmerkung |
|
||||
|-------|-----------|
|
||||
| **Paket 4 — SMTP + E-Mail-Einladungs-/Reset-Flow** | Auf Kundenwunsch später; Aktivierung läuft vorerst über Initial-/Einmal-Passwort, gekapselt für spätere Token-Aktivierung |
|
||||
| **Netzplan-Datei-Upload (REG-NET)** | Datei-Upload-/Storage-Infrastruktur existiert noch nicht; REG-NET verweist vorerst per Feld auf den extern gepflegten Netzplan. Upload als eigenes Paket (Storage-Backend + Coolify-Volume) |
|
||||
| **Tenant-weite MFA-Pflicht scharfschalten** | Flag `securityPolicy.mfaRequired` vorhanden + von „MFA deaktivieren" respektiert; Enrollment-Erzwingung beim Login noch nicht verdrahtet (analog Force-Change-Gate) |
|
||||
| **Admin Phase 2** | Impersonation, Plan/Limits, Logo-Upload, DSGVO-Export/Retention |
|
||||
| **NIS2-Modul** | nie begonnen (großes Framework, Incident-Reporting mit Fristen-Timern) |
|
||||
| **Richtlinien-Versionierung/Diff, DOCX/PDF-Export** | offen |
|
||||
| **ISB-Freigabe der neuen GAP-Texte** | fachlicher Prozessschritt (kein Code): neue/geänderte VA-/Richtlinien-Texte durch den ISB freigeben |
|
||||
| **Platzhalter-Module** | SoA & Controls, Vorfälle, Nachweise, Management-Review, KI-Chat |
|
||||
|
||||
---
|
||||
|
||||
## 3. Für neue Entwickler — technische Landkarte
|
||||
|
||||
> Setup, Stack, Konventionen und Fallstricke unverändert in **`docs/HANDOVER-DEV.md`** (§1–§9). Hier nur, was `dev` ergänzt.
|
||||
|
||||
### 3.1 Neue Datenmodelle (Prisma)
|
||||
|
||||
| Modell | Zweck | Mandantengebunden? |
|
||||
|--------|-------|--------------------|
|
||||
| `PlatformAdmin` | Getrennter Superadmin-Store (kein `tenant_id`), Argon2id, TOTP-Secret, Recovery-Codes, Lockout | nein (plattformweit) |
|
||||
| `PlatformSetting` (Singleton) | Plattform-Policy, u. a. `mfaRequired` | nein |
|
||||
| `Task` / `TaskComment` | Generisches Aufgaben-/Freigabe-Modell (erster Typ `policy_approval`), Kommentar-Historie | ja |
|
||||
| `ManagedRegister` / `RegisterRow` | Generisches editierbares Register (code, columns JSON, Cross-Links supplier/asset) | ja |
|
||||
| `SoftwareProfile` | 1:1 zu `Asset` (Typ SOFTWARE): Anbieter-Verknüpfung (`providerAssetId`→SUPPLIER), Version, Freigabestatus (`SoftwareApprovalStatus`), Freigeber, Kritikalität, Review | ja |
|
||||
| `ProjectProfile` | 1:1 zu `Asset` (Typ PROJECT): IS-Klassifizierung, ISB-Einbindung, `ProjectStatus`. Kritikalität via C/I/A am Asset, Risiken via `RiskAsset` | ja |
|
||||
| `AssetType` neu | Enum um `SOFTWARE` und `PROJECT` erweitert | — |
|
||||
| `User.*` neu | `mustChangePassword`, `mfaEnrolledAt`, `recoveryCodes` | ja |
|
||||
| `PolicyDocument.archivedAt`, `PolicyRequirement.archivedAt` | Lifecycle für nicht-destruktiven Re-Import (deaktivieren statt löschen) | ja |
|
||||
| `AuditLog.tenantId` nullable | Plattform-Ereignisse ohne Mandantenbezug (`scope=platform`) | — |
|
||||
| `WizardScope` (A2) | Scope des Onboarding-Wizards: Prüfziele, Geltungsbereich, Standorte, Ausschlüsse — Basis der Scope-Filter-Engine (`scope-filter.ts`) | ja (RLS) |
|
||||
| `ImplementationHint` (B5) | Globaler C6-Umsetzungshinweis-Katalog je Anforderung (organisatorisch/technisch/Nachweise/Ressourcen, AL-Filter) | nein (globaler Katalog, kein RLS) |
|
||||
| `PolicyPackageState` (B6) | Je Mandant: Version/Stand des importierten Vorlagenpakets — Basis für kontrollierte Diff-Übernahme von Updates | ja (RLS) |
|
||||
| `ControlAssessment` (A7) | Je Mandant/Control: Belegstatus, Reifegrad (R0–R3), Zielreifegrad — Basis für Gap-Aufgaben und SoA | ja (RLS) |
|
||||
| `RiskCatalogEntry` (A6) | Globaler Standard-Risikokatalog (C4) zum Übernehmen — Content identisch je Mandant | nein (globaler Katalog, kein RLS) |
|
||||
| `ControlImplementation` (#10) | Je Mandant/Control-Spiegelstrich: Umsetzungsstatus (dokumentiert/abgehakt), koppelt an Reifegrad und Aufgaben | ja (RLS) |
|
||||
| `Task.description` (7-9) | Beschreibungsfeld am bestehenden `Task` (Migration `task_description`) für die Aufgaben/Maßnahmen-Parität | ja |
|
||||
| `Risk.acceptedAt/By/Rationale` (A6) | Restrisiko-Akzeptanz-Felder am bestehenden `Risk` (Migration `risk_acceptance`) | ja |
|
||||
|
||||
Alle neuen tenant-gebundenen Modelle sind in **`TENANT_MODELS`** (`src/server/db.ts`) und haben **RLS-Policies** (in den jeweiligen Migrationen).
|
||||
|
||||
### 3.2 Auth-Architektur (wichtig!)
|
||||
|
||||
- **Zwei getrennte NextAuth-Instanzen:** Mandanten-Login (`src/server/auth.ts`, `/login`) und **Plattform-Login** (`src/server/platform-auth.ts`, eigener Cookie + basePath `/api/platform-auth`, `/platform/login`). Plattform-Session trägt **keinen** `tenantId`.
|
||||
- **Superadmin-Bereich** liegt unter `src/app/(platform)/…` (Layout erzwingt Plattform-Session + ggf. MFA); Mandanten-App unter `src/app/(app)/…`.
|
||||
- **MFA-Helfer** `src/server/mfa.ts` (otplib TOTP + Recovery-Codes) — von Plattform- und Nutzer-MFA gemeinsam genutzt.
|
||||
- **Force-Change:** `(app)`-Layout prüft Kontostatus/`mustChangePassword` autoritativ aus der DB → `/change-password` bzw. Abmelde-Screen bei deaktivierten Konten.
|
||||
- **Passwort-Policy:** `src/lib/password-policy.ts` (reine Validierung, client-safe) + `src/server/password.ts` (Argon2id + Generator); Quelle `TenantSettings.securityPolicy.password`.
|
||||
|
||||
### 3.3 Modul-Durchsetzung (§3.4) — Konvention für neue Actions
|
||||
|
||||
- Jede mutierende Server-Action eines **gegateten Moduls** läuft über `moduleGuard("<key>")` (`src/server/action-guard.ts`): Session → `assertModuleEnabled` → RBAC.
|
||||
- **Vollständigkeitscheck** `scripts/check-module-guards.ts` (als `prebuild` verdrahtet): jede Datei in `src/server/actions/` muss dort eingetragen sein (Modul-Key oder `EXEMPT`), sonst **failt der Build**. → Neue Action-Datei? Dort eintragen.
|
||||
- Neues Modul **`tasks`** in `src/lib/modules.ts` (für Bestands-Tenants per Default aktiv, da fehlende `TenantModule`-Zeile = aktiv).
|
||||
|
||||
### 3.4 Wo liegt was (neu)
|
||||
|
||||
- **Superadmin/Plattform:** `src/app/(platform)/admin/**`, `/platform/{login,enroll-mfa,profile}`, `src/server/actions/{admin,platform,platform-users}.ts`.
|
||||
- **Benutzer-/Rollenverwaltung (Kunde):** `src/app/(app)/settings/users/`, `src/server/actions/{tenant-users,account}.ts`, Komponenten `user-table.tsx`/`user-forms.tsx`/`role-manager.tsx`.
|
||||
- **Aufgaben/Freigabe:** `src/app/(app)/tasks/`, `src/server/actions/tasks.ts` (+ `submitForApproval` in `policies.ts`); Dashboard-Kachel in `dashboard/page.tsx`.
|
||||
- **Register:** `src/components/generic-register.tsx`, `src/server/actions/register.ts`, Definitionen in `prisma/import-managed.ts` (`GENERIC_REGISTERS` + `RETIRED_REGISTERS`-Cleanup).
|
||||
- **Software (Lieferantenbereich):** Tab in `src/app/(app)/suppliers/page.tsx` (`?tab=software`), `src/components/software-modals.tsx`, `src/server/actions/software.ts`, `SOFTWARE_INCLUDE` in `src/lib/supplier-include.ts`.
|
||||
- **Projekte (Assetinventar):** Typ-Filter/Popup in `src/app/(app)/assets/page.tsx`, `src/components/project-modals.tsx`, `src/server/actions/projects.ts`, `PROJECT_INCLUDE` in `src/lib/supplier-include.ts`.
|
||||
- **Kritische IT-Dienste:** Auto-Sicht-Zweig in `src/app/(app)/assets/page.tsx` (`?view=critical`) — abgeleitet aus Verfügbarkeit + BIA (`ProcessAsset`→`Process`→`BiaEntry`); Link-Ziel von `resolveLink("REG-CRIT-SERVICES")`.
|
||||
- **Richtlinien-Import (nicht-destruktiv):** `prisma/import-policies.ts` (Diff/Upsert, `{ dryRun }`, Änderungsreport, `archivedAt`).
|
||||
- **Richtlinien-Import/Upload (B4):** Actions `src/server/actions/policy-package.ts` (Import-Kapselung: Self-Service `importPolicyPackage` + Plattform `importPolicyPackageForTenant`) und `policy-upload.ts` (`uploadOwnPolicy`); Aktivierungs-Trigger in `toggleTenantModule` (`admin.ts`); Storage-Adapter `src/server/storage/adapter.ts` (Stub, Epic S1); UI `src/app/(app)/policies/page.tsx` (Buttons + Report-Banner) + `src/app/(app)/policies/upload/page.tsx`. Eigene Uploads liegen im Namensraum `EIG-*` (außerhalb des Paket-Namensraums → vom Re-Import unberührt).
|
||||
- **Branding (in `dev`):** Tokens in `src/app/globals.css` (`--brand-*` / `--ui-*`) mit JS-Pendant `src/lib/brand.ts`; Komponenten `src/components/brand/{certvia-logo,tenant-brand,powered-by-gefim}.tsx`; Assets `public/assets/logo/`, `public/favicon/`, `public/site.webmanifest`; Dokument-/Mail-CD `src/lib/{document-brand,email-brand}.ts`; Doku `docs/BRANDING-CERTVIA.md` (+ Design-Paket unter `docs/branding/`).
|
||||
- **Vorlagenpaket (Source of Truth):** `seed/isms-vorlagenpaket-v2/` — 28→**37 Dokumente** (VA-14..19; **P01/D01/VA-20** neu für Prototypen-/Datenschutz, B4-3), `mapping.json` (321 Anforderungen), `variables.schema.json`, Baseline, Nachweisregister, **`_verify.py`** (Rendering-/Anker-Check; nach Änderungen `python3 _verify.py` → **OK**).
|
||||
|
||||
### 3.5 Konventionen / Fallstricke (Ergänzungen)
|
||||
|
||||
- **Dev-Server & Server-Actions:** Änderungen an Server-Actions greifen im Turbopack-Dev manchmal erst nach **Neustart** des Dev-Servers.
|
||||
- **Migrations-Flow Prisma 7** wie gehabt (`migrate diff --from-config-datasource … --to-schema … --script`, dann RLS-DO-Block manuell anhängen, `migrate deploy`). Data-Migrationen (z. B. `strip_tool_variable_articles`) sind reine SQL-`UPDATE`-Migrationen.
|
||||
- **Geteilte DB bei paralleler 2-Lane-Entwicklung (Dev A × Dev B):** Beide Worktrees zeigen auf **dieselbe** lokale Postgres-DB. Dadurch enthält `migrate diff --from-config-datasource` **fremde**, vom anderen Branch angewandte Schemaänderungen (z. B. wollte A1-1 fälschlich Dev Bs `tasks`-Spalten `links/origin/priority/resources` droppen). **Regel:** beim Erzeugen einer Migration nur die **eigenen** DDL-Blöcke übernehmen und Fremd-Drops von Hand entfernen; anschließend prüfen, dass die Spalten/Objekte des anderen erhalten sind. Migrations-Reihenfolge & „nie gleichzeitig" strikt nach Contracts §6. **Merge-Nachsorge:** Wird eine Migration im anderen Branch neu erzeugt (anderer Timestamp) und die geteilte DB hat noch die alte angewandt, meldet `migrate status` „applied ≠ lokal". Fix ohne Datenverlust: stalen `_prisma_migrations`-Eintrag löschen + `prisma migrate resolve --applied <neuer_name>` (kein SQL läuft neu). So geschehen bei `tasks_wizard_fields` (`…103650` in DB → `…104412` committet).
|
||||
- **Zentrale Variablen** (Organisation/Rollen/Schutzbedarf-Flags, `src/lib/policy-variables.ts`) sind im Richtlinien-Editor gesperrt und werden serverseitig geblockt — nur in `/settings` pflegbar.
|
||||
- **Rendering (Variante B):** Tool-Variablen-Defaults ohne führenden Artikel (`TOOL_TICKET`=„Ticketsystem" etc.); der Fließtext setzt Artikel/Deklination. Bestandswerte werden per Migration migriert.
|
||||
- **Register vs. Managed-Register-Docs:** die verwalteten Register (CRYPTO/RISKMATRIX/CLASSIFICATION/HANDBUCH) sind spezifische Modelle; die verbliebenen `REG-*` (SENS-ROLES, AUDIT-PLAN, NET) nutzen das **generische** `ManagedRegister`-Modell. `importPolicies` archiviert nur den Paket-Namensraum (L00/R*/VA-*/BASELINE/NACHWEIS) — Register bleiben unberührt.
|
||||
- **Register-Konsolidierung (Block 5):** REG-EXT-SERVICES / REG-SW-WHITELIST / REG-CRIT-SERVICES / REG-PROJECTS sind **stillgelegt** (Liste `RETIRED_REGISTERS` in `import-managed.ts` löscht Dokument + `ManagedRegister` + Zeilen idempotent beim Import). Ihre `{{LINK:REG-…}}` in den Seed-Texten bleiben unverändert — nur `resolveLink` (`src/lib/policy-render.ts`) biegt sie auf die Modul-Routen um (`/suppliers?tab=services|software`, `/assets?view=critical`, `/assets?type=PROJECT`). Wer ein Register neu stilllegen will: Code aus `GENERIC_REGISTERS` entfernen, in `RETIRED_REGISTERS` eintragen, `resolveLink`-Fall ergänzen.
|
||||
- **Software/Projekte als Asset-Typen:** folgen exakt dem bestehenden Muster von SUPPLIER/IT_SERVICE (Asset + 1:1-Profil, `refNo` je Mandant, Cockpit-Popups auf `/suppliers` **und** `/assets`, backHref-gesteuert). Neue Action-Dateien (`software.ts`→`suppliers`, `projects.ts`→`assets`) sind in `scripts/check-module-guards.ts` registriert.
|
||||
|
||||
### 3.6 Demo-Logins (Passwort `Demo1234!`)
|
||||
|
||||
- Mandanten-Login `/login`: `admin@demo.example` (Mandanten-Admin + ISB), **`bea.approver@demo.example`** (ISB, zweiter Freigeber für den Vier-Augen-Workflow), `auditor@…`, `owner@…`, `user@…`.
|
||||
- Plattform-Login `/platform/login`: `admin@demo.example` (getrennte Session; MFA optional, Enrollment beim ersten Login nur wenn Policy es verlangt).
|
||||
|
||||
---
|
||||
|
||||
## 4. Commit-Übersicht (`main..dev`, neueste zuerst)
|
||||
|
||||
```
|
||||
55260a7 Merge SEC3+SEC4 (MFA pro Mandant erzwingen, WebAuthn/Passkeys, TOTP-Verschlüsselung at rest, Plattform-Admin-Verwaltung) in dev
|
||||
8a154f0 Merge TISAX v7-Fortsetzung (Fachbereich-Ableitung beim Import, Richtlinien nach Fachbereich im Onboarding, parametrisierbares Redirect-Ziel) in dev
|
||||
a0c0d14 Merge TISAX v6/v7 (ABGABE-xlsx-Export, echter MinIO/S3-Adapter, PolicyDocument.domain/Fachbereich, Audit-Permissions) in dev
|
||||
850b691 Merge TISAX v5 (Audit-Vorbereitung Phase 1: Audit-Übersicht/Wizard-Shell, Readiness/GAP-Tab, Nachweise-Tab, Control-Beschreibungen mit KI-Entwurf + ABGABE-CSV-Export) in dev
|
||||
6370cee Merge TISAX v4 (Prozesshaus-Ausbau: Löschen, Katalog-Teilprozesse parentCode, Details-Overlay; BIA-Popup vereinfacht + Träger-/Risiko-Neuanlage) in dev
|
||||
23df560 Merge TISAX v3 (Prozesshaus + geführtes BIA je Prozess, Popup-Bearbeitung Rollen/Kriterien, zusätzliche Prozess-Felder) in dev
|
||||
f1c11aa Feature: Plattform-Konsole legt Tenant-Nutzer per Einladungslink an (wie Mandanten-Admin)
|
||||
2bfc071 Merge TISAX-Integration (M0–M4 + Wizard-Neustruktur) in dev — Fundament, Strukturanalyse, Cockpit (RACI/Evidence), Audit-Wizard, TISAX-Tasks, Content-Seed; 3 Migrationen + RLS für neue Tabellen
|
||||
2fd522c Feature: Benutzer-Anlegen verschickt Einladungslink per Mail (invitation-Template, /reset-Token 7 Tage) statt Passwort-Anzeige
|
||||
4d28c86 Fix: Benutzer-/Mail-Actions graceful statt Fehlerseite + Formular-Werterhalt
|
||||
6b4c6fb Coolify: Mail-Worker-Service (SEC1) ergänzt
|
||||
c47ace0 Merge SEC1+SEC2: Mailversand/Queue (SEC1, BullMQ/ioredis/nodemailer, Worker) + Auth-Self-Service (SEC2, AuthToken, Reset/Passwortwechsel/E-Mail-Änderung, Session-Invalidierung, Rate-Limit) in dev
|
||||
3998f9f Fix: /tasks SSR-Crash — entfernte Variable `open` im Untertitel wiederhergestellt
|
||||
3932ff2 Merge 7-9/4: Aufgaben als Kanban-Board (Maßnahmen-Design) + Vorschläge/Bearbeiten korrigiert in dev
|
||||
00e7e79 Dockerfile: Fachcontent (docs/wizard-uebergabe) ins migrate-Image für Demo-Seed (C4/C6)
|
||||
fb1935e Dockerfile: Richtlinien-Vorlagenpaket (seed/) in migrate- und runner-Image
|
||||
d0dfe0b Merge Security: P1/P2/P3-Härtungspaket (F-01…F-20) in dev — Tenant-Isolation, Auth/Session, RLS scharf (F-04), moduleGuard-DB-Authz (F-06), Web-Härtung, MFA-Replay, Supply-Chain/Container (F-11/F-18)
|
||||
63b583d Merge Dev-A: A6-1 + A6-2 (Standard-Risikokatalog C4, Standardmaßnahme→Aufgabe, Restrisiko-Akzeptanz) in dev
|
||||
e6c5e51 Merge Dev: UX-Fixes (#1/#3/#6) + Aufgaben/Maßnahmen-Vereinheitlichung (7-9) + Umsetzungshinweise Control-Schritt (#10, ControlImplementation) in dev
|
||||
6b4b190 Merge Dev-B: Wizard-Schritte 4 (Richtlinien) + 6 (Risiken) — echte Komponenten statt Platzhalter in dev
|
||||
0629613 Merge Branding: Umstellung auf Certvia (Design-Tokens, Logo/Icons, Metadaten, i18n, Auth-/Systemseiten, Dokument-CD) in dev
|
||||
7f4a85c Merge Fix: Wizard-Bearbeitung von Validierung entkoppeln (Parallelisierung) + Rollen-Rechte-Sync-Skript in dev
|
||||
6b20e13 Merge Dev-B: B7-2 (VDA-ISA-Katalog-Export CSV + Management-Zusammenfassung, C9) in dev
|
||||
2cc422c Merge Dev-A: A8-1/A8-2 (Gap-Konsolidierungs-Engine) + A8 (Gap-Schritt 8: Aggregation/Priorisierung/Task-Abgleich) in dev
|
||||
76cfebc Merge Dev-A: A5-1 (Asset-Schritt) + A7-1/A7-2 (Control-Assessment + Reifegrad-Engine) in dev
|
||||
7dc5ae1 Merge Dev-B: B6 (Vorlagenpaket-Versionierung + kontrollierte Diff-Übernahme) in dev
|
||||
1238564 Merge Dev-B: B7-1 (Assessment-Readiness-Dashboard + Interpretationstexte C9) in dev
|
||||
de76856 Merge Dev-A: A4 (ISMS-Rollen Schritt 3 + Funktionstrennung FT-01…06) in dev
|
||||
012c0fa Merge Dev-B: Prüfziele als Single Source aus WizardScope (Doppelquelle behoben) in dev
|
||||
227d7a3 Merge Dev-A: A3-1 (generisches Objekt-Review / Validierungs-Workflow) in dev
|
||||
8c9f648 Merge Dev-B: B5-1 + B5-2 (Umsetzungshinweise C6, kontextsensitives Panel) in dev [+ 98d5e26 B5-1, 93e2f44 B5-2]
|
||||
d5c11df Merge Dev-A: A2-1 + A2-2 (Assessment-Level zentral, Scope-Filter) in dev [+ 69cc25a A2-1, 177df8b A2-2]
|
||||
78be114 Doku: STAND B4 · c473cad B4-3 (P01/D01/VA-20) · eb7c899 B4-2 (Upload) · 269506b B4-1 (Import) — Dev B, per FF in dev
|
||||
4e1b116 Merge Dev-B: B3 Fragebogen (Schritt 2 context) in dev [+ f818093 B3-Feature-Commit]
|
||||
872c35e Merge Dev-B: F3+B2 Regel-/Mapping-Engine in dev [+ 20afd63 B2-Feature-Commit]
|
||||
(DevOps-Integration: dev-b2-regel-engine + dev-b3-fragebogen additiv gemergt; Gate grün)
|
||||
b9d8027 Story A1-2: Dashboard-Kachel „Onboarding-Fortschritt" (Dev A)
|
||||
949d7c5 Story F2: ObjectReviewStatus + external_validator + Wizard-Validierung (Dev A)
|
||||
12c94fe Merge Dev-B-Lane in dev: F1 + B1 + F4 (Konsolidierung beider Lanes)
|
||||
0d52090 F4: Wizard-Flags in variables.schema.json (Dev B)
|
||||
ddd2dc4 B1: Auto-Generierung von Aufgaben-Vorschlägen (C2 §8) (Dev B)
|
||||
30c3638 F1: Task-Objekt um Wizard-Felder erweitern (Contracts §1) (Dev B)
|
||||
97b3b4e Story A1-1: Onboarding-Wizard-Shell (Step-Registry, State-Machine, Gate) (Dev A)
|
||||
(darüber Wizard-Kickoff-Commits: Sign-off, Dev-B-Bestätigung, Contracts, Übergabepaket)
|
||||
(sowie lokale Doku-Commits — Onboarding-Prompt + STAND-Updates)
|
||||
f368d8f Fix: Fonts selbst hosten (next/font/local) + Bootstrap an Superadmin-Store anpassen
|
||||
cc8d486 Feat: Prod-Bootstrap (Erst-Superadmin) + Contabo-Runbook
|
||||
── ab hier auf origin/dev (gepusht) ──
|
||||
9b479ab Software und Projekte als Assets + Auto-Sicht kritische Dienste
|
||||
150a1d9 Register-Konsolidierung: 4 Register in Fachmodule überführt
|
||||
0806030 Datenmodell: Asset-Typen SOFTWARE und PROJECT mit Fachprofilen
|
||||
2ec0230 Doku: Konsolidierte Übergabe des dev-Stands (PM + neue Entwickler)
|
||||
95d4479 GAP WP3.1: IMPL-Texte mit verwalteten Registern verdrahtet
|
||||
bd56a47 GAP WP3.0: Generisches, editierbares Register-Datenmodell + Editor
|
||||
b9784e5 GAP E2: ISA 3.1.3-Stub entfernt (3.1.2 deprecated)
|
||||
b7d5df4 GAP WP2.2 (Rendering Variante B) + WP4 (Feinschliff)
|
||||
36c2903 GAP WP1: Neue VAs 14–19 + Register + Baseline + Eltern-Wiring
|
||||
522508a GAP WP2.1: Inline-VA-Verweise + Verify-Fix (F17)
|
||||
742277f Doku: Benutzer-Popups, Aufgaben-Modul, Richtlinien-Governance, Demo-Approver
|
||||
1d8f563 Freigabe-Workflow + Aufgaben-Modul + Dashboard-Kachel
|
||||
73c9813 Benutzerverwaltung als Popup (Einstellungen + Admin)
|
||||
959d816 Richtlinien-Fixes: zentrale Variablen, Schutzbedarf zentral, Coverage nach Level
|
||||
d38b265 Benutzer bearbeiten (Name/E-Mail) + Kern-Einstellungen nur Superadmin
|
||||
303dcd0 Doku: Produktionshärtung + Benutzer-/Rollenverwaltung
|
||||
d0821e2 Paket B — Mandanten-Admin: Benutzer- & Rollenverwaltung
|
||||
3db820e Paket C — MFA optional (Superadmin + Tenant)
|
||||
908b098 Paket A — Plattform-Admin: Benutzerverwaltung je Mandant
|
||||
db36c79 Fundament Benutzer-/Rollenverwaltung: Schema, Passwort-Policy, Force-Change
|
||||
e07dcd9 Nicht-destruktiver Richtlinien-Re-Import (Härtung Paket 3)
|
||||
8e4040d Separater Superadmin-Store + eigener Login + MFA (Härtung Paket 2)
|
||||
8348764 API-seitige Modul-Durchsetzung (§3.4, Härtung Paket 1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Deployment & Verifikation
|
||||
|
||||
- **Test-/Coolify-Deploy (Demo):** `dev` deployen; die 7 neuen Migrationen laufen automatisch im Init-Container (`prisma migrate deploy`), Bootstrap-Seed legt Demo-Daten + Demo-Approver an. Die letzte Migration ändert das `AssetType`-Enum und legt zwei RLS-Tabellen an — einmal komplett durchlaufen lassen, bevor die neuen Ansichten getestet werden.
|
||||
- **Prod-Deploy (ohne Demo-Seed):** Runbook **`docs/DEPLOY-PROD-CONTABO.md`**. Statt Demo-Seed läuft `scripts/bootstrap-admin.ts` (Erst-Superadmin im `platformAdmin`-Store + Mandant/Mandanten-Admin, idempotent), gesteuert per `BOOTSTRAP_*`-Env im `migrate`-Job der `docker-compose.coolify.yml`; Env-Referenz `.env.prod.example`. Fonts sind selbst gehostet (kein Google-Fonts-Fetch zur Build-Zeit → reproduzierbarer Offline-Build).
|
||||
- **Lokale Verifikation:** `npx tsc --noEmit` → `npm run lint` → `npm run build` (führt `prebuild`-Guard-Check aus); für das Vorlagenpaket `python3 seed/isms-vorlagenpaket-v2/_verify.py` (**OK** = rückstandsfrei, Mapping sauber).
|
||||
- **Sync-Status (Gitea aktuell offline):** lokaler `dev` ist **27 Commits vor `origin/dev`** (inkl. der beiden Dev-B-Integrations-Merges F3+B2 und B3). Sobald Gitea erreichbar ist: **erst `git fetch`**, prüfen ob `origin/dev` noch `9b479ab` ist (bzw. ob jemand anderes gepusht hat), dann `git push origin dev`. Bei Divergenz nicht blind force-pushen — abstimmen.
|
||||
- **Merge `dev` → `main`:** liegt beim PM/Lead (Gitea-PR: `…/msolarczek/ISMS-Tool/pulls/new/dev`).
|
||||
|
||||
---
|
||||
|
||||
## 6. Empfohlene nächste Schritte
|
||||
|
||||
1. **ISB-Freigabe** der neuen/angepassten Richtlinien- und VA-Texte (fachlich, inkl. **P01/D01/VA-20** aus B4-3).
|
||||
2. **Storage-Backend (Epic S1)** — echten Adapter hinter `src/server/storage/adapter.ts` (B4-2-Stub) einhängen (S3/MinIO/Coolify-Volume); danach Datei-Persistenz eigener Richtlinien + Netzplan-Upload REG-NET.
|
||||
3. **Wizard-Stories vollständig konsolidiert** — Dev A: A1–A8, Dev B: F1–F4, B1–B7 (inkl. B7-2 Export + Prüfziel-Follow-up). **Alle Feature-Branches in `dev`.** Als Nächstes (neue Stories/Epics): SoA-/Reifegrad-Auswertungen auf Basis von A7, Reporting-Ausbau auf Basis des VDA-ISA-Exports, echtes Storage-Backend (Epic S1).
|
||||
4. **Paket 4** — SMTP + E-Mail-Einladungs-/Aktivierungs-/Reset-Flow (Aktivierung ist bereits gekapselt).
|
||||
5. **Tenant-weite MFA-Pflicht** scharfschalten (Enrollment-Gate).
|
||||
6. **Admin Phase 2** (Impersonation, Plan/Limits) oder **NIS2-Modul** — je nach Vertriebs-/Compliance-Priorität.
|
||||
|
||||
## Hotfix: Docker-Build brach ohne PASSWORD_PEPPER ab (Deploy-Blocker)
|
||||
- **Symptom:** Coolify-Deploy „erfolgreich", aber KEINE certvia-Container. Ursache war der Image-Build selbst: `RUN npx prisma generate && npm run build` (Dockerfile:40) exit 1 → kein `up`.
|
||||
- **Root Cause:** `src/server/auth.ts` erzeugte den Konstant-Zeit-Dummy-Hash auf **Modulebene** (`const DUMMY_HASH_PROMISE = hashPassword(...)`). `hashPassword()` liest den `PASSWORD_PEPPER`, der zur Docker-**Build**-Zeit fehlt (nur `DATABASE_URL`-Platzhalter gesetzt). `next build` (Page-Data-Collection für `/api/auth/[...nextauth]`) lud das Modul → Import-Zeit-Throw (fail-secure) → Build-Abbruch. Lokal grün, weil `.env` den Pepper liefert (im Image per `.dockerignore` ausgeschlossen).
|
||||
- **Fix:** Dummy-Hash lazy + memoisiert (`dummyHash()`), Aufruf erst zur Laufzeit in `verifyIdentityPassword` — gleiches Muster wie `assertSecureEnv()`/`pepper()`. Konstant-Zeit-Verhalten (F-05) bleibt erhalten.
|
||||
- **Verifiziert:** `docker build --target builder` grün OHNE gesetzten `PASSWORD_PEPPER` (Coolify-Build-Bedingung); tsc grün.
|
||||
|
||||
## Hotfix 2: incident-inbound-worker Crash-Loop riss den Stack ab
|
||||
- **Symptom (nach Build-Fix):** migrate ✅, app ✅ `Ready`, mail-/backup-worker ✅ — aber Coolify-Status flippte auf „exited" und riss den ganzen Stack ab. Ursache: `incident-inbound-worker` ohne IMAP-Konfig `process.exit(1)` + `restart: unless-stopped` → Crash-Loop → Coolify wertet Deploy als unhealthy → `compose down` (auch der gesunden App).
|
||||
- **Fix:** `scripts/incident-inbound-worker.ts` idlet jetzt bei fehlender IMAP-Konfig (`idleUntilSignal()`), statt zu exiten. Container bleibt „running", SIGTERM beendet sauber (Exit 0). Bei nachträglicher IMAP-Konfig: Container-Neustart aktiviert den Betrieb.
|
||||
- **Verifiziert:** tsc grün; Smoke-Test ohne IMAP-Env → Prozess bleibt am Leben, loggt Idle-Hinweis, kein Crash.
|
||||
|
||||
## Merge: Objektspeicher MinIO → Garage (self-hosted)
|
||||
- feature/garage-migration → dev (`--no-ff`). Umsetzung des Konzepts `docs/KONZEPT-garage-migration.md` (4 Lanes), keine Datenmigration (nur Test-Instanzen, Neu-Deploy).
|
||||
- **Infra:** `garage`-Service ersetzt `minio` in `docker-compose.yml` + `docker-compose.coolify.yml`; `deploy/garage.toml` (Single-Node, `s3_region=us-east-1`, RPC-/Admin-Token); Volumes `garage_meta` (kritisch, ins Backup) + `garage_data`.
|
||||
- **Provisioning:** `scripts/garage-provision.ts` — idempotenter Init-Job (Layout + Bucket `isms-documents` + Key-Import aus S3_*-Env + Rechte).
|
||||
- **App-Code:** `ensureBucket()` in `adapter.ts` + `backup-store.ts` nur noch verifizierend (HeadBucket), **kein** S3-`CreateBucket` mehr (Garage kann das nicht); fehlender Bucket → sprechender Konfigfehler statt stiller Heilung. `CreateBucketCommand`-Imports entfernt.
|
||||
- **Test/Doku:** `scripts/test-garage-storage.ts` (skippt ohne `S3_ENDPOINT`, echter E2E mit gesetzten S3_*), Runbook in `docs/DEPLOY-COOLIFY.md`.
|
||||
- **Gate grün:** tsc, lint, build, Storage-Smoke-Test.
|
||||
- **Deploy-Hinweise:** Coolify-Env `S3_ENDPOINT=http://garage:3900`, `S3_REGION=us-east-1`, `GARAGE_RPC_SECRET`/`GARAGE_ADMIN_TOKEN` **literal** setzen (Interpolationsfalle); `minio`-Service erst nach Abnahme entfernen (Rollback-Netz).
|
||||
|
||||
## Hotfix Garage-Deploy: garage.toml ins Image backen (Coolify-Bind-Mount-Falle)
|
||||
- **Symptom:** `garage`-Container crasht ~2s nach Start → unhealthy → Deploy bricht ab. Log: `Error: IO error: Is a directory (os error 21)` nach „Loading configuration…".
|
||||
- **Ursache:** Coolify legt die Quelle des relativen Bind-Mounts `./deploy/garage.toml` als **Verzeichnis** an (Storage-Behandlung) → Garage bekommt `/etc/garage.toml` als Ordner.
|
||||
- **Fix:** Neue Dockerfile-Stage `garage` (`FROM dxflrs/garage:v1.2.0` + `COPY deploy/garage.toml /etc/garage.toml`); `docker-compose.coolify.yml` nutzt `build: target garage` statt `image:` + Bind-Mount. Secrets bleiben zur Laufzeit aus `GARAGE_RPC_SECRET`/`GARAGE_ADMIN_TOKEN`. Lokales `docker-compose.yml` behält den Bind-Mount (auf normalem Docker unkritisch).
|
||||
- **Verifiziert:** `docker build --target garage` + Start mit gültigem Secret → Daemon läuft, `/garage status` Exit 0.
|
||||
|
||||
## Merge: Framework-Erweiterung — ISO 27001 neben TISAX (AP1–AP5 + B1)
|
||||
- Kumulativer Merge von `feature/framework-assessment` (enthielt alle Framework-Lanes: iso27001-framework-mapping, framework-core, ap2, ap3-soa, ap4-mgmt, ap5-doccontrol, assessment) → `dev` (`--no-ff`, a747b57). 150 Dateien.
|
||||
- **AP1** Framework-Dimension (`TenantFramework`, `PolicyTemplateVersion.framework`), **AP2** Provisionierung & Framework-Flags + framework-fähiger Vorlagen-Editor, **AP3** SoA-Modul (ISO-Anwendbarkeitserklärung, 93 Annex-A-Zeilen), **AP4** Managementklauseln (9.1/9.3/10.2, CAPA + Wirksamkeitsprüfung), **AP5** Dokumentenlenkung (Prüfzyklen, Versionshistorie, Lesebestätigungen), **A1–A4/B2/B3** ISO-Inhalte, **B1** Assessment-/Readiness-Strategie-Schicht.
|
||||
- **Variante A** (Konzept D4): ein Dokumentensatz, zwei Mappings — `docs/FRAMEWORK-MAPPING-ISO27001.md`, `docs/KONZEPT-framework-iso27001.md`.
|
||||
- **Gate grün:** tsc, lint, build. Neue Tests grün: `test-framework-{core,templates,provision,assessment,dryrun}`, `test-{assessment-iso,soa,doc-control,review}`. **TISAX-Snapshot-Regression: 0 Abweichungen** (45 Controls, AL2) — TISAX-Verhalten bit-genau erhalten.
|
||||
|
||||
## Fix: Normen (Frameworks) je Mandant nachträglich umschaltbar
|
||||
- `cb2bc0b` Admin-Action + UI (`admin/[id]/page.tsx`, `actions/admin.ts`, i18n de/en): ISO/TISAX pro Mandant nachträglich aktivieren/deaktivieren. `1475193` Abnahmetest-Fix: „wiedererkannt" zählt reaktivierte Dokumente mit.
|
||||
- Neuer Test `scripts/test-framework-toggle.ts` (Aktivieren/Deaktivieren + Zustand wiederherstellen). Gate grün: tsc/lint/build, test-framework-toggle/-dryrun, TISAX-Snapshot 0 Abweichungen.
|
||||
|
||||
## BIA-Prozessübersicht: Prozesshaus-Ansicht (Standard) + Tabellen-Umschalter
|
||||
- `/processes` (`src/app/(app)/processes/page.tsx`) zeigt statt der flachen Tabelle standardmäßig ein **Prozesshaus**: Bahnen nach Kategorie (Management/Kern/Support), Hauptprozesse als aufklappbare Karten (native `<details>`), Teilprozesse eingerückt (Baumkonnektor). Je Hauptprozess **BIA-Rollup** aus den Teilprozessen: Kritikalität = Maximum, RTO/RPO/MTD = schärfster (kleinster) Wert; Farbcode + Statuspunkt nach `biaStatus`; Schnittstellen (`Process.interfaces`) als Chip. Umschalter „Prozesshaus ⇄ Tabelle“ über `?view=tabelle` (Prozesshaus = Default); Tabellen-Ansicht unverändert.
|
||||
- **Kein Datenmodell-Umbau** — nutzt vorhandene Felder (`parentId`, `category`, `biaStatus`, `BiaEntry`). KPIs: Prozesse gesamt / im Scope / BIA vollständig / hohe Kritikalität (≥3). Modals (Detail/Anlegen/Bearbeiten) unverändert. Neue i18n-Keys unter `processes` (de/en). Gate grün: tsc/lint/build. Konzept-Mockup: `docs/MOCKUP-bia-prozessuebersicht.html`.
|
||||
- **Nachtrag — jetzt umgesetzt:** strukturierte Prozess-zu-Prozess-Abhängigkeiten (siehe nächster Abschnitt); der frühere Freitext `interfaces` bleibt zusätzlich erhalten.
|
||||
|
||||
## Prozess-Abhängigkeiten (strukturiert: „benötigt" / „wird benötigt von")
|
||||
- Neues Modell **`ProcessDependency`** (`source` benötigt `target`, optionale `note`), Migration `20260907084110_add_process_dependencies` **inkl. RLS** (tenant_isolation + FORCE), Unique `(source, target)`, FK-Cascade beim Prozess-Löschen; in `TENANT_MODELS` aufgenommen. Auswahl **innerhalb des Mandanten**.
|
||||
- Server-Actions in `actions/processes.ts`: `addProcessDependency` (idempotenter Upsert, Selbstbezug ausgeschlossen, beide Prozesse müssen existieren) und `removeProcessDependency`; `deleteProcess` löst Kanten in beide Richtungen. Beide `bia:write`-gegated + Audit-Log.
|
||||
- UI: Bearbeiten-Modal neuer Abschnitt „Abhängigkeiten" (Chips + Entfernen, Auswahl-Form „benötigt: [Prozess] + Notiz", plus read-only „wird benötigt von"); Detail-Modal zeigt beide Richtungen; **Prozesshaus** zeigt „↳ benötigt: …"-Chips und „▲ N Prozesse hängen hiervon ab" (Teilprozesse kompakt inline) + Link zum Abhängigkeits-Graph. Neue i18n-Keys `deps*` (de/en). Gate grün: tsc/lint/build, Modul-Guard-Check 45 Dateien ok.
|
||||
- **Netz-/Graph-Darstellung:** `buildDependencyGraph` (`src/server/dependency-graph.ts`) um Prozess→Prozess-Kanten (`ProcessDependency`, Label „benötigt von", Flussrichtung Abhängigkeit→Nutzer) erweitert; sie erscheinen im bestehenden Graphen `/dependencies` (React Flow + dagre) und fließen in Analyse/kritischen Pfad ein. SPOF-Erkennung jetzt auch für **Prozesse** (gemeinsam benötigte Prozesse wie „IT-Betrieb", von denen mehrere kritische Prozesse abhängen). Neuer Client-Filter **„Nur Prozesse"** in `dependency-graph.tsx` (blendet Assets aus → reine Prozess-Abhängigkeitskarte). Verifiziert am `demo`-Mandanten: IT-Betrieb als SPOF (3) korrekt erkannt.
|
||||
|
||||
## Datenimport (Excel) — zurückgezogen
|
||||
- Das zuvor auf `dev` ergänzte Excel-Datenimport-Feature (geteilte Logik `src/server/import/`, UI `/settings/import`, Ops-Skript, Tabelle `ImportRef`/Migration `20260904081701_add_import_refs`, Konzept `KONZEPT-datenimport.md`) wurde **vollständig entfernt** (nie deployt, daher ohne DB-Auswirkung). Bestandsdaten werden weiterhin über die Modul-Formulare bzw. den Onboarding-Wizard erfasst.
|
||||
- `docs/HANDBUCH-KUNDENBETREUUNG.md` bleibt als produkt-/supportorientiertes Einstiegshandbuch für die Kundenbetreuung (Zugang/Rollen, Provisionierung, Framework-Wahl, Module, Onboarding, Support-Fälle, Doku-Verweise) — die Datenimport-Abschnitte wurden herausgenommen.
|
||||
|
||||
## Fix: Risikokriterien 5×5 vervollständigt (Matrix ↔ Einstellungen konsistent)
|
||||
- Bug: Risiko-Bewertung (Formular-Skala 1–5, Matrix 5×5, Score-Schwellen bis 25) war 5×5, aber die Kriterien-Daten nur 4-stufig geseedet (EW_LEVELS=4, Schadensdimensionen 1–4) → 5. Stufe ohne Definition.
|
||||
- Entscheidung (PO): **5×5** — Kriterien ergänzen (Bewertung/Matrix/Score bleiben unverändert).
|
||||
- Seed `prisma/import-managed.ts`: 5. EW-Stufe („Nahezu sicher") + 5. Stufe je Schadensdimension.
|
||||
- Editor `onboarding/steps/criteria/criteria-editor.tsx` (Settings + Wizard geteilt): Typ/Update/Neuanlage/Rendering auf 1–5; `actions.ts` zod-Schema um „5"; `settings/risk-criteria/page.tsx` + `onboarding/steps/criteria/step.tsx` editorDims um „5".
|
||||
- Backfill `scripts/backfill-risk-5x5.ts` (idempotent): ergänzt EW-Stufe 5 + Schadensstufe 5 für Bestandsmandanten. Für Test/Prod nach Redeploy je Instanz einmal ausführen (demo, gefim).
|
||||
- Gate grün (tsc/lint/build); Backfill lokal verifiziert.
|
||||
@@ -0,0 +1,328 @@
|
||||
# Übergabe: Anwendung auf zwei Frameworks umbauen (ISO 27001 neben TISAX)
|
||||
|
||||
**Stand:** 2026-08-21 · **Zielgruppe:** Entwickler:innen · **Vorarbeit:** Branch `feature/iso27001-framework-mapping`, Commit `492d315`
|
||||
|
||||
> **Ausgangslage:** Die Inhaltsseite ist fertig. `seed/isms-vorlagenpaket-v2` trägt jetzt **zwei
|
||||
> Framework-Mappings** auf **einem** Dokumentensatz — `mapping.json` (VDA ISA, 321 Anforderungen) und
|
||||
> `mapping-iso.json` (ISO/IEC 27001:2022, 120 Anforderungen). Die Anwendung kennt das zweite Mapping
|
||||
> noch nicht: `parsePackageFiles` liest `mapping.json` fest verdrahtet.
|
||||
>
|
||||
> **Auftrag:** Framework als erste Klasse im Datenmodell und in der Paketauflösung, damit ein Mandant
|
||||
> ISO, TISAX oder beides führen kann. Danach die drei ISO-Artefakte, die es im Tool noch nicht gibt:
|
||||
> SoA, Kennzahlen, Managementbewertung/Korrekturmaßnahmen.
|
||||
|
||||
Fachlicher Hintergrund und Begründung der Entscheidung: `docs/FRAMEWORK-MAPPING-ISO27001.md`.
|
||||
Gesamtarchitektur und die übrigen Lanes: `docs/KONZEPT-framework-iso27001.md`.
|
||||
|
||||
---
|
||||
|
||||
## 0. Was **nicht** angefasst werden muss
|
||||
|
||||
Die Paketinhalte sind generiert. Wer ISO-Texte oder Zuordnungen ändern will, ändert
|
||||
`_iso_crosswalk.json` bzw. `_iso_sections.json` und lässt `python3 _generate_iso.py` laufen —
|
||||
**nie direkt die Markdown-Dateien**, der Generator überschreibt sentinel-begrenzte Blöcke.
|
||||
|
||||
Danach müssen beide Prüfskripte grün sein:
|
||||
|
||||
```bash
|
||||
cd seed/isms-vorlagenpaket-v2
|
||||
python3 _generate_iso.py # idempotent, zweiter Lauf ändert nichts
|
||||
python3 _verify.py # TISAX-Sicht
|
||||
python3 _verify_iso.py # ISO-Sicht
|
||||
python3 _render_diff.py HEAD # TISAX-Regression gegen den aktuellen Stand
|
||||
```
|
||||
|
||||
Die Sichtbarkeit im Dokument steuern zwei Variablen aus `variables.schema.json`:
|
||||
`FLAG_FW_TISAX` (Default `true`) und `FLAG_FW_ISO27001` (Default `false`).
|
||||
|
||||
### Parallelbetrieb ist vorgesehen
|
||||
|
||||
Sind **beide** Flags gesetzt, rendert das Dokument beide Anforderungssichten untereinander — über
|
||||
**einem** gemeinsamen Umsetzungstext. Genau dafür ist die Bibliothek gebaut:
|
||||
|
||||
```
|
||||
3.2 Sichere Anmeldung
|
||||
*Anforderungsbezug:* VDA ISA 4.1.2 · ISO/IEC 27001 A.8.5
|
||||
|
||||
**Anforderung**
|
||||
*Anforderungen nach VDA ISA 2027:*
|
||||
- **[MUSS]** Verfahren zur Benutzerauthentifizierung nach dem Stand der Technik werden angewandt.
|
||||
- **[SOLL]** Für privilegierte Benutzerkonten werden höherwertige Verfahren genutzt …
|
||||
*Anforderungen nach ISO/IEC 27001:*
|
||||
- **[ISO A.8.5]** Sichere Authentisierungstechnologien und -verfahren sind einzusetzen.
|
||||
|
||||
**Umsetzung bei {{ORG_NAME}}**
|
||||
Die Authentifizierungsverfahren sind risikobasiert ausgewählt … Passwortvorgaben nach BL-IAM-01 …
|
||||
```
|
||||
|
||||
Der Anforderungsbezug steht in einer eigenen Zeile unter der Überschrift und nennt je nach
|
||||
Betriebsart eine oder beide Normen. Die beiden Zwischenüberschriften erscheinen **nur**, wenn
|
||||
tatsächlich beide Frameworks aktiv sind.
|
||||
Die 19 ISO-only-Abschnitte kommen bei einem Doppel-Mandanten additiv hinzu.
|
||||
|
||||
Auf der Datenseite ist der Parallelbetrieb erst nach AP1 möglich: `PolicyRequirement` trägt dann
|
||||
beide ID-Namensräume (`4.1.2-M1` und `A.5.15-1`) nebeneinander — vorausgesetzt, Falle 1.1 ist gelöst.
|
||||
|
||||
---
|
||||
|
||||
## 1. Die vier Fallen — bitte zuerst lesen
|
||||
|
||||
### 1.1 `reconcilePackage` archiviert die Anforderungen des jeweils anderen Frameworks
|
||||
|
||||
**Das ist der kritische Punkt.** `prisma/import-policies.ts:368-371` archiviert jede
|
||||
`PolicyRequirement`, deren `reqId` nicht im importierten Paket steht:
|
||||
|
||||
```ts
|
||||
for (const ex of existingReqs) {
|
||||
if (desiredReqIds.has(ex.reqId) || ex.archivedAt) continue;
|
||||
report.requirements.archived++;
|
||||
await prisma.policyRequirement.update({ where: { id: ex.id }, data: { archivedAt: now } });
|
||||
}
|
||||
```
|
||||
|
||||
Ein ISO-Import in einen Mandanten mit TISAX archiviert damit **alle 321 VDA-ISA-Anforderungen** —
|
||||
und umgekehrt. Die ID-Namensräume kollidieren zwar nicht (`4.1.2-M1` vs. `A.5.15-1`, `@@unique([tenantId, reqId])`
|
||||
bleibt heil), aber der Abgleich muss **framework-scoped** werden:
|
||||
|
||||
- `PolicyRequirement.framework Framework` ergänzen (Backfill `TISAX`),
|
||||
- den Archivierungslauf auf `where: { tenantId, framework }` einschränken.
|
||||
|
||||
Für **Dokumente** gilt das nicht: Beide Mappings lesen dieselben `richtlinien/`- und `verfahren/`-Dateien,
|
||||
`pkg.documents` ist identisch. Ebenso Variablen, Baseline-Parameter und Nachweisregister — die sind geteilt
|
||||
und dürfen genau einmal je Mandant abgeglichen werden.
|
||||
|
||||
### 1.2 Zwei Unique-Constraints brechen bei zwei Frameworks
|
||||
|
||||
| Modell | heute | muss werden |
|
||||
|---|---|---|
|
||||
| `PolicyTemplateVersion` (`prisma/schema.prisma:1639`) | `version String @unique` | `@@unique([framework, version])` — sonst kollidieren ISO 2.1 und TISAX 2.1 |
|
||||
| `PolicyPackageState` (`prisma/schema.prisma:1614`) | `tenantId String @unique` | `@@unique([tenantId, framework])` — sonst merkt sich ein Mandant nur eine Paketversion |
|
||||
|
||||
### 1.3 TISAX darf sich nicht verändern
|
||||
|
||||
Bestandsmandanten müssen bitgenau dasselbe sehen wie heute. Der Renderdiff über alle 17 Richtlinien
|
||||
(TISAX-Kontext vorher/nachher) war bei der Paketumstellung **0 Abweichungen** — dieser Wert ist die
|
||||
Messlatte. `src/lib/policy-render.ts` belegt fehlende Framework-Flags bereits vor
|
||||
(`FLAG_FW_TISAX = true`, `FLAG_FW_ISO27001 = false`), damit ein Bestandsmandant vor dem Paket-Re-Import
|
||||
keine leeren Anforderungsblöcke sieht. **Diesen Fail-Safe nicht entfernen**, auch nicht wenn die Flags
|
||||
später über `TenantFramework` gesetzt werden.
|
||||
|
||||
Nebenbei: `applyProtection` (`src/lib/policy-render.ts:54`) setzt `FLAG_HIGH_PROTECTION` bedingungslos auf `true`
|
||||
mit der Begründung „im TISAX-Modell stets aktiv". Für ISO-Mandanten ist das derzeit folgenlos (die
|
||||
ISO-Blöcke nutzen die Schutzbedarf-Flags nicht), sollte aber beim Bau der `IsoStrategy` bewusst
|
||||
entschieden werden.
|
||||
|
||||
### 1.4 Migrations- und Build-Konventionen
|
||||
|
||||
- Migrationsflow Prisma 7 wie in `docs/HANDOVER-DEV.md:100`: `migrate diff --from-config-datasource … --to-schema … --script`,
|
||||
danach den **RLS-DO-Block manuell** an die `migration.sql` anhängen, dann `migrate deploy`.
|
||||
- Jedes neue mandantengebundene Modell gehört in **`TENANT_MODELS`** (`src/server/db.ts:81`) **und**
|
||||
braucht eine RLS-Policy in seiner Migration.
|
||||
- `scripts/check-module-guards.ts` läuft als `prebuild`-Gate: **jede neue Datei** unter
|
||||
`src/server/actions/` muss dort eingetragen sein (Modul-Key oder `EXEMPT`), sonst schlägt der Build fehl.
|
||||
- Bei paralleler Lane-Entwicklung teilen sich die Worktrees dieselbe lokale Postgres-DB. Beim Erzeugen
|
||||
einer Migration nur die **eigenen** DDL-Blöcke übernehmen und Fremd-Drops von Hand entfernen.
|
||||
- `npm run lint` und `npm run build` müssen vor jedem Commit grün sein (`AGENTS.md:25`).
|
||||
|
||||
---
|
||||
|
||||
## 2. Arbeitspakete
|
||||
|
||||
### AP1 — Framework-Dimension *(Fundament, blockiert alles Weitere)*
|
||||
|
||||
**Schema**
|
||||
|
||||
```prisma
|
||||
enum Framework { ISO_27001 TISAX }
|
||||
|
||||
model TenantFramework {
|
||||
id String @id @default(cuid())
|
||||
tenantId String @map("tenant_id")
|
||||
framework Framework
|
||||
isPrimary Boolean @default(false) @map("is_primary")
|
||||
config Json? // z. B. { tisaxLevel: "AL3" } bzw. { certScope, certBodyTarget }
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
@@unique([tenantId, framework])
|
||||
@@index([tenantId])
|
||||
@@map("tenant_frameworks")
|
||||
}
|
||||
```
|
||||
|
||||
Zusätzlich: `PolicyRequirement.framework`, `PolicyTemplateVersion.framework`,
|
||||
`PolicyPackageState.framework` (siehe Fallen 1.1 und 1.2). Alles additiv, Backfill der Bestandsdaten auf
|
||||
`TISAX`.
|
||||
|
||||
**Paketauflösung**
|
||||
|
||||
| Datei | Änderung |
|
||||
|---|---|
|
||||
| `prisma/import-policies.ts` | `parsePackageFiles(seedDir, mappingFile = "mapping.json")`; Requirements framework-scoped reconcilen |
|
||||
| `prisma/template-store.ts:147` | `resolvePackageForTenant(prisma, tenantId, seedDir, framework)`; `loadPublishedPackage(prisma, locale, framework)`; `getAvailableVersion` ebenso |
|
||||
| `scripts/sync-policy-templates.ts:23` | über **Frameworks × Sprachen** iterieren statt nur über Sprachen |
|
||||
|
||||
Die vier Aufrufer von `resolvePackageForTenant` bekommen den Framework-Parameter durchgereicht:
|
||||
`src/server/provision.ts:139`, `src/server/actions/policy-package.ts:28`, `src/server/actions/admin.ts`,
|
||||
`src/app/(app)/policies/updates/page.tsx:44`.
|
||||
|
||||
**Das Seed-Verzeichnis bleibt für beide Frameworks dasselbe** — die fünf `SEED_DIR`-Konstanten ändern
|
||||
sich nicht, nur der Mapping-Dateiname. Das ist der Vorteil von Variante A.
|
||||
|
||||
**DoD:** Bestandsmandanten laufen unverändert als TISAX; ein Mandant kann mit
|
||||
`frameworks: ["ISO_27001"]`, `["TISAX"]` oder beiden provisioniert werden; bei Doppel-Framework
|
||||
koexistieren 321 + 120 Anforderungen und **keine** ist fälschlich archiviert.
|
||||
|
||||
---
|
||||
|
||||
### AP2 — Provisionierung und Flags *(klein, direkt nach AP1)*
|
||||
|
||||
`ProvisionOpts` (`src/server/provision.ts:37`) um `frameworks: Framework[]` erweitern.
|
||||
`provisionTenant` schreibt die `TenantFramework`-Zeilen, importiert **je Framework** das passende
|
||||
Mapping und setzt die Sichtbarkeits-Flags als `PolicyVariable`:
|
||||
|
||||
| Mandant führt | `FLAG_FW_TISAX` | `FLAG_FW_ISO27001` |
|
||||
|---|:--:|:--:|
|
||||
| nur TISAX | `true` | `false` |
|
||||
| nur ISO | `false` | `true` |
|
||||
| beides | `true` | `true` |
|
||||
|
||||
**Achtung Reihenfolge:** `reconcilePackage` erhält nutzergepflegte Variablenwerte und überschreibt sie
|
||||
nicht. Die Flags müssen also **nach** dem Import gesetzt werden, sonst bleibt der Schema-Default stehen
|
||||
und ein ISO-Mandant sieht die VDA-ISA-Sicht.
|
||||
|
||||
`tisaxLevel` bleibt vorerst auf `TenantSettings`, wird aber als TISAX-scoped dokumentiert (Entscheidung D2).
|
||||
Die AL-Flags dürfen bei einem reinen ISO-Mandanten nicht gesetzt werden.
|
||||
|
||||
**DoD:** Ein frisch provisionierter ISO-Mandant öffnet `/policies` und sieht in jedem Dokument die
|
||||
ISO-Anforderungssicht plus die 19 ISO-only-Abschnitte; keine „ISA"-Klammern in den Überschriften.
|
||||
|
||||
---
|
||||
|
||||
### AP3 — SoA-Modul *(das fehlende ISO-Kernartefakt)*
|
||||
|
||||
Heute ist der Modul-Key `soa` (`src/lib/modules.ts:19`) mit `href: "/soa"` registriert, **die Route
|
||||
existiert aber nicht** — die Logik liegt als Wizard-Schritt 7 in `src/server/actions/soa.ts` und ist ein
|
||||
VDA-ISA-Reifegrad-Assessment (0–3), nicht die ISO-Anwendbarkeitserklärung.
|
||||
|
||||
```prisma
|
||||
model SoaEntry {
|
||||
id String @id @default(cuid())
|
||||
tenantId String @map("tenant_id")
|
||||
framework Framework
|
||||
control String // "A.5.15"
|
||||
applicable Boolean @default(true)
|
||||
justification String // Begründung Einbeziehung ODER Ausschluss
|
||||
source String? // Risiko-ID / gesetzliche / vertragliche Anforderung
|
||||
implementationStatus String @default("geplant") // umgesetzt | teilweise | geplant
|
||||
ownerId String? @map("owner_id")
|
||||
policyCode String? @map("policy_code")
|
||||
evidenceId String? @map("evidence_id")
|
||||
@@unique([tenantId, framework, control])
|
||||
@@index([tenantId])
|
||||
@@map("soa_entries")
|
||||
}
|
||||
```
|
||||
|
||||
Die vier Felder `applicable`, `justification`, `implementationStatus` und die Ausschlussbegründung sind
|
||||
**normative Pflichtangaben** (ISO/IEC 27001:2022, 6.1.3 d) — ohne sie ist die SoA im Zertifizierungsaudit
|
||||
angreifbar.
|
||||
|
||||
Vorbefüllung aus `mapping-iso.json`: 93 Controls; das Feld `condition` (z. B. `FLAG_DEV_INHOUSE`) steuert
|
||||
die Default-Anwendbarkeit. Als fachliche Vorlage für Aufbau und Spalten dient
|
||||
`seed/isms-vorlagenpaket-v2/Statement-of-Applicability-ISO.md`.
|
||||
|
||||
**DoD:** Ein ISO-Mandant kann die SoA vollständig pflegen und als PDF/XLSX exportieren; ein Control ohne
|
||||
Begründung wird als unvollständig markiert.
|
||||
|
||||
---
|
||||
|
||||
### AP4 — Managementklauseln: Kennzahlen, Bewertung, Korrekturmaßnahmen
|
||||
|
||||
Drei Modelle fehlen; alle drei sind ISO-Pflichtthemen und heute nicht abbildbar:
|
||||
|
||||
| Klausel | Modell | Inhalt |
|
||||
|---|---|---|
|
||||
| 9.1 | `Kpi` / `KpiValue` | Kennzahl, Datenquelle, Zielwert, Turnus, Verantwortlicher, Messwerte je Periode |
|
||||
| 9.3 | `ManagementReview` | Datum, Eingaben nach 9.3.2, Ergebnisse nach 9.3.3, Beschlüsse mit Verantwortlichem und Termin |
|
||||
| 10.2 | `Nonconformity` + `CorrectiveAction` | Herkunft, Sofortkorrektur, Ursachenanalyse, Maßnahme, Wirksamkeitsbewertung |
|
||||
|
||||
Vorhandene Bausteine, auf denen das aufsetzen kann: `Task.recurrence` (RRULE), `Task.remindAt`,
|
||||
`Task.effectiveUntil` (Wirksamkeitsintervall, gekoppelt an `Evidence.validUntil`), `TaskParticipant` (RACI)
|
||||
und `AuditLog`. Die Datenquellen für die Kennzahlen liegen bereits im Tool: Aufgabenfristen und
|
||||
Überfälligkeit, Incident-SLA und Meldefristen (`src/lib/incident-deadlines.ts`), Reifegrade je Control,
|
||||
Maßnahmenstatus.
|
||||
|
||||
Fachlicher Inhalt der Abschnitte steht in R03 der Bibliothek (`ISO-MS-MESSUNG`, `ISO-MS-MGMTREVIEW`,
|
||||
`ISO-MS-CAPA`) — die Modelle sollten die dort beschriebenen Felder tragen.
|
||||
|
||||
**DoD:** Kennzahlenblatt mit Zielwerten pflegbar und über zwei Perioden auswertbar; Management-Review
|
||||
entlang der 9.3.2-Agenda protokollierbar; ein Maßnahmenfall inklusive dokumentierter Wirksamkeitsprüfung
|
||||
abschließbar.
|
||||
|
||||
---
|
||||
|
||||
### AP5 — Dokumentenlenkung *(klein, hohe Auditwirkung)*
|
||||
|
||||
- `PolicyDocument.reviewCycle` und `nextReviewAt` — heute führt nur `ManagedRegister` einen
|
||||
`reviewCycle`; A.5.1 verlangt die Überprüfung „in geplanten Abständen". Behelfsweise über
|
||||
`Task.recurrence` möglich, sauberer am Dokument.
|
||||
- `PolicyAcknowledgement { tenantId, policyDocumentId, version, userId, acknowledgedAt }` — die
|
||||
Lesebestätigung ist in `SPEC.md` §4.6 vorgesehen und fehlt. Sie ist zugleich der einfachste Nachweis
|
||||
für Klausel 7.3 und Control A.6.3.
|
||||
- Änderungshistorie je Dokumentversion — im Entwicklungsstand als offen geführt. Kann aus `AuditLog`
|
||||
(Vorher/Nachher) abgeleitet oder als eigene Tabelle geführt werden.
|
||||
|
||||
**DoD:** Übersicht „Prüfung fällig" im Tool; Auswertung der Lesebestätigungen je Richtlinienversion;
|
||||
Historie eines Dokuments über mindestens zwei Versionen sichtbar.
|
||||
|
||||
---
|
||||
|
||||
## 3. Reihenfolge und Aufwand
|
||||
|
||||
```
|
||||
AP1 Framework-Dimension ██████ 4–6 PT ← blockiert alles
|
||||
├─ AP2 Provisionierung ██ 1–2 PT
|
||||
├─ AP3 SoA-Modul ██████ 5–8 PT
|
||||
├─ AP4 Managementkl. ██████ 5–8 PT
|
||||
└─ AP5 Dok.-Lenkung ███ 2–3 PT
|
||||
```
|
||||
|
||||
AP3, AP4 und AP5 sind nach AP1 parallelisierbar. Die Schätzung entspricht den Lanes 1, 4 und 5 aus
|
||||
`KONZEPT-framework-iso27001.md`; der inhaltliche Teil von Lane 2 (ISO-Mapping und -Texte) ist erledigt und
|
||||
entfällt.
|
||||
|
||||
**Feature-Flag:** ISO bleibt laut Entscheidung D7 hinter einem Plattform-Schalter, bis AP3 abgenommen ist.
|
||||
|
||||
---
|
||||
|
||||
## 4. Abnahme
|
||||
|
||||
| Prüfung | Erwartung |
|
||||
|---|---|
|
||||
| `python3 _verify.py` und `_verify_iso.py` | beide `OK` |
|
||||
| `python3 _render_diff.py <rev>` (TISAX-Sicht) | 0 Abweichungen — Skript liegt im Paket bei. **Vergleichsstand ist der Kopf dieses Branches, nicht `a9649b3`**: der Anforderungsbezug ist dort bewusst aus der Überschrift in eine eigene Zeile gewandert (14 von 17 Richtlinien betroffen, ausschließlich diese Zeile — der Anforderungs- und Umsetzungstext ist unverändert). |
|
||||
| `python3 _render_diff.py <rev> --framework BEIDE` | Parallelbetrieb prüfbar |
|
||||
| `npx tsx scripts/test-framework-dryrun.ts` | alle Prüfungen bestanden — Trockenlauf ohne Schreibzugriff über Paketebene und alle Mandanten der lokalen DB |
|
||||
| Bestandsmandant (TISAX) nach Deploy | Readiness und Exporte identisch zum Snapshot vor dem Umbau |
|
||||
| Import ISO in Mandant mit TISAX | 120 neue Anforderungen, **0 archivierte** ISA-Anforderungen |
|
||||
| Import ISO, Umsetzungstexte | 120 von 120 gefüllt (0 leer) |
|
||||
| Dokumente bei Doppel-Framework | 39 Dokumente, **nicht** doppelt |
|
||||
| `npm run lint`, `npx tsc --noEmit`, `npm run build` | grün |
|
||||
|
||||
Der Importer lässt sich ohne Datenbank gegen beide Mappings prüfen — `parsePackageFiles` ist reine
|
||||
Dateiarbeit und liefert `documents`, `requirements`, `variables`, `baseline`, `evidence` als
|
||||
`ParsedPackage`. Ein Trockenlauf des Mandanten-Imports geht über `reconcilePackage(..., { dryRun: true })`;
|
||||
er erzeugt den Änderungsreport ohne Schreibzugriff und eignet sich als Freigabebedingung.
|
||||
|
||||
---
|
||||
|
||||
## 5. Offene Punkte auf der Paketseite (nicht Entwicklung)
|
||||
|
||||
Diese Punkte gehören dem ISB bzw. der Redaktion, nicht dem Entwicklungsteam — hier nur zur Abgrenzung:
|
||||
|
||||
- Nachweisregister um Zeilen für Kennzahlenblatt, Management-Review-Protokoll und Maßnahmenregister ergänzen.
|
||||
- VA-15 trennen (internes Audit vs. Managementbewertung) und ein Verfahren für Korrekturmaßnahmen
|
||||
ergänzen — **Nummer ab VA-21**, VA-20 ist belegt.
|
||||
- `REVIEW_CYCLE` wird an 33 Bestandsstellen für fünf verschiedene Zyklen verwendet; die getrennten
|
||||
Variablen (`POLICY_REVIEW_CYCLE`, `MGMT_REVIEW_CYCLE`, `RISK_REVIEW_CYCLE`) greifen bisher nur in den
|
||||
neuen ISO-Abschnitten.
|
||||
- ISB-Freigabe der 19 neuen Abschnittstexte und Review des Crosswalks.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Übergabe — Umbau „Zentrale Identität + Mandanten-Mitgliedschaften" (certvia)
|
||||
|
||||
> Kurzübergabe für Team-Lead + PM + neue Entwickler. Produkt: **certvia** (ISMS-Tool). Branch: **`feature/identity-mandanten`**.
|
||||
|
||||
## Worum es geht
|
||||
Eine Person soll sich mit **einem** Login/Passwort/MFA anmelden und danach wählen, in **welchem Mandanten** sie arbeitet — mit je Mandant unterschiedlichen Rollen. Heute ist jeder Nutzer fest an genau einen Mandanten gebunden (eigenes Passwort/MFA je Mandant). Umbau nach **Option C**: globale `Identity` (Anmeldung) + bestehende per-Mandant-`User`-Zeilen als „Mitgliedschaften".
|
||||
|
||||
## Die zwei Dokumente
|
||||
1. [KONZEPT-identity-mandanten.md](KONZEPT-identity-mandanten.md) — **Entscheidungsvorlage** (fachlich, warum/was). Enthält die getroffenen Entscheidungen A–E, Two-Step-Login, Passphrasen, MFA-Matrix, die vier Anlage-Flows, Sicherheitsbetrachtung.
|
||||
2. [FEINDESIGN-identity-mandanten.md](FEINDESIGN-identity-mandanten.md) — **umsetzbarer Bauplan** (technisch): Zieldatenmodell, Session-Shape, Flows, 7 Workstreams, 6 Meilensteine, Risiken, DoD, Onboarding, Aufwand (≈ 47–73 PT / ≈ 5–7 Wochen).
|
||||
|
||||
## Getroffene Entscheidungen (fix)
|
||||
| A | B | C | D | E |
|
||||
|---|---|---|---|---|
|
||||
| MFA **beim Login** (2-stufig: erst Passwort, dann MFA) | Reset-Hoheit → Self-Service + Plattform (Mandanten-Admin verliert MFA-/Passwort-Reset) | **Einladung** als Standard-Anlage | **Migration entfällt** (nur Testdaten → Reseed) | Plattform-Admins **getrennt** (`platform_admins`) |
|
||||
|
||||
## Womit das Team startet (M0 → M1)
|
||||
1. **Onboarding:** Pflichtlektüre `docs/HANDOVER-DEV.md` → `docs/SPEC.md` → `docs/STAND-dev-branch.md` → FEINDESIGN → KONZEPT. Dev-Setup + Gate (§10 im FEINDESIGN).
|
||||
2. **WS0 Fundament als Pairing** (Lead + je 1 Dev): `Identity`-Modell, Schema-Recut, Migration, `TENANT_MODELS`, Reseed. Blocker für fast alles Weitere.
|
||||
3. Danach parallel: WS1 (Auth-Kern), WS3 (Einladung), WS4 (Passwort/MFA an Identity), WS6 (Seed).
|
||||
|
||||
## Die 5 „Goldenen Regeln" (nicht verhandelbar)
|
||||
1. `User.id` = Mitgliedschaft, **stabil lassen**; Auth-Felder leben auf `Identity`.
|
||||
2. `Identity` ist **global**, **nicht** in `TENANT_MODELS`, kein `tenant_id`, keine RLS-Policy.
|
||||
3. Genau **ein** aktiver Mandant pro Session; server-autoritativ; bei Wechsel re-validieren.
|
||||
4. **Keine** „Passwort direkt setzen"-Anlage mehr — nur Einladung.
|
||||
5. MFA/Passwort gehören der Identity — **kein** Mandanten-Admin-Reset.
|
||||
|
||||
## Warum der Umbau überschaubar bleibt
|
||||
Weil `User.id` **und** die Semantik von `session.user.tenantId` (= aktiver Mandant) erhalten bleiben, sind **~356 `dbForTenant()`-Stellen, alle 6 Owner-FKs und das RLS-Modell unberührt**. Der Umbau konzentriert sich auf Login, Session-Aufbau, Mandantenauswahl und Nutzer-Lifecycle.
|
||||
|
||||
## Koordination mit laufender Arbeit
|
||||
- **Richtlinien-Upload im Adminportal** (parallel in Arbeit) ist **funktional nicht betroffen**: er hängt nur an `moduleGuard("policies")`, `session.user.tenantId`, `session.user.id`, `dbForTenant()` und `requirePlatformFullAdmin` — alles stabile Flächen. **Ein** Berührungspunkt: die geteilte Datei `src/app/(platform)/admin/[id]/page.tsx` (Policy-Upload an der Module-Karte, Identity-Umbau an der Benutzerverwaltung) → nur Merge-Koordination, kein funktionaler Konflikt. Empfehlung: WS3/WS-UI und der Policy-Upload-Stream stimmen Reihenfolge auf dieser Datei ab.
|
||||
- **DevOps:** Feature-Branch → `git merge --no-ff` nach `dev` → Gate grün (tsc/lint/build + alle `scripts/test-*.ts`) → Push auf **beide** Remotes (`origin` git.certvia.de + `local-gitea`) → `docs/STAND-dev-branch.md` pflegen.
|
||||
|
||||
## Offen für PM-Entscheidung (kein Blocker fürs Feindesign)
|
||||
- Team-Besetzung/Startdatum, Sprint-Zuschnitt entlang M1–M6.
|
||||
- Phase-2-Punkte (per-Mandant „immer Step-up", E-Mail-Änderung als Identity-Op, evtl. PlatformAdmin-Konsolidierung) — bewusst zurückgestellt.
|
||||
@@ -0,0 +1,107 @@
|
||||
# Umsetzungspaket — Vollständige Branding-Umstellung auf **Certvia**
|
||||
|
||||
> Claude-Code-Prompt für **einen** Entwickler. Basis-Branch **`dev`**, Feature-Branch **`dev/branding-certvia`** (PR-Ziel `dev`).
|
||||
> Quelle der Wahrheit: **Certvia Brand-Board** (`Certvia-Brand-Board-final.html`) + Logo-SVGs (`certvia-mark-positiv/negativ/grau/anthrazit.svg`, `certvia-favicon.svg`, `certvia-lockup-positiv.svg`) aus `Certvia-Design-Uebergabe.zip`.
|
||||
|
||||
## 0. Ziel & Leitplanken
|
||||
Die App vollständig auf den **Certvia-Styleguide** umstellen — Logo, Wortmarke, App-Name, Favicon/Icons, Typografie, Marken-/UI-Farben, Dokument-/Export-Design und alle Texte.
|
||||
**Wichtige Leitplanken:**
|
||||
- **GEFIM bleibt Dachmarke.** „**Ein Produkt von GEFIM**" (inkl. GEFIM-Logo) bleibt im Footer/Impressum/Export-Fußzeile erhalten. Nur die **Produktmarke** wird Certvia.
|
||||
- **UI-Farben bleiben wie initial festgelegt** (Dark-Theme-Primär `#7d6fd6` etc.) — sie **sind** die Certvia-UI-Palette. Nicht „korrigieren". Marken-Violett `#5d52a3` gilt für Logo/Print/Verläufe, UI-Interaktiv bleibt `#7d6fd6`.
|
||||
- **Keine Funktionsänderung** — reines Branding/Design. Kein Umbau von Logik/Datenmodell.
|
||||
|
||||
---
|
||||
|
||||
## 1. Design-Tokens (verbindliche Referenz)
|
||||
|
||||
**Markenfarben (Logo, Print, Verläufe, Akzent):**
|
||||
| Rolle | Hex |
|
||||
|---|---|
|
||||
| Violett (Marke) | `#5d52a3` |
|
||||
| Magenta (Akzent: „via", Haken, Highlights) | `#812d80` |
|
||||
| Hellblau | `#8dc4e0` |
|
||||
| Anthrazit (Text/Headlines) | `#3b3b3a` |
|
||||
|
||||
**UI Dark-Theme (unverändert, = Certvia-Produktpalette):**
|
||||
`--violet:#7d6fd6` · `--violet-deep:#5d52a3` · `--blue:#8dc4e0` · `--magenta:#b45bb0` · `--bg0:#0e1220` · `--bg1:#141a2e` · `--panel:rgba(30,38,64,.72)` · `--panel-b:rgba(120,135,180,.18)` · `--elev:#1a2138` · `--txt:#e8ecf7` · `--muted:#8b93ad` · `--ok:#39c07f` · `--warn:#f0ad4e` · `--risk:#ff6b6b` · Primär-Verlauf `linear-gradient(135deg,#5d52a3,#7d6fd6)` · Fokus-Ring `rgba(125,111,214,.35)`.
|
||||
|
||||
**Typografie:** Headlines/Wortmarke **Poppins**, Fließtext **Open Sans** (bereits im Einsatz — bestätigen, **selbst hosten**, kein ungefragtes Google-Fonts-CDN).
|
||||
|
||||
**Logo/Marke:** C-Monogramm (offenes „C" Violett `#5d52a3` + Haken Magenta `#812d80`, Haken schließt bündig an die C-Öffnung). Wortmarke „Cert" (Poppins Light, Anthrazit) + „**via**" (Poppins Bold, Magenta). Auf dunklem Grund: C `#7d6fd6`, Haken `#d17bcf`, Text weiß.
|
||||
|
||||
---
|
||||
|
||||
## 2. Story B0 — Bestandsaufnahme / Branding-Inventar (zuerst!) (S)
|
||||
**Als** Entwickler **möchte ich** alle Branding-Berührungspunkte finden, **damit** nichts übersehen wird.
|
||||
- Repo-weit suchen und als kurze Inventarliste (Datei → Fundstelle → Maßnahme) dokumentieren:
|
||||
```bash
|
||||
rg -i "gefim" -l # Produktname vs. Dachmarke unterscheiden
|
||||
rg -i "shield|logo|brand|favicon|wordmark|app[_-]?name|siteName|title" src public
|
||||
rg -i "#5d52a3|#7d6fd6|#812d80|#8dc4e0|#b45bb0|#0e1220" src # hartkodierte Farben außerhalb der Tokens
|
||||
rg -i "poppins|open sans|fonts.googleapis" src public
|
||||
```
|
||||
- **AK:** Inventarliste liegt vor; jede Fundstelle ist einer der Stories S1–S9 zugeordnet; klar getrennt „Produktmarke → Certvia" vs. „Dachmarke → GEFIM bleibt".
|
||||
|
||||
---
|
||||
|
||||
## 3. Stories
|
||||
|
||||
### S1 — Design-Tokens zentralisieren & Certvia-Palette verankern (M)
|
||||
- Eine **zentrale Token-Quelle** (CSS-Variablen/`theme`/Tailwind-Config) als Single Source of Truth; hartkodierte Farben aus S0 durch Tokens ersetzen.
|
||||
- Marken- vs. UI-Tokens klar benennen (`--brand-violet` `#5d52a3` vs. `--ui-primary` `#7d6fd6`), damit Logo/Print und UI nicht vermischt werden.
|
||||
- **AK:** keine hartkodierten Markenfarben mehr in Komponenten; Umschalten zentral möglich; UI optisch unverändert (nur konsolidiert).
|
||||
|
||||
### S2 — Logo, Wortmarke & Icons (M)
|
||||
- **App-Header/Sidebar**, **Login** (`/login`) und **Plattform-Login** (`/platform/login`): GEFIM-Schild → **Certvia-Logo** (Lockup C-Monogramm + „Certvia"). Dark-Variante nutzen.
|
||||
- **Favicon** + **PWA/Manifest-Icons** (`public/`, `manifest.webmanifest`, `apple-touch-icon`) auf `certvia-favicon.svg` (C auf Violett-Tile) und generierte PNGs (32/180/192/512).
|
||||
- `meta-theme-color` = `#5d52a3` (schon so auf der Website).
|
||||
- SVG-Assets aus dem Design-Paket in `public/assets/logo/` bzw. `src/components/brand/` einbinden; **Logo als React-Komponente** `<CertviaLogo variant="lockup|mark" theme="light|dark" />`.
|
||||
- **AK:** in allen App-Bereichen erscheint das Certvia-Logo; Favicon/Tab-Icon = Certvia; keine GEFIM-Schild-Reste in Produkt-UI.
|
||||
|
||||
### S3 — App-Name, Titel, Meta & i18n-Texte (S–M)
|
||||
- App-Name/`<title>`/OG-/Twitter-Meta, PWA-Name, Sidebar-Kopf, „Über"/Version-Info → **Certvia**.
|
||||
- i18n (`de`/`en`): alle Produktname-Strings auf „Certvia"; Tagline „Informationssicherheit. Endlich einfach." wo passend.
|
||||
- **AK:** Browser-Tab, Meta, Manifest und sichtbare Produktnamen zeigen „Certvia"; „ein Produkt von GEFIM" bleibt erhalten.
|
||||
|
||||
### S4 — Typografie bestätigen & selbst hosten (S)
|
||||
- Poppins (300/400/500/600/700) + Open Sans (400/600/700) **self-hosted** (woff2) statt CDN; Fallback-Stack; `font-display: swap`.
|
||||
- **AK:** keine externen Font-Requests; Wortmarke „Cert**via**" korrekt (Light + Bold), Headlines Poppins, Fließtext Open Sans.
|
||||
|
||||
### S5 — Dokument-/Export-Corporate-Design (M–L)
|
||||
- **DOCX/PDF/Print-Export** (Richtlinien, VDA-ISA-Katalog, Reports) auf **Certvia-Corporate-Design**: Deckblatt/Kopf mit Certvia-Logo + Farben, Fußzeile „Certvia — ein Produkt von GEFIM" + GEFIM-Logo, Poppins/Open Sans.
|
||||
- Betrifft den (offenen) DOCX/PDF-Export — Branding-Layer so bauen, dass er beim Export-Feature andockt.
|
||||
- **AK:** exportierte Dokumente tragen Certvia-Branding; GEFIM als Dachmarke in der Fußzeile.
|
||||
|
||||
### S6 — E-Mail-/Benachrichtigungs-Templates (S–M, falls vorhanden)
|
||||
- Sobald SMTP/E-Mail (Paket 4) existiert bzw. für Einladungs-/Reset-Mails: Header/Footer/Farben/Logo auf Certvia; Absender-/Signatur-Text „Certvia — ein Produkt von GEFIM".
|
||||
- Falls E-Mail noch nicht aktiv: nur die **Template-Basis** brandfähig vorbereiten.
|
||||
- **AK:** vorhandene Mail-Templates gebranded oder brandfähige Basis vorbereitet.
|
||||
|
||||
### S7 — Auth-, Fehler- & Systemseiten (S)
|
||||
- Login, Change-Password, deaktiviertes Konto, 404/500, Wartungs-/Status-Banner, Loading-/Empty-States: Certvia-Logo + Palette.
|
||||
- **AK:** keine ungebrandeten/gemischten Screens mehr.
|
||||
|
||||
### S8 — Mandanten-Branding-Default = Certvia (S–M)
|
||||
- Der Whitelabel-/Branding-Fallback je Mandant (Admin Phase 2 „Logo-Upload") ist **Certvia** als Default; Custom-Logo überschreibt nur, wenn gesetzt.
|
||||
- **AK:** ohne Custom-Logo zeigt jeder Mandant Certvia; „ein Produkt von GEFIM" bleibt unabhängig davon.
|
||||
|
||||
### S9 — Restliche GEFIM-Referenzen bereinigen (S)
|
||||
- Alle in S0 gefundenen **Produkt**-Referenzen „GEFIM" → „Certvia" (Kommentare, Alt-Texte, aria-labels, Klassennamen unkritisch). **Dachmarken-Hinweise bewusst belassen.**
|
||||
- **AK:** `rg -i "gefim"` liefert nur noch Dachmarken-Kontext (Footer/Impressum/Export-Fußzeile/Assets `gefim/`).
|
||||
|
||||
---
|
||||
|
||||
## 4. QA / Definition of Done
|
||||
- **Visuelles Review** der Kernscreens (Dashboard, Richtlinien, Assets, Risiken, Lieferanten, Aufgaben, Admin, beide Logins, Export, Fehlerseiten) hell **und** dunkel — Screenshots im PR.
|
||||
- **Kontrast prüfen:** Magenta `#812d80` auf Weiß und `#d17bcf` auf Dunkel (WCAG AA für Text/aktive Elemente).
|
||||
- `rg -i "gefim"` = nur Dachmarken-Kontext; keine externen Font-/Logo-Requests; keine hartkodierten Markenfarben.
|
||||
- `npx tsc --noEmit` → `npm run lint` → `npm run build` grün; Demo-Umgebung lauffähig.
|
||||
- **Reines Branding-PR** — keine funktionalen Diffs.
|
||||
|
||||
## 5. Reihenfolge
|
||||
S0 (Inventar) → S1 (Tokens) → S2 (Logo/Icons) → S3 (Name/Meta/i18n) → S4 (Fonts) → S7 (Auth/Fehler) → S9 (Cleanup) → S5 (Export) → S8 (Mandanten-Default) → S6 (Mail, falls vorhanden).
|
||||
|
||||
## 6. Assets (mitliefern an den Entwickler)
|
||||
Aus `Certvia-Design-Uebergabe.zip`: `logo/certvia-mark-positiv.svg`, `-negativ.svg`, `-grau.svg`, `-anthrazit.svg`, `certvia-favicon.svg`, `certvia-lockup-positiv.svg`, `logo/README-Logo.md`, `Brand-Board.html` (Farb-/Typo-Referenz) sowie `gefim-dachmarke/` (GEFIM-Logo für den „ein Produkt von GEFIM"-Hinweis).
|
||||
|
||||
> Hinweis: Falls PNG-Rastergrößen (Favicon/Apple-Touch/PWA 32/180/192/512) benötigt werden, kann ich sie aus dem SVG erzeugen und beilegen — sag kurz Bescheid.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Certvia — Logo-Dateien
|
||||
|
||||
Logo = **C-Monogramm + Haken** (Entwurf C) in GEFIM-Farben. Alle Marken (außer Lockup) sind quadratisch (viewBox 64×64), vektoriell und frei skalierbar.
|
||||
|
||||
## Dateien
|
||||
| Datei | Verwendung |
|
||||
|---|---|
|
||||
| `certvia-mark-positiv.svg` | Standard auf hellem Grund (C Violett, Haken Magenta) |
|
||||
| `certvia-mark-negativ.svg` | Auf farbigem/dunklem Grund (weiß) |
|
||||
| `certvia-mark-grau.svg` | Graustufen |
|
||||
| `certvia-mark-anthrazit.svg` | Einfarbig Anthrazit (Dokumente/Druck s/w) |
|
||||
| `certvia-favicon.svg` | App-Icon/Favicon (Monogramm auf violettem Tile) |
|
||||
| `certvia-lockup-positiv.svg` | Wortmarke horizontal (Zeichen + „Certvia") |
|
||||
|
||||
## Farben
|
||||
- **Violett (C):** `#5d52a3`
|
||||
- **Magenta (Haken & „via"):** `#812d80`
|
||||
- **Anthrazit (Wortmarke „Cert"):** `#3b3b3a`
|
||||
- Auf dunklem Grund/UI: C `#7d6fd6`, Haken `#d17bcf`.
|
||||
|
||||
## Konstruktion / Regeln
|
||||
- „C" ist **offen nach rechts**; der **Haken** liegt in der Öffnung („cert").
|
||||
- **Kein Verlauf** im Zeichen. „C" nicht schließen, nicht verzerren, Seitenverhältnis wahren.
|
||||
- **Schutzraum:** mind. Höhe des Haken-Elements rundum frei.
|
||||
- Wortmarke „Cert" (Poppins Light/300, Anthrazit) + „**via**" (Poppins Bold/700, Magenta).
|
||||
- Hinweis: SVG-Lockup nutzt Poppins per `font-family` — beim finalen Export ggf. **Text in Pfade wandeln**, damit die Schrift überall korrekt erscheint.
|
||||
|
||||
## Schrift
|
||||
- **Poppins** (Wortmarke/Headlines), **Open Sans** (Fließtext).
|
||||
@@ -0,0 +1,797 @@
|
||||
# Craftvia Brandbook
|
||||
|
||||
**Version 1.0 · September 2026**
|
||||
**Marken- und Gestaltungsgrundlage für Produkt, Website, Vertrieb und Kommunikation**
|
||||
|
||||
---
|
||||
|
||||
## 1. Brandbook auf einen Blick
|
||||
|
||||
Craftvia ist die digitale Einsatzplattform für Handwerks- und Servicebetriebe. Sie verbindet Büro und Baustelle, führt Aufträge vom Eingang bis zum abrechnungsfähigen Nachweis und sorgt dafür, dass Informationen dort ankommen, wo sie gebraucht werden.
|
||||
|
||||
**Leitclaim:** **Handwerk. Digital auf Kurs.**
|
||||
**Erklärender Claim:** **Vom Auftrag bis zur Abrechnung.**
|
||||
**Markenversprechen:** Weniger Papier, weniger Rückfragen, schneller abrechnen.
|
||||
**Kategorie:** Digitale Einsatz- und Auftragsplattform für Handwerk und technischen Service
|
||||
**KI-Assistent im Produkt:** **Lotse**
|
||||
|
||||
Craftvia gehört zur gemeinsamen Produktfamilie:
|
||||
|
||||
- **Certvia** – ISMS und Informationssicherheit verwalten
|
||||
- **Visitvia** – Besucher und Zutritte verwalten
|
||||
- **Craftvia** – Aufträge und Einsätze verwalten
|
||||
|
||||
---
|
||||
|
||||
## 2. Ausgangslage
|
||||
|
||||
In vielen Handwerksbetrieben endet die Digitalisierung dort, wo der Einsatz beginnt. Auftragsinformationen liegen im Büro, Stundenzettel reisen wochenlang im Fahrzeug mit, Fotos bleiben auf privaten Geräten und Materialangaben müssen nachträglich rekonstruiert werden. Erst wenn alle Nachweise vollständig sind, kann die Rechnung entstehen.
|
||||
|
||||
Das führt zu wiederkehrenden Problemen:
|
||||
|
||||
- Informationen werden doppelt erfasst oder gehen verloren.
|
||||
- Monteure arbeiten mit unvollständigen oder veralteten Unterlagen.
|
||||
- Das Backoffice muss fehlenden Angaben hinterhertelefonieren.
|
||||
- Arbeitszeiten, Material und Fotos treffen verspätet ein.
|
||||
- Tages- und Abschlussberichte kosten unnötig Zeit.
|
||||
- Abrechnungen verzögern sich und belasten den Cashflow.
|
||||
- Wissen über Kunden, Objekte und frühere Einsätze bleibt verteilt.
|
||||
- Notdienste außerhalb der Bürozeiten werden uneinheitlich dokumentiert.
|
||||
|
||||
Craftvia schließt diese Lücke mit einem durchgängigen, praxistauglichen Prozess.
|
||||
|
||||
---
|
||||
|
||||
## 3. Markenstrategie
|
||||
|
||||
### 3.1 Vision
|
||||
|
||||
Handwerksbetriebe arbeiten ohne Medienbrüche: Jeder Auftrag ist klar, jeder Einsatz nachvollziehbar und jede erbrachte Leistung unmittelbar abrechenbar.
|
||||
|
||||
### 3.2 Mission
|
||||
|
||||
Craftvia verbindet Büro, Montageteams und Einsatzort in einem einfachen digitalen Arbeitsablauf. Die Plattform stellt relevante Informationen bereit, unterstützt die Dokumentation und überführt abgeschlossene Arbeit ohne Umwege in einen vollständigen Leistungsnachweis.
|
||||
|
||||
### 3.3 Purpose
|
||||
|
||||
Wir geben Handwerksbetrieben mehr Zeit für gute Arbeit und weniger Aufwand mit Papier, Rückfragen und Nachbearbeitung.
|
||||
|
||||
### 3.4 Markenversprechen
|
||||
|
||||
**Mit Craftvia wird aus einem Auftrag zuverlässig ein dokumentierter und abrechnungsfähiger Einsatz.**
|
||||
|
||||
### 3.5 USP
|
||||
|
||||
Craftvia bildet nicht nur einzelne Aufgaben ab, sondern verbindet den gesamten operativen Weg:
|
||||
|
||||
> Auftrag übernehmen → Team vorbereiten → Einsatz dokumentieren → Leistung bestätigen → Backoffice informieren → schneller abrechnen
|
||||
|
||||
Der Unterschied liegt in der Verbindung aus:
|
||||
|
||||
- einem für Handwerksbetriebe verständlichen Prozess,
|
||||
- mobiler, auch auf der Baustelle praktikabler Bedienung,
|
||||
- vollständiger Objekt- und Einsatzhistorie,
|
||||
- strukturierten Nachweisen für die Abrechnung,
|
||||
- eigenständiger Notdienstdokumentation und
|
||||
- dem KI-Assistenten **Lotse**, der Eingaben vereinfacht und Berichte vorbereitet.
|
||||
|
||||
### 3.6 Markenwerte
|
||||
|
||||
| Wert | Bedeutung für Craftvia |
|
||||
|---|---|
|
||||
| **Praktisch** | Funktionen lösen reale Aufgaben im Betriebsalltag. |
|
||||
| **Verlässlich** | Informationen, Nachweise und Status sind nachvollziehbar verfügbar. |
|
||||
| **Einfach** | Die Bedienung bleibt auch unter Zeitdruck klar. |
|
||||
| **Verbindend** | Büro, Team und Einsatzort arbeiten mit demselben Informationsstand. |
|
||||
| **Fortschrittlich** | Automatisierung und KI unterstützen konkret, ohne den Menschen zu verdrängen. |
|
||||
| **Bodenständig** | Die Marke spricht verständlich, direkt und ohne Software-Pathos. |
|
||||
|
||||
### 3.7 Markenpersönlichkeit
|
||||
|
||||
Craftvia wirkt wie ein erfahrener, gut organisierter Kollege: ruhig, lösungsorientiert, aufmerksam und verbindlich. Die Marke kennt den Alltag auf der Baustelle ebenso wie die Anforderungen im Büro. Sie will nicht beeindrucken, sondern Arbeit spürbar leichter machen.
|
||||
|
||||
**Craftvia ist:** kompetent, klar, robust, partnerschaftlich, modern.
|
||||
**Craftvia ist nicht:** verspielt, technokratisch, belehrend, überladen oder künstlich futuristisch.
|
||||
|
||||
---
|
||||
|
||||
## 4. Name und Markenidee
|
||||
|
||||
### 4.1 Bedeutung des Namens
|
||||
|
||||
**Craft** steht für Handwerk, Können und praktische Arbeit. **Via** bedeutet Weg oder „über/durch“ und verbindet Craftvia sprachlich mit Certvia und Visitvia.
|
||||
|
||||
Die Markenidee lautet:
|
||||
|
||||
> **Craftvia schafft den digitalen Weg vom Auftrag bis zur Abrechnung.**
|
||||
|
||||
Der Name bleibt international anschlussfähig, während Sprache, Bildwelt und Kommunikation bewusst nah am deutschsprachigen Handwerk bleiben.
|
||||
|
||||
### 4.2 Schreibweise
|
||||
|
||||
- Immer **Craftvia**, mit großem C und ansonsten kleingeschrieben.
|
||||
- Nicht: CraftVia, CRAFTVIA, Craft-via oder Craft Via.
|
||||
- In Fließtext ohne Anführungszeichen verwenden.
|
||||
- Generische Ergänzungen beschreibend anfügen, etwa „Craftvia Einsatzplanung“.
|
||||
|
||||
### 4.3 Die Rolle des „Lotsen“
|
||||
|
||||
„Mein Lotse“ ist nicht länger die Produktmarke. **Lotse** kann als Name des KI-Assistenten innerhalb von Craftvia weiterleben.
|
||||
|
||||
Der Lotse:
|
||||
|
||||
- nimmt Sprach- und Texteingaben entgegen,
|
||||
- strukturiert Notizen, Zeiten und Materialangaben,
|
||||
- weist auf fehlende Dokumentation hin,
|
||||
- bereitet Tages-, Montage- und Abschlussberichte vor,
|
||||
- hilft beim Auffinden früherer Einsätze und Unterlagen,
|
||||
- unterstützt, entscheidet aber nicht ungefragt anstelle des Nutzers.
|
||||
|
||||
Bevorzugte Formulierungen:
|
||||
|
||||
- „Frag den Lotsen.“
|
||||
- „Der Lotse unterstützt dich bei der Dokumentation.“
|
||||
- „Mit dem Lotsen zum vollständigen Einsatzbericht.“
|
||||
|
||||
Nicht verwenden: „Mein Lotse“ als parallelen Produktnamen oder eine eigenständige zweite Marke neben Craftvia.
|
||||
|
||||
---
|
||||
|
||||
## 5. Positionierung
|
||||
|
||||
### 5.1 Positionierungssatz
|
||||
|
||||
Für Handwerks- und technische Servicebetriebe, die Aufträge zuverlässig zwischen Büro und Einsatzteam steuern wollen, ist Craftvia die digitale Einsatzplattform, die Informationen, Dokumentation und Abrechnungsvorbereitung in einem durchgängigen Prozess verbindet. Anders als isolierte Zeiterfassungs- oder Baustellendokumentationslösungen begleitet Craftvia den Auftrag von der Übernahme bis zum vollständigen Leistungsnachweis – praxistauglich, mobil und KI-gestützt.
|
||||
|
||||
### 5.2 Zielgruppen
|
||||
|
||||
**Primär**
|
||||
|
||||
- Inhaber und Geschäftsführer kleiner und mittlerer Handwerksbetriebe
|
||||
- Betriebs- und Einsatzleiter
|
||||
- Backoffice, Disposition und vorbereitende Abrechnung
|
||||
- Monteure, Techniker und Montageteams im Außeneinsatz
|
||||
|
||||
**Sekundär**
|
||||
|
||||
- Service- und Wartungsunternehmen
|
||||
- Technischer Gebäudeservice und Facility Services
|
||||
- Montage- und Instandhaltungsbetriebe
|
||||
- Unternehmen mit wiederkehrenden Kunden- und Objekteinsätzen
|
||||
|
||||
### 5.3 Nutzen nach Rolle
|
||||
|
||||
| Rolle | Zentrales Bedürfnis | Nutzenversprechen |
|
||||
|---|---|---|
|
||||
| Geschäftsführung | Überblick und Liquidität | Schnellere Abrechnung, transparente Auftragsstände, weniger Verwaltungsaufwand |
|
||||
| Backoffice | Vollständige Informationen | Strukturierte Nachweise ohne Zettelchaos und Nachtelefonieren |
|
||||
| Einsatzleitung | Planbare Durchführung | Klare Zuweisungen, aktuelle Unterlagen und sichtbarer Fortschritt |
|
||||
| Monteur/Techniker | Einfach arbeiten | Alle Informationen mobil, schnelle Erfassung und weniger Schreibarbeit |
|
||||
| Kunde/Auftraggeber | Nachvollziehbare Leistung | Saubere Berichte, Fotos und Bestätigungen |
|
||||
|
||||
### 5.4 Markennutzen
|
||||
|
||||
**Funktional:** Aufträge, Teams, Zeiten, Material, Fotos, Dokumente und Berichte in einem Ablauf.
|
||||
**Wirtschaftlich:** Leistungen früher und vollständiger abrechnen; Cashflow verbessern.
|
||||
**Emotional:** Sicherheit, dass nichts verloren geht und der Betrieb unter Kontrolle bleibt.
|
||||
**Sozial:** Professionelles Auftreten gegenüber Mitarbeitenden und Kunden.
|
||||
|
||||
---
|
||||
|
||||
## 6. StoryBrand und Heldenreise
|
||||
|
||||
### 6.1 Der Held
|
||||
|
||||
Der Held ist nicht Craftvia, sondern der Handwerksbetrieb – konkret der Inhaber, die Einsatzleitung, das Backoffice und das Team vor Ort.
|
||||
|
||||
### 6.2 Das Problem
|
||||
|
||||
**Äußerlich:** Papierzettel, verstreute Informationen, fehlende Nachweise, langsame Berichte.
|
||||
**Innerlich:** Frust über Rückfragen, Unsicherheit und das Gefühl, dem Tagesgeschäft hinterherzulaufen.
|
||||
**Grundsätzlich:** Gute Arbeit sollte nicht an schlechter Informationsweitergabe und unnötiger Verwaltung verlieren.
|
||||
|
||||
### 6.3 Der Begleiter
|
||||
|
||||
Craftvia versteht beide Seiten des Betriebs: die Realität auf der Baustelle und die Anforderungen im Büro. Die Plattform gibt einen klaren Prozess vor, ohne unnötige Komplexität zu erzeugen.
|
||||
|
||||
### 6.4 Der Plan
|
||||
|
||||
1. Auftrag importieren oder anlegen.
|
||||
2. Team zuweisen und alle Unterlagen bereitstellen.
|
||||
3. Einsatz mobil dokumentieren und bestätigen.
|
||||
4. Vollständigen Nachweis ans Backoffice übergeben.
|
||||
5. Rechnung schneller erstellen.
|
||||
|
||||
### 6.5 Call-to-Action
|
||||
|
||||
**Primär:** „Craftvia kennenlernen“ oder „Demo vereinbaren“
|
||||
**Sekundär:** „Ablauf ansehen“
|
||||
|
||||
### 6.6 Erfolg
|
||||
|
||||
- Aktuelle Informationen für alle Beteiligten
|
||||
- Weniger Papier und doppelte Erfassung
|
||||
- Vollständige Einsatzberichte
|
||||
- Kürzere Zeit zwischen Leistung und Rechnung
|
||||
- Besserer Cashflow
|
||||
- Nachvollziehbare Kunden- und Objekthistorie
|
||||
|
||||
### 6.7 Vermiedenes Scheitern
|
||||
|
||||
- Stundenzettel bleiben nicht wochenlang im Fahrzeug.
|
||||
- Das Backoffice wartet nicht auf fehlende Angaben.
|
||||
- Abrechenbare Leistungen werden nicht vergessen.
|
||||
- Bei Folgeeinsätzen muss Wissen nicht neu zusammengesucht werden.
|
||||
|
||||
---
|
||||
|
||||
## 7. Botschaftensystem
|
||||
|
||||
### 7.1 Kernbotschaft
|
||||
|
||||
**Craftvia bringt Auftrag, Einsatz und Abrechnung auf einen gemeinsamen digitalen Weg.**
|
||||
|
||||
### 7.2 Botschaftssäulen
|
||||
|
||||
#### Alles für den Einsatz an einem Ort
|
||||
|
||||
Aufträge, Ansprechpartner, Dokumente, technische Zeichnungen, Materialvorgaben und frühere Einsätze stehen dem Team zentral zur Verfügung.
|
||||
|
||||
#### Dokumentieren, während die Arbeit passiert
|
||||
|
||||
Zeiten, Material, Fotos, Notizen, Spracheingaben und Unterschriften werden direkt vor Ort erfasst – vollständig und nachvollziehbar.
|
||||
|
||||
#### Schneller bereit zur Abrechnung
|
||||
|
||||
Nach Abschluss erhält das Backoffice einen strukturierten Leistungsnachweis. Aus Wochen werden Tage, im Idealfall Stunden.
|
||||
|
||||
#### Wissen bleibt im Betrieb
|
||||
|
||||
Jeder Einsatz erweitert die Kunden- und Objekthistorie. Beim nächsten Auftrag sind relevante Informationen sofort verfügbar.
|
||||
|
||||
#### KI, die konkret unterstützt
|
||||
|
||||
Der Lotse strukturiert Eingaben, erkennt Lücken und bereitet Berichte vor. Die Kontrolle bleibt beim Menschen.
|
||||
|
||||
### 7.3 Proof Points
|
||||
|
||||
Kommunikation soll Nutzen möglichst mit überprüfbaren Funktionen belegen:
|
||||
|
||||
- Auftragsimport aus vorhandenen Dokumenten
|
||||
- Teamzuweisung und mobile Bereitstellung
|
||||
- Zeit-, Material-, Foto- und Spracherfassung
|
||||
- Pflichtnachweise und Vollständigkeitsprüfung
|
||||
- Kundenunterschrift und Abschlussbericht
|
||||
- automatische Information an das Backoffice
|
||||
- Notdienstauftrag durch das Einsatzteam
|
||||
- Kunden-, Objekt- und Einsatzhistorie
|
||||
- PWA für Desktop, Tablet und Smartphone
|
||||
- mandantenfähige Plattform für mehrere Betriebe
|
||||
|
||||
Keine unbewiesenen Prozent- oder Zeitersparnisse kommunizieren. Quantitative Aussagen erst nach belastbaren Kundendaten verwenden.
|
||||
|
||||
---
|
||||
|
||||
## 8. Claims und Taglines
|
||||
|
||||
### 8.1 Claim-Hierarchie
|
||||
|
||||
**Leitclaim**
|
||||
> **Handwerk. Digital auf Kurs.**
|
||||
|
||||
**Funktionsclaim**
|
||||
> **Vom Auftrag bis zur Abrechnung.**
|
||||
|
||||
**Nutzenclaim**
|
||||
> **Sauber dokumentiert. Schneller abgerechnet.**
|
||||
|
||||
**Kategorie-Descriptor**
|
||||
> **Die Einsatzplattform fürs Handwerk.**
|
||||
|
||||
### 8.2 Weitere freigegebene Aussagen
|
||||
|
||||
- Weniger Papier. Mehr Überblick.
|
||||
- Damit gute Arbeit schneller zur Rechnung wird.
|
||||
- Büro und Baustelle. Endlich im selben Ablauf.
|
||||
- Jeder Einsatz vollständig dokumentiert.
|
||||
- Alle Informationen. Direkt am Einsatzort.
|
||||
- Arbeit erledigt. Nachweis komplett.
|
||||
- Vom ersten Auftrag bis zum nächsten Einsatz.
|
||||
- Ihr digitaler Weg durch Auftrag, Einsatz und Nachweis.
|
||||
|
||||
### 8.3 Claim-Verwendung
|
||||
|
||||
- Der Leitclaim trägt Image- und Markenkommunikation.
|
||||
- Der Funktionsclaim erklärt Craftvia bei Erstkontakt.
|
||||
- Der Nutzenclaim eignet sich für Kampagnen und konkrete Landingpages.
|
||||
- Den „Kurs“-Gedanken dosiert einsetzen; Craftvia ist keine maritime Themenwelt.
|
||||
|
||||
---
|
||||
|
||||
## 9. Tonalität und Sprache
|
||||
|
||||
### 9.1 Sprachprinzipien
|
||||
|
||||
1. **Direkt:** Kurze Sätze, aktive Verben, klarer Nutzen.
|
||||
2. **Bodenständig:** Alltagssprache statt Beratungsvokabular.
|
||||
3. **Respektvoll:** Nutzer sind Fachleute ihres Handwerks.
|
||||
4. **Konkret:** Reale Abläufe und Ergebnisse statt leerer Versprechen.
|
||||
5. **Zuversichtlich:** Probleme benennen, aber lösungsorientiert bleiben.
|
||||
|
||||
### 9.2 Anrede
|
||||
|
||||
Für Website und Vertrieb wird zunächst die respektvolle **Sie-Ansprache** empfohlen. Im Produkt kann eine knappe, handlungsnahe Ansprache ohne Pronomen dominieren („Foto hinzufügen“, „Einsatz abschließen“). Der Lotse kann je nach Unternehmenseinstellung „Sie“ oder „du“ verwenden; innerhalb eines Mandanten muss dies konsistent sein.
|
||||
|
||||
### 9.3 Bevorzugte Begriffe
|
||||
|
||||
| Verwenden | Vermeiden |
|
||||
|---|---|
|
||||
| Auftrag, Einsatz, Team, Nachweis | Ticket, Workforce Unit, Case |
|
||||
| Büro, Backoffice | Administration Layer |
|
||||
| vor Ort | Field Environment |
|
||||
| Bericht vorbereiten | Content generieren |
|
||||
| unterstützt durch KI | revolutioniert durch AI |
|
||||
| vollständig, nachvollziehbar | disruptiv, bahnbrechend |
|
||||
|
||||
### 9.4 Beispiel
|
||||
|
||||
**Gut:** „Der Einsatz ist abgeschlossen. Zeiten, Material, Fotos und Unterschrift liegen dem Büro sofort vor.“
|
||||
**Nicht gut:** „Unsere innovative End-to-End-AI-Plattform optimiert Ihre Field-Service-Prozesse.“
|
||||
|
||||
---
|
||||
|
||||
## 10. Markenarchitektur
|
||||
|
||||
### 10.1 Empfohlenes Modell
|
||||
|
||||
Die Produkte treten als **verbundene Einzelmarken** mit einheitlicher Namenslogik auf. Eine gemeinsame Absendermarke kann ergänzt werden, sobald sie definiert ist.
|
||||
|
||||
| Produkt | Kernbereich | Descriptor |
|
||||
|---|---|---|
|
||||
| **Certvia** | Informationssicherheit | ISMS & Compliance |
|
||||
| **Visitvia** | Besuchermanagement | Visitor Management |
|
||||
| **Craftvia** | Handwerk und technischer Service | Work Order & Field Service Management |
|
||||
|
||||
### 10.2 Gemeinsame Familienmerkmale
|
||||
|
||||
- Namen folgen dem Muster **[Domäne] + via**.
|
||||
- „via“ steht für einen klaren digitalen Weg durch einen Geschäftsprozess.
|
||||
- Wortmarken teilen typografische Grundlogik, Proportionen und Qualitätsniveau.
|
||||
- Jedes Produkt erhält eine eigene Akzentfarbe und ein eigenes Symbol.
|
||||
- Struktur, Navigation und zentrale UI-Muster bleiben produktübergreifend verwandt.
|
||||
- Die Familie verspricht verständliche, sichere und praxistaugliche Geschäftsanwendungen.
|
||||
|
||||
### 10.3 Produkt- und Funktionsnamen in Craftvia
|
||||
|
||||
Empfohlene beschreibende Module:
|
||||
|
||||
- Craftvia Aufträge
|
||||
- Craftvia Einsätze
|
||||
- Craftvia Teams
|
||||
- Craftvia Berichte
|
||||
- Craftvia Objekte
|
||||
- Craftvia Notdienst
|
||||
- Craftvia Dokumente
|
||||
- Craftvia Lotse
|
||||
|
||||
Keine neue Untermarke für jede Funktion schaffen. **Lotse** ist die einzige bewusst personifizierte Produktfunktion.
|
||||
|
||||
### 10.4 Cross-Product-Kommunikation
|
||||
|
||||
Beispiel:
|
||||
|
||||
> Drei klare Wege für zentrale Geschäftsprozesse: Certvia für Informationssicherheit, Visitvia für Besuchermanagement und Craftvia für Aufträge und Einsätze.
|
||||
|
||||
Die Produkte nicht künstlich funktional koppeln, solange keine echte Integration besteht.
|
||||
|
||||
---
|
||||
|
||||
## 11. Visuelle Identität
|
||||
|
||||

|
||||
|
||||
Die oben gezeigte Identität überträgt die erkennbare dunkelblau-orange Gestaltung von „Mein Lotse“ auf Craftvia. Sie dient als verbindliche visuelle Vorzugsrichtung für die weitere Reinzeichnung. Das Hauptlogo gehört Craftvia; die illustrierte Lotsenfigur bleibt als eigenständiger KI-Assistent im Produkt erhalten.
|
||||
|
||||
### 11.1 Gestaltungsprinzip
|
||||
|
||||
Die visuelle Identität verbindet **handwerkliche Robustheit** mit **digitaler Klarheit**. Sie wirkt professionell und belastbar, nicht verspielt oder wie ein kurzlebiges Technologie-Startup.
|
||||
|
||||
Leitbegriffe:
|
||||
|
||||
- klare Wege
|
||||
- verlässliche Verbindung
|
||||
- Fortschritt
|
||||
- Präzision
|
||||
- Arbeit in Bewegung
|
||||
- dokumentierter Abschluss
|
||||
|
||||
### 11.2 Logo-Konzept
|
||||
|
||||
Empfohlen wird eine reduzierte Wort-Bild-Marke aus:
|
||||
|
||||
- der Wortmarke **Craftvia** und
|
||||
- einem geometrischen Signet, das Weg, Verbindung und Abschluss abstrahiert.
|
||||
|
||||
Geeignete Bildideen:
|
||||
|
||||
1. **C-Pfad:** Ein stilisiertes C bildet einen Weg mit Start- und Zielpunkt.
|
||||
2. **CV-Monogramm:** C und V greifen ineinander; das V wirkt zugleich wie Haken oder bestätigter Arbeitsschritt.
|
||||
3. **Verbundene Wegpunkte:** Zwei bis drei Punkte bilden einen klaren Prozesspfad.
|
||||
|
||||
**Vorzugsrichtung:** C-Pfad mit subtil integriertem Bestätigungshaken. Das Symbol verbindet Name, Prozess und Ergebnis, ohne auf austauschbare Hammer-, Zahnrad- oder Baustellenklischees zurückzugreifen.
|
||||
|
||||
Der frühere maritime Lotse oder Kompass soll nicht mehr das Hauptlogo bestimmen. Ein diskreter Navigationsgedanke darf im Symbol oder in der Illustration des KI-Assistenten vorkommen.
|
||||
|
||||
### 11.3 Logo-Regeln
|
||||
|
||||
- Primär horizontale Wort-Bild-Marke verwenden.
|
||||
- Signet allein nur bei kleinen Formaten, App-Icon und Favicon.
|
||||
- Schutzraum mindestens in Höhe des kleinen „a“ der Wortmarke.
|
||||
- Mindestbreite digital: 120 px für die vollständige Marke, 24 px für das Signet.
|
||||
- Keine Schatten, Verläufe, Konturen oder Verzerrungen im Logo.
|
||||
- Keine Platzierung auf unruhigen Fotos ohne ruhige Farbfläche.
|
||||
- Einfarbige Varianten in Dunkelblau, Weiß und Schwarz vorsehen.
|
||||
|
||||
### 11.4 Farbpalette
|
||||
|
||||
#### Craftvia Kernfarben
|
||||
|
||||
| Rolle | Name | Hex | Verwendung |
|
||||
|---|---|---:|---|
|
||||
| Primär | **Lotsenblau** | `#082E5B` | Logo, Navigation, Headlines, Vertrauen |
|
||||
| Sekundär | **Signalorange** | `#FF6A00` | „via“, Weg-/Haken-Signet, CTA, aktive Elemente |
|
||||
| Dunkel | **Graphit** | `#34383D` | Fließtext, Footer und starke Kontraste |
|
||||
| Hell | **Hafengrau** | `#F3F5F7` | Flächen und Seitenhintergrund |
|
||||
| Neutral | **Stahlgrau** | `#66727D` | Sekundärtext und Icons |
|
||||
| Linie | **Zink** | `#D9E0E5` | Trennlinien und Eingabefelder |
|
||||
| Weiß | **Klarweiß** | `#FFFFFF` | Karten und Kontrastflächen |
|
||||
|
||||
#### Funktionsfarben
|
||||
|
||||
| Funktion | Hex | Verwendung |
|
||||
|---|---:|---|
|
||||
| Erfolg | `#23845D` | abgeschlossen, geprüft |
|
||||
| Warnung | `#C87912` | unvollständig, Aufmerksamkeit |
|
||||
| Fehler | `#C64242` | Fehler, blockierende Aktion |
|
||||
| Information | `#2F6FA3` | neutrale Hinweise |
|
||||
|
||||
Farbe nie als einziges Statussignal einsetzen; immer mit Text und/oder Icon kombinieren.
|
||||
|
||||
#### Produktfamilie
|
||||
|
||||
Lotsenblau kann als gemeinsames neutrales Fundament der Produktfamilie dienen. Signalorange ist der exklusive Craftvia-Akzent. Certvia und Visitvia behalten beziehungsweise erhalten klar unterscheidbare Akzentfarben. Die konkrete Familienpalette ist in einem übergeordneten Designsystem abschließend zu harmonisieren.
|
||||
|
||||
### 11.5 Typografie
|
||||
|
||||
**Primärschrift:** **Inter** – für Web, App und Präsentationen.
|
||||
**Fallback:** system-ui, Segoe UI, Roboto, Arial, sans-serif.
|
||||
|
||||
Empfohlene Gewichte:
|
||||
|
||||
- Headlines: 700
|
||||
- Zwischenüberschriften: 600
|
||||
- Fließtext: 400
|
||||
- UI-Labels und Buttons: 600
|
||||
|
||||
Grundregeln:
|
||||
|
||||
- Satzfall statt Versalien verwenden.
|
||||
- Fließtext digital mindestens 16 px.
|
||||
- Großzügige Zeilenhöhe von etwa 1,5.
|
||||
- Textzeilen auf Website-Inhalten auf ca. 65–75 Zeichen begrenzen.
|
||||
- Zahlen und Statuswerte klar, aber nicht dekorativ hervorheben.
|
||||
|
||||
### 11.6 Iconografie
|
||||
|
||||
- Einfache Outline-Icons mit konsistenter Strichstärke.
|
||||
- Abgerundete Ecken vermitteln Zugänglichkeit, ohne weich zu wirken.
|
||||
- Icons immer aus der Tätigkeit ableiten: Auftrag, Kalender, Team, Kamera, Material, Bericht, Unterschrift.
|
||||
- Keine Mischung verschiedener Icon-Stile.
|
||||
- Maritime Symbole ausschließlich im Kontext des Lotsen und sehr sparsam einsetzen.
|
||||
|
||||
### 11.7 Bildwelt
|
||||
|
||||
Die Bildwelt zeigt echte Arbeitssituationen und den Informationsfluss zwischen Baustelle und Büro.
|
||||
|
||||
**Motive**
|
||||
|
||||
- Fachkräfte bei konkreter Arbeit, nicht beim Posieren
|
||||
- Tablet oder Smartphone als selbstverständliches Werkzeug
|
||||
- Details von Händen, Material, Anlage und Dokumentation
|
||||
- Austausch zwischen Team und Backoffice
|
||||
- saubere, glaubwürdige Arbeitsumgebungen mit realen Gebrauchsspuren
|
||||
|
||||
**Stil**
|
||||
|
||||
- dokumentarisch, hochwertig, natürlich
|
||||
- neutrales bis leicht warmes Licht
|
||||
- klare Bildkomposition und ausreichend Freiraum für Text
|
||||
- diverse Gewerke, Altersgruppen und Personen zeigen
|
||||
|
||||
**Vermeiden**
|
||||
|
||||
- gestellte Handschlagmotive
|
||||
- übertriebene Schutzhelm-Stockfotos ohne fachlichen Kontext
|
||||
- reine Software-Screens auf abstrakten Neon-Hintergründen
|
||||
- maritime Bildwelten, Leuchttürme oder Steuerräder als Dauermotiv
|
||||
|
||||
### 11.8 Illustrationen
|
||||
|
||||
Illustrationen dürfen Prozesse vereinfachen: Auftrag kommt herein, Team arbeitet, Nachweis geht zurück. Flache geometrische Formen, klare Linien und wenige Farben verwenden. Technische Details nur zeigen, wenn sie korrekt sind.
|
||||
|
||||
---
|
||||
|
||||
## 12. UI- und UX-Grundsätze
|
||||
|
||||
### 12.1 Leitprinzipien
|
||||
|
||||
1. **Für den Einsatz gebaut:** große Touch-Ziele, hohe Kontraste, wenige Schritte.
|
||||
2. **Status sofort sichtbar:** Was ist neu, offen, unvollständig oder abgeschlossen?
|
||||
3. **Eine primäre Aktion je Ansicht:** Nutzer erkennen den nächsten Schritt ohne Suche.
|
||||
4. **Fehler vermeiden:** Pflichtangaben und fehlende Nachweise früh anzeigen.
|
||||
5. **Fortschritt sichern:** Eingaben zwischenspeichern und instabile Verbindung berücksichtigen.
|
||||
6. **Rollen respektieren:** Monteur, Disposition und Backoffice sehen das für sie Relevante.
|
||||
|
||||
### 12.2 Layout und Komponenten
|
||||
|
||||
- 8-Pixel-Raster als Basis
|
||||
- Karten für Aufträge und Einsätze mit klarer Statuskante
|
||||
- Primärbuttons in Craft Orange auf ruhigen Flächen
|
||||
- Sekundärbuttons als Outline oder Textbutton
|
||||
- Eckenradius 8–12 px, nicht pillenförmig für jede Komponente
|
||||
- Mindestgröße interaktiver Flächen: 44 × 44 px
|
||||
- Formulare in logische, kurze Abschnitte teilen
|
||||
- Fortschrittsanzeige bei mehrstufigem Einsatzabschluss
|
||||
|
||||
### 12.3 Statussprache
|
||||
|
||||
Bevorzugte Statuswerte:
|
||||
|
||||
- Neu
|
||||
- Geplant
|
||||
- Unterwegs
|
||||
- In Arbeit
|
||||
- Dokumentation unvollständig
|
||||
- Zur Prüfung
|
||||
- Abgeschlossen
|
||||
- Bereit zur Abrechnung
|
||||
- Abgerechnet
|
||||
|
||||
Status müssen tatsächliche Prozessschritte abbilden und dürfen nicht synonym verwendet werden.
|
||||
|
||||
### 12.4 Lotse im Interface
|
||||
|
||||
Der Lotse erscheint als hilfreiche, kontextbezogene Funktion – nicht als dauerhaft dominierender Chatbot.
|
||||
|
||||
Beispiele:
|
||||
|
||||
- „Bericht mit Lotse vorbereiten“
|
||||
- „3 Angaben fehlen. Lotse prüfen lassen“
|
||||
- „Sprachnotiz zusammenfassen“
|
||||
|
||||
Jede KI-Ausgabe bleibt prüf- und editierbar. Automatisch erzeugte Inhalte werden als Vorschlag gekennzeichnet.
|
||||
|
||||
### 12.5 Barrierefreiheit
|
||||
|
||||
- Ziel: WCAG 2.2 AA für Website und zentrale Produktabläufe
|
||||
- Kontrast von Text und Interaktionen prüfen
|
||||
- vollständige Tastaturbedienung im Backoffice
|
||||
- sichtbare Fokuszustände
|
||||
- verständliche Fehlermeldungen direkt am Feld
|
||||
- Alternativtexte für inhaltliche Bilder
|
||||
- keine Information ausschließlich durch Farbe oder Bewegung
|
||||
|
||||
---
|
||||
|
||||
## 13. Homepage-Struktur
|
||||
|
||||
### 13.1 Header
|
||||
|
||||
**Navigation:** Produkt · Lösungen · Für wen · Lotse · Preise · Über uns
|
||||
**Sekundäre Aktion:** Anmelden
|
||||
**Primäre Aktion:** Demo vereinbaren
|
||||
|
||||
### 13.2 Hero
|
||||
|
||||
**Eyebrow:** Die Einsatzplattform fürs Handwerk
|
||||
**Headline:** **Handwerk. Digital auf Kurs.**
|
||||
**Subheadline:** Craftvia verbindet Büro und Baustelle – vom Auftrag über die mobile Dokumentation bis zum vollständigen Nachweis für eine schnellere Abrechnung.
|
||||
**Primärer CTA:** Demo vereinbaren
|
||||
**Sekundärer CTA:** Ablauf ansehen
|
||||
|
||||
**Visual:** Ein realistischer Einsatzablauf mit mobiler Auftragsansicht im Vordergrund und einer klaren Statuskette im Hintergrund. Keine rein dekorative Geräte-Collage.
|
||||
|
||||
### 13.3 Problemsektion
|
||||
|
||||
**Headline:** **Gute Arbeit ist längst erledigt. Die Rechnung wartet noch.**
|
||||
|
||||
Stundenzettel liegen im Fahrzeug, Fotos fehlen und Materialangaben kommen auf Zuruf. Das Backoffice sammelt Informationen, statt Rechnungen vorzubereiten. So vergehen zwischen Einsatz und Zahlung wertvolle Wochen.
|
||||
|
||||
**Problemkarten:**
|
||||
|
||||
- Zettel und Informationen sind unterwegs.
|
||||
- Rückfragen kosten Büro und Team Zeit.
|
||||
- Fehlende Nachweise verzögern die Abrechnung.
|
||||
|
||||
### 13.4 Lösungssektion
|
||||
|
||||
**Headline:** **Ein klarer Weg für jeden Auftrag.**
|
||||
|
||||
1. **Auftrag vorbereiten** – Daten übernehmen, Unterlagen zuordnen, Team einplanen.
|
||||
2. **Einsatz durchführen** – Alle Informationen mobil nutzen und Leistungen direkt erfassen.
|
||||
3. **Vollständig abschließen** – Bericht, Fotos und Unterschrift prüfen und übergeben.
|
||||
4. **Schneller abrechnen** – Das Backoffice erhält einen strukturierten Nachweis.
|
||||
|
||||
### 13.5 Nutzen-/Cashflow-Sektion
|
||||
|
||||
**Headline:** **Damit aus geleisteter Arbeit schneller Umsatz wird.**
|
||||
|
||||
Craftvia verkürzt den Weg zwischen Baustelle und Büro. Sobald ein Einsatz abgeschlossen ist, liegen die relevanten Angaben strukturiert vor. Das reduziert Nacharbeit und schafft die Grundlage, Rechnungen früher zu stellen.
|
||||
|
||||
**Hinweis:** Keine konkrete Beschleunigung in Prozent versprechen, bis diese durch Pilotkunden belegt ist.
|
||||
|
||||
### 13.6 Zielgruppensektion
|
||||
|
||||
**Für das Büro:** Überblick, vollständige Nachweise, weniger Nachtelefonieren.
|
||||
**Für die Einsatzleitung:** klare Planung und aktueller Status.
|
||||
**Für das Team vor Ort:** alle Unterlagen und einfache Dokumentation in einer Anwendung.
|
||||
**Für die Geschäftsführung:** transparente Abläufe und schnellerer Cashflow.
|
||||
|
||||
### 13.7 Lotse-Sektion
|
||||
|
||||
**Headline:** **Der Lotse nimmt Schreibarbeit ab. Sie behalten die Kontrolle.**
|
||||
|
||||
Sprachnotizen strukturieren, fehlende Angaben erkennen und Berichte vorbereiten: Der KI-Assistent unterstützt genau dort, wo Dokumentation im Alltag Zeit kostet. Alle Vorschläge bleiben prüfbar.
|
||||
|
||||
**CTA:** Lotse kennenlernen
|
||||
|
||||
### 13.8 Historie-Sektion
|
||||
|
||||
**Headline:** **Beim nächsten Einsatz ist das Wissen schon da.**
|
||||
|
||||
Vergangene Arbeiten, Berichte, Fotos, technische Zeichnungen und Hinweise bleiben am Kunden und Objekt verfügbar. So startet das Team nicht bei null.
|
||||
|
||||
### 13.9 Notdienst-Sektion
|
||||
|
||||
**Headline:** **Auch dann dokumentiert, wenn das Büro nicht besetzt ist.**
|
||||
|
||||
Teams können einen Notdiensteinsatz selbst anlegen, Leistungen erfassen und abschließen. Das Backoffice erhält am nächsten Arbeitstag alle Angaben zur Prüfung und Abrechnung.
|
||||
|
||||
### 13.10 Vertrauen und Produktfamilie
|
||||
|
||||
**Headline:** **Ein Produkt aus einer klaren Softwarefamilie.**
|
||||
|
||||
Craftvia folgt derselben Idee wie Certvia und Visitvia: komplexe Geschäftsprozesse verständlich führen, Informationen zentral verfügbar machen und tägliche Arbeit verlässlich dokumentieren.
|
||||
|
||||
### 13.11 Abschluss-CTA
|
||||
|
||||
**Headline:** **Bringen Sie Ihre Aufträge auf einen klaren digitalen Weg.**
|
||||
**Text:** Erleben Sie, wie Craftvia Büro und Einsatzteam verbindet und abgeschlossene Arbeit schneller abrechnungsfähig macht.
|
||||
**CTA:** Demo vereinbaren
|
||||
|
||||
---
|
||||
|
||||
## 14. Mustertexte
|
||||
|
||||
### 14.1 Kurzbeschreibung
|
||||
|
||||
Craftvia ist die digitale Einsatzplattform für Handwerks- und Servicebetriebe. Sie verbindet Auftrag, Team, Baustellendokumentation und Abrechnungsvorbereitung in einem durchgängigen Ablauf.
|
||||
|
||||
### 14.2 50-Wörter-Pitch
|
||||
|
||||
Mit Craftvia erhalten Teams alle Auftragsinformationen direkt am Einsatzort, dokumentieren Zeiten, Material, Fotos und Leistungen mobil und übergeben vollständige Nachweise ans Büro. So sinkt der Abstimmungsaufwand, Wissen bleibt am Kunden und abgeschlossene Arbeit kann schneller abgerechnet werden – unterstützt durch den KI-Assistenten Lotse.
|
||||
|
||||
### 14.3 Elevator Pitch
|
||||
|
||||
Viele Handwerksbetriebe leisten heute gute Arbeit und warten trotzdem Wochen auf die nötigen Unterlagen für die Rechnung. Craftvia verbindet Büro und Baustelle in einem digitalen Prozess: Auftrag bereitstellen, Einsatz dokumentieren, Bericht abschließen und vollständig ans Backoffice übergeben. Damit wird aus erledigter Arbeit schneller eine abrechenbare Leistung.
|
||||
|
||||
### 14.4 App-Store-/Verzeichnistext
|
||||
|
||||
**Craftvia – Aufträge und Einsätze verwalten**
|
||||
|
||||
Craftvia begleitet Handwerks- und Serviceteams vom Auftrag bis zum vollständigen Leistungsnachweis. Alle relevanten Informationen stehen mobil zur Verfügung. Zeiten, Material, Fotos, Notizen und Unterschriften werden direkt vor Ort erfasst. Das Backoffice erhält strukturierte Unterlagen für Prüfung und Abrechnung.
|
||||
|
||||
### 14.5 Social-/Vertriebs-Teaser
|
||||
|
||||
Der Auftrag ist erledigt – aber der Stundenzettel liegt noch im Fahrzeug? Craftvia bringt Büro und Baustelle in einen gemeinsamen Ablauf. Leistungen werden direkt vor Ort dokumentiert und vollständig zur Abrechnung übergeben. Weniger Nachfragen. Weniger Papier. Schneller bereit für die Rechnung.
|
||||
|
||||
### 14.6 Produktfamilien-Pitch
|
||||
|
||||
Certvia, Visitvia und Craftvia bilden eine Familie klarer Geschäftsanwendungen: Informationssicherheit verwalten, Besucherprozesse steuern und Handwerkseinsätze digital begleiten. Jede Lösung konzentriert sich auf einen zentralen Prozess – verständlich, nachvollziehbar und praxistauglich.
|
||||
|
||||
---
|
||||
|
||||
## 15. Anwendungsszenarien
|
||||
|
||||
### 15.1 Geplanter Auftrag
|
||||
|
||||
Das Backoffice übernimmt Daten aus einer Auftragsbestätigung, prüft Kunde und Objekt, ergänzt Unterlagen und weist ein Team zu. Das Team sieht Auftrag, Ansprechpartner, Materialvorgaben und Zeichnungen mobil. Nach dem Einsatz werden Zeiten, Verbrauch, Fotos und Unterschrift abgeschlossen. Der Bericht steht unmittelbar zur Prüfung bereit.
|
||||
|
||||
### 15.2 Wiederkehrender Einsatz
|
||||
|
||||
Vor Ort öffnet der Techniker die Objekthistorie und sieht frühere Arbeiten, Bilder und Hinweise. Neue Erkenntnisse werden dem Objekt zugeordnet und stehen beim nächsten Einsatz wieder zur Verfügung.
|
||||
|
||||
### 15.3 Notdienst
|
||||
|
||||
Ein Monteur legt außerhalb der Bürozeiten selbst einen Notdiensteinsatz an, dokumentiert Problem, Maßnahmen, Material und Arbeitszeit und lässt die Leistung bestätigen. Das Backoffice wird informiert und kann den Vorgang am nächsten Arbeitstag abrechnen.
|
||||
|
||||
### 15.4 KI-gestützte Dokumentation
|
||||
|
||||
Der Monteur spricht eine Notiz ein. Der Lotse schlägt strukturierte Tätigkeiten und Berichtstext vor, erkennt fehlende Angaben und bittet um Ergänzung. Vor dem Abschluss prüft und bestätigt der Monteur das Ergebnis.
|
||||
|
||||
---
|
||||
|
||||
## 16. Do & Don't
|
||||
|
||||
### Do
|
||||
|
||||
- Craftvia als Weg vom Auftrag zum Nachweis erklären.
|
||||
- wirtschaftlichen Nutzen mit dem Arbeitsalltag verbinden.
|
||||
- echte Gewerke und glaubwürdige Situationen zeigen.
|
||||
- Softwarefunktionen in einfacher Sprache beschreiben.
|
||||
- Lotse als unterstützende, kontrollierbare KI positionieren.
|
||||
- Craftvia sichtbar in die Certvia-/Visitvia-Familie einordnen.
|
||||
|
||||
### Don't
|
||||
|
||||
- „Mein Lotse“ weiterhin als Produktname verwenden.
|
||||
- eine maritime Erlebniswelt um Craftvia bauen.
|
||||
- KI als Ersatz für Fachkräfte darstellen.
|
||||
- unbelegte Effizienz- oder Umsatzversprechen machen.
|
||||
- Craftvia auf reine Zeiterfassung reduzieren.
|
||||
- mit ERP-Fachbegriffen kommunizieren, wenn Alltagssprache genügt.
|
||||
- Certvia, Visitvia und Craftvia visuell völlig unabhängig entwickeln.
|
||||
|
||||
---
|
||||
|
||||
## 17. Governance und nächste Schritte
|
||||
|
||||
### 17.1 Verbindlich in dieser Version
|
||||
|
||||
- Markenname und Schreibweise **Craftvia**
|
||||
- Zugehörigkeit zur Produktfamilie Certvia / Visitvia
|
||||
- Kernpositionierung und Markenversprechen
|
||||
- Claim-Hierarchie
|
||||
- Lotse als optionaler Name des KI-Assistenten
|
||||
- Tonalitäts- und UX-Prinzipien
|
||||
- strategische Richtung der visuellen Identität
|
||||
|
||||
### 17.2 Vor Veröffentlichung zu validieren
|
||||
|
||||
- Marken-, Domain- und Kollisionsprüfung für Craftvia
|
||||
- finale Absendermarke beziehungsweise Herstellerzusatz
|
||||
- Logoentwicklung und Prüfung in kleinen Größen
|
||||
- Abstimmung der produktübergreifenden Farb- und Designsysteme
|
||||
- Barrierefreiheitsprüfung der finalen Farbkombinationen
|
||||
- Datenschutz- und Transparenztexte für KI-Funktionen
|
||||
- quantitative Nutzenversprechen anhand von Pilotprojekten
|
||||
- tschechische Namens-, Claim- und Sprachprüfung vor Lokalisierung
|
||||
|
||||
### 17.3 Empfohlene Umsetzungsreihenfolge
|
||||
|
||||
1. Wort-Bild-Marke und App-Icon ausarbeiten.
|
||||
2. gemeinsames Designsystem für Certvia, Visitvia und Craftvia definieren.
|
||||
3. zentrale Website-Ansichten gestalten und testen.
|
||||
4. Kernabläufe der App prototypisch validieren.
|
||||
5. Pilotkunden begleiten und Nutzenkennzahlen erheben.
|
||||
6. Markenbotschaften mit echten Belegen schärfen.
|
||||
|
||||
---
|
||||
|
||||
## 18. Markenkompass
|
||||
|
||||
Bei jeder neuen Seite, Funktion oder Kampagne sind fünf Fragen zu beantworten:
|
||||
|
||||
1. Hilft dies, den Weg vom Auftrag zur Abrechnung klarer zu machen?
|
||||
2. Ist der Nutzen für Büro oder Einsatzteam sofort verständlich?
|
||||
3. Wirkt die Lösung praktisch, verlässlich und bodenständig?
|
||||
4. Fügt sie sich sichtbar in die Produktfamilie ein?
|
||||
5. Unterstützt der Lotse den Menschen, ohne Kontrolle oder Transparenz zu nehmen?
|
||||
|
||||
Wenn eine Maßnahme diese Fragen nicht überzeugend beantwortet, sollte sie überarbeitet werden.
|
||||
|
||||
---
|
||||
|
||||
**Craftvia**
|
||||
**Handwerk. Digital auf Kurs.**
|
||||
*Vom Auftrag bis zur Abrechnung.*
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,323 @@
|
||||
# GAP-Report Runde 2 (strenger Re-Sweep): Richtlinien & Verfahrensanweisungen — ISMS-Vorlagenpaket v2
|
||||
|
||||
| Angabe | Wert |
|
||||
|--------|------|
|
||||
| Prüfgegenstand | `seed/isms-vorlagenpaket-v2/` (Source of Truth; **nicht** der Spiegel unter `.next/standalone/…`) |
|
||||
| Standard | VDA ISA 2027 (Information Security) / ISO 27001:2022 / NIS2-Kontext |
|
||||
| Umfang | 15 Richtlinien (L00, R01–R14), 13 Verfahrensanweisungen (VA-01–VA-13), Baseline, Nachweisregister, `mapping.json` (316 Anforderungen) |
|
||||
| Prüfraster (streng) | **WAS · WIE · WO eindeutig dokumentiert · WER · NACHWEIS** — je Anforderung. „erfüllt" nur, wenn ALLE fünf Dimensionen konkret beantwortet sind **und** operative Prozesse auf eine VA bzw. zentral gepflegte Werte auf Register/Baseline verweisen. Sobald eine Dimension fehlt/vage/doppeldeutig ist → mindestens „teilweise". |
|
||||
| Runde | **2 (Korrektur der zu milden Runde 1)** |
|
||||
| Erstellt | 2026-07-22 |
|
||||
| Status | Review-Report (read-only) — es wurde **nichts** am Vorlagenpaket geändert; nur diese Report-Datei wurde neu erzeugt. |
|
||||
|
||||
> Hinweis: Reiner Prüfbericht. Keine Datei des Vorlagenpakets, kein Code, keine DB, kein Seed wurde geändert; kein Commit, kein Push. Alle Textvorschläge sind einpflegefertig, aber **nicht** eingepflegt.
|
||||
|
||||
---
|
||||
|
||||
## 1. Management-Summary
|
||||
|
||||
Das Vorlagenpaket hat weiterhin einen **überdurchschnittlichen Reifegrad** (zentrale Baseline mit BL-IDs, zentrales Nachweisregister, 316 REQ-Anker ↔ 316 Mapping-IDs ohne Waisen, `-elev`-Blöcke für alle HOCH/SEHR-HOCH-Controls). Runde 1 hat diesen Reifegrad jedoch **zu wohlwollend** in Verdikte übersetzt: Sie hat Anforderungen als „erfüllt" gewertet, deren Umsetzungstext den strengen Rubric (eindeutiger Nachweisort, Inline-VA-Verweis, verwaltetes Register) nicht besteht. Runde 2 legt den skeptischen Maßstab konsequent an.
|
||||
|
||||
**Was gegenüber Runde 1 strenger/korrigiert wurde:**
|
||||
|
||||
- **8 Controls von „erfüllt" auf „teilweise" herabgestuft** (Details in §2): **1.2.3, 2.1.2, 3.1.1, 5.2.6, 5.2.8, 5.3.4-KI, 6.1.3, 7.1.2**. Die neue Control-Verteilung ist **14 erfüllt / 30 teilweise / 2 GAP** (Runde 1: 22 / 22 / 2).
|
||||
- **Doppeldeutige Verortung** („im {{TOOL_TICKET}} **bzw.** ISMS-Tool") wird konsequent als **fehlender eindeutiger Nachweisort (G2)** gewertet — betrifft u. a. 1.2.3 und 1.6.1.
|
||||
- **„Liste/Freigabeliste im ISMS-Tool"** ohne Register-ID, Pflichtattribute und Review-Turnus wird als **fehlendes verwaltetes Register (G4/G8)** gewertet — auch dort, wo Runde 1 „erfüllt" vergeben hatte (1.3.3, 1.3.4, 5.3.4, 5.3.4-KI, 6.1.3, 5.2.8, 5.2.7, 5.1.2).
|
||||
- **Inline-VA-Verweis** wird control-genau geprüft: Von **23 Controls mit zuständiger VA** verweisen nur **8** im Umsetzungstext auf ihre VA; **15** nennen das Verfahren nur generisch bzw. im Anhang → G3.
|
||||
|
||||
**Die drei in Runde 1 bestätigten Misses — in Runde 2 sauber aufgearbeitet:**
|
||||
|
||||
1. **ISA 1.2.3 / R01 §3.3 (Informationssicherheit in Projekten):** In Runde 1 fälschlich „erfüllt". Tatsächlich deckt **keine VA** 1.2.3 ab (kein `FULFILLS 1.2.3` in den VA-Headern, kein Eintrag in `mapping.json → verfahren`). Der Umsetzungstext verortet doppeldeutig („die Einstufung wird im {{TOOL_TICKET}} **bzw. ISMS-Tool** dokumentiert"), und weder der genannte „dokumentierte Kriterienkatalog" noch ein **Projektregister/Projektverzeichnis** sind als verwaltetes Artefakt referenziert. → **Neu bewertet: teilweise**; Befund **G4** (neue VA „Informationssicherheit in Projekten") **+ G2/G8** (eindeutiger Nachweisort, Kriterienkatalog- und Projektregister). Textvorschläge in §8 (A-N1).
|
||||
2. **Rendering-/Konsistenzbug `{{TOOL_TICKET}}` u. ä.:** Der Default von `{{TOOL_TICKET}}` ist **„das Ticketsystem"**; das Muster „im {{TOOL_TICKET}}" rendert daher zu **„im das Ticketsystem"** (Doppelartikel). Analog `{{TOOL_NAME}}` = „das ISMS-Tool" und `{{TOOL_IAM}}` = „das zentrale Verzeichnis …". Systemischer **G6**-Befund mit **11 konkreten Fundstellen** (§6), inkl. eines zusätzlichen Kasus-Fehlers bei `in {{TOOL_IAM}}` (R08:153).
|
||||
3. **Software-Whitelist als verwaltetes Register mit Lieferantenbezug UND Asset-Kopplung:** Empfehlung **REG-SW-WHITELIST** mit Spalten u. a. Software, Version/Patch-Stand, **Quelle/Lieferant/Dienstleister**, Freigabestatus, Verantwortlich, Review — **doppelt cross-verlinkt** an **R13/VA-10 (Lieferantensteuerung)** (zugelassene Software hat einen steuerbaren Lieferanten) und an **R02/VA-08 (Asset & Klassifizierung)** (zugelassene Software ist als Asset geführt). Analog **REG-EXT-SERVICES** für externe/Cloud-/KI-Dienste (§5, §8 A-N3).
|
||||
|
||||
**Reifegrad-Einschätzung Runde 2:** Inhaltlich bleibt die Abdeckung auf Ebene der 312 konsolidierten ISA-Zeilen hoch; die Herabstufungen betreffen überwiegend **Nachweisführung und Verortung** (Inline-Verweis, verwaltetes Register, eindeutiger Ort), nicht fehlenden Sachinhalt. Zwei echte Inhalts-GAPs bleiben (**2.1.1**, **3.1.3**). Mit der Roadmap in §7 erreicht das Paket ein durchgängig audittaugliches Niveau.
|
||||
|
||||
---
|
||||
|
||||
## 2. Bewertungs-Übersicht
|
||||
|
||||
### 2.1 Verteilung Control-Ebene (46 Controls)
|
||||
|
||||
| Verdikt | Runde 1 | **Runde 2** | Controls (Runde 2) |
|
||||
|---------|:------:|:-----------:|--------------------|
|
||||
| **erfüllt** | 22 | **14** | 1.1.1; 1.2.1; 1.2.2; 3.1.4; 4.1.2; 5.1.1; 5.2.2; 5.2.3; 5.2.4; 5.2.5; 5.2.9; 5.3.3; 6.1.1; 7.1.1 |
|
||||
| **teilweise** | 22 | **30** | 1.2.3; 1.3.1; 1.3.2; 1.3.3; 1.3.4; 1.4.1; 1.5.1; 1.5.2; 1.6.1; 1.6.2; 1.6.3; 2.1.2; 2.1.3; 2.1.4; 3.1.1; 4.1.1; 4.1.3; 4.2.1; 5.1.2; 5.2.1; 5.2.6; 5.2.7; 5.2.8; 5.3.1; 5.3.2; 5.3.4; 5.3.4-KI; 6.1.2; 6.1.3; 7.1.2 |
|
||||
| **GAP** | 2 | **2** | 2.1.1; 3.1.3 |
|
||||
|
||||
> Die 46 Controls = 45 Controls in `mapping.json` **+** der „Phantom"-Control **3.1.3** (IMPL-Stub in R07 ohne `REQ`-Anker und ohne `mapping.json`-Eintrag; siehe GAP G-B2).
|
||||
|
||||
### 2.2 Gegenüber Runde 1 KORRIGIERTE Einstufungen (alle: erfüllt → teilweise/GAP)
|
||||
|
||||
| Control | Richtlinie | Runde 1 | **Runde 2** | Grund der Verschärfung | GAP-Typ |
|
||||
|---------|-----------|---------|-------------|------------------------|---------|
|
||||
| **1.2.3** | R01 | erfüllt | **teilweise** | Keine VA deckt 1.2.3 ab; Verortung doppeldeutig („{{TOOL_TICKET}} bzw. ISMS-Tool"); Kriterienkatalog & Projektregister nicht als verwaltete Artefakte referenziert | G2, G4, G8, G6 |
|
||||
| **2.1.2** | R05 | erfüllt | **teilweise** | „Ein Verfahren zum Umgang mit Verstößen ist beschrieben" — Verfahren nicht verortet/verlinkt (kein VA-/Dok-Verweis) | G1, G2 |
|
||||
| **3.1.1** | R07 | erfüllt | **teilweise** | Zutrittsvergabe/-entzug (S1) und Besuchermanagement (S2) nur als „berücksichtigt" pauschaliert; kein Verfahren/VA verortet | G1, G3 |
|
||||
| **5.2.6** | R10 | erfüllt | **teilweise** | VA-06 erfüllt laut `FULFILLS` 5.2.6-M1, wird im IMPL 5.2.6 aber **nicht** inline referenziert | G3 |
|
||||
| **5.2.8** | R04 | erfüllt | **teilweise** | Kritische IT-Dienste nur „identifiziert"; kein verwaltetes Register (RTO/RPO nur im `-elev`-Block, keine BIA-Register-ID) | G8 |
|
||||
| **5.3.4-KI** | R12 | erfüllt | **teilweise** | „Freigabeliste im ISMS-Tool" ist informelles Register ohne Register-ID/Attribute/Turnus (REG-EXT-SERVICES) | G8, G4 |
|
||||
| **6.1.3** | R13 | erfüllt | **teilweise** | VA-10 erfüllt laut `FULFILLS` 6.1.3-M1, IMPL 6.1.3 verweist nicht inline; „Liste der IT-Dienste" (elev) informell | G3, G8 |
|
||||
| **7.1.2** | R14 | erfüllt | **teilweise** | Kein referenzierter Prozess für Betroffenenrechte/Löschfristen-Review (nur BL-DEL-01 statisch); keine Datenschutz-Pflege-VA | G4 |
|
||||
|
||||
### 2.3 Anforderungsebene (316 Einzelanforderungen) — Schwerpunkte
|
||||
|
||||
- **Inline-VA-Verweis:** 23 Controls haben eine zuständige VA; **8** verweisen inline (5.1.1, 5.2.4, 5.2.5*, 5.2.8, 5.2.9, 5.3.4, 5.3.4-KI, 6.1.1), **15** nicht (G3). *5.2.5 verweist auf VA-06, nicht auf das ebenfalls zuständige VA-04.
|
||||
- **Register/Baseline-Bezug fehlt (G8/G4)** bei allen „Liste im Tool"-Formulierungen: 1.2.3 (Kriterienkatalog/Projektregister), 1.3.3 & 5.3.4/5.3.4-KI (externe/Cloud/KI-Dienste), 1.3.4 (Software-Whitelist), 1.5.1 (Auditplan), 2.1.1 (sensible Rollen), 5.1.2 & 5.2.7 (Netz/Netzdienste), 5.2.8 & 6.1.3 (kritische IT-Dienste).
|
||||
- **Leere Anforderung / Mapping-Bruch:** 3.1.3 (leerer `REQ`-Block, IMPL-Stub ohne Mapping); ISA **3.1.2** fehlt in R07 und `mapping.json` vollständig.
|
||||
- **Strukturhinweis:** Control **1.1.1** (L00) hat **keinen gebündelten IMPL-Block**; `impl_anchor == req_anchor` — die „Umsetzung" ist die Leitlinien-Prosa selbst. Inhaltlich vertretbar (Leitlinie), aber vom übrigen `IMPL <control>`-Muster abweichend (siehe auch F-Tooling).
|
||||
|
||||
---
|
||||
|
||||
## 3. Vollständige Verlinkungs-/Coverage-Matrix — ALLE 46 Controls
|
||||
|
||||
Spalten: **Inline im Umsetzungstext verlinkt?** = verweist der `IMPL <control>`-Block per `{{LINK:VA-xx}}`/„siehe … Verfahren" auf die zuständige VA (ja) oder steht die VA nur generisch/im Anhang (nein); „n.a." = keine VA zuständig.
|
||||
|
||||
| # | Control | Anf.-Stufe(n) | Zuständige VA (FULFILLS) | Inline verlinkt? | Register/Baseline-Bezug | Status | Bemerkung |
|
||||
|--:|---------|---------------|--------------------------|:---------------:|--------------------------|--------|-----------|
|
||||
| 1 | 1.1.1 | M×5 / S×4 | n.a. | n.a. | Nachweisregister; ISMS-Tool | erfüllt | Leitlinie; kein IMPL-Block (`impl_anchor=req_anchor`) |
|
||||
| 2 | 1.2.1 | M×6 | n.a. | n.a. | ISMS-Tool; Managementbewertung | erfüllt | Governance vollständig verortet |
|
||||
| 3 | 1.2.2 | M×4 / S×2 / H×1 | n.a. | n.a. | Rollenmatrix; ISMS-Tool | erfüllt | Funktionstrennung im `-elev` |
|
||||
| 4 | 1.2.3 | M×1 / S×3 / H×1 | **keine** | **n.a. (VA fehlt)** | **kein Kriterienkatalog-/Projektregister; keine BL** | **teilweise** | **KORRIGIERT** v. erfüllt; G2/G4/G8/G6 (Miss #1) |
|
||||
| 5 | 1.3.1 | M×2 / S×1 | VA-08 | **nein** | Asset-Inventar (ISMS-Tool) | teilweise | G3 |
|
||||
| 6 | 1.3.2 | M×3 / S×1 | VA-08 | **nein** | Klassifizierungsschema | teilweise | G3 |
|
||||
| 7 | 1.3.3 | M×2 / S×4 | n.a. | n.a. | „Freigabeliste im ISMS-Tool" (informell) | teilweise | G8/G4 → REG-EXT-SERVICES |
|
||||
| 8 | 1.3.4 | M×2 / S×5 / V×1 | n.a. | n.a. | „Whitelist im ISMS-Tool" (informell) | teilweise | G8/G4 → REG-SW-WHITELIST (Miss #3) |
|
||||
| 9 | 1.4.1 | M×4 / S×4 | VA-09 | **nein** | Risikoregister (ISMS-Tool) | teilweise | G3 |
|
||||
| 10 | 1.5.1 | M×5 / S×1 | n.a. | n.a. | „Auditplan" (informell); keine BL-Frequenz | teilweise | G4/G2/G8 → VA-15, REG-AUDIT-PLAN |
|
||||
| 11 | 1.5.2 | M×2 / S×1 | n.a. | n.a. | unabhängige Prüfung; kein Turnus/BL | teilweise | G2/G8 |
|
||||
| 12 | 1.6.1 | M×3 / S×6 / V×1 | VA-01 | **nein** | Meldeweg; „{{TOOL_TICKET}} **bzw.** ISMS-Tool" | teilweise | G3/G2/G6 (doppeldeutig) |
|
||||
| 13 | 1.6.2 | M×3 / S×3 / H×5 / V×1 | VA-01 | **nein** | {{TOOL_TICKET}} | teilweise | G3/G6 |
|
||||
| 14 | 1.6.3 | M×3 / S×6 / H×5 / V×1 | VA-02 | **nein** | Krisenplan; keine BL-Übungsfrequenz | teilweise | G3/G8 |
|
||||
| 15 | 2.1.1 | M×3 / S×2 | **keine** | **n.a. (VA fehlt)** | **kein Register sensibler Rollen** | **GAP** | G1/G2/G4/G5 → VA-14, REG-SENS-ROLES |
|
||||
| 16 | 2.1.2 | M×2 / S×3 | n.a. | n.a. | Personalakte; Verstoß-„Verfahren" unverortet | **teilweise** | **KORRIGIERT** v. erfüllt; G1/G2 |
|
||||
| 17 | 2.1.3 | M×1 / S×6 | VA-12 | **nein** | BL-HR-01; {{TOOL_NAME}} | teilweise | G3/G6 |
|
||||
| 18 | 2.1.4 | M×1 / S×2 / H×1 | n.a. | n.a. | „eine Regelung" — nicht verortet | teilweise | G2/G1 |
|
||||
| 19 | 3.1.1 | M×3 / S×5 / H×1 | n.a. | n.a. | BL-PHY-01/02; Besucher/Zutritt generisch | **teilweise** | **KORRIGIERT** v. erfüllt; G1/G3 → VA-17 |
|
||||
| 20 | 3.1.3 | — (leer) | n.a. | n.a. | IMPL-Stub ohne REQ/Mapping | **GAP** | G6/G1; ISA 3.1.2 fehlt zudem ganz |
|
||||
| 21 | 3.1.4 | M×1 / S×1 / H×1 | n.a. | n.a. | TECH_MDM; BL-EP-02 | erfüllt | Baseline-verankert |
|
||||
| 22 | 4.1.1 | M×1 / S×1 / H×1 | VA-03 | **nein** | BL-IAM-07; TOOL_IAM | teilweise | G3 |
|
||||
| 23 | 4.1.2 | M×2 / S×3 / H×1 / V×1 | n.a. | n.a. | BL-IAM-01/02; TECH_MFA | erfüllt | Baseline-verankert |
|
||||
| 24 | 4.1.3 | M×7 / S×10 | VA-03 | **nein** | TOOL_IAM | teilweise | G3 |
|
||||
| 25 | 4.2.1 | M×2 / S×5 / H×1 / V×2 | VA-03 | **nein** | BL-IAM-05; RECERT_FREQ | teilweise | G3 |
|
||||
| 26 | 5.1.1 | M×1 / S×1 / H×1 | VA-07 | **ja** | BL-CRY-02/05 | erfüllt | Vorbildliche Referenzkette |
|
||||
| 27 | 5.1.2 | M×3 / S×3 / H×1 / V×1 | VA-07 | **nein** | BL-CRY-01/04; Netzdienste informell | teilweise | G3/G8 → REG-NET |
|
||||
| 28 | 5.2.1 | M×1 / S×4 / H×1 | VA-04 | **nein** | BL-OPS-09; {{TOOL_TICKET}} | teilweise | G3/G6 |
|
||||
| 29 | 5.2.2 | M×2 / S×1 | n.a. | n.a. | Trennung Dev/Test/Prod | erfüllt | Konkret |
|
||||
| 30 | 5.2.3 | M×2 / S×8 | n.a. | n.a. | BL-OPS-03; TECH_MALWARE | erfüllt | Baseline-verankert |
|
||||
| 31 | 5.2.4 | M×5 / S×3 / H×2 / V×1 | VA-13 | **ja** | BL-OPS-04; LOG_RETENTION | erfüllt | Referenzkette vollständig |
|
||||
| 32 | 5.2.5 | M×3 / S×3 | VA-04, VA-06 | **teils** | BL-OPS-01/02; PATCH_SLA_CRIT | erfüllt | VA-06 inline; VA-04 nicht inline |
|
||||
| 33 | 5.2.6 | M×5 / S×3 / H×1 / V×1 | VA-06 | **nein** | BL-OPS-07/08; PENTEST_FREQ | **teilweise** | **KORRIGIERT** v. erfüllt; G3 |
|
||||
| 34 | 5.2.7 | M×2 / S×2 / H×1 | n.a. | n.a. | BL-NET-01/02; „Netzplan" informell | teilweise | G8/G2 → REG-NET |
|
||||
| 35 | 5.2.8 | M×2 / S×3 / H×7 / V×3 | VA-02 | **ja** | kein REG-CRIT-SERVICES; RTO/RPO nur elev | **teilweise** | **KORRIGIERT** v. erfüllt; G8 |
|
||||
| 36 | 5.2.9 | M×2 / S×1 / H×2 / V×3 | VA-05 | **ja** | BL-OPS-05; BACKUP_SCHEME/RETENTION | erfüllt | Referenzkette vollständig |
|
||||
| 37 | 5.3.1 | M×4 / S×5 / V×1 | n.a. | n.a. | {{TOOL_TICKET}}; keine Secure-Dev-VA | teilweise | G4/G1/G6 → VA-16 |
|
||||
| 38 | 5.3.2 | M×1 / S×3 / H×1 | n.a. | n.a. | „über ein Verfahren" (generisch) | teilweise | G1/G4 → VA-16 |
|
||||
| 39 | 5.3.3 | S×1 | n.a. | n.a. | BL-DEL-01; Löschprotokoll | erfüllt | Konkret |
|
||||
| 40 | 5.3.4 | M×1 / S×1 | VA-11 | **ja** | „Freigabeliste im ISMS-Tool" (informell) | teilweise | G8 → REG-EXT-SERVICES |
|
||||
| 41 | 5.3.4-KI | M×3 / S×1 | VA-11 | **ja** | „Freigabeliste im ISMS-Tool" (informell) | **teilweise** | **KORRIGIERT** v. erfüllt; G8/G4 |
|
||||
| 42 | 6.1.1 | M×3 / S×2 / H×3 / V×2 | VA-10 | **ja** | BL-SUP-01; Lieferantenverzeichnis | erfüllt | Referenzkette vollständig |
|
||||
| 43 | 6.1.2 | M×4 / S×5 | VA-10 | **nein** | NDAs „im ISMS-Tool" (informell) | teilweise | G3 |
|
||||
| 44 | 6.1.3 | M×5 / S×2 / H×5 | VA-10 | **nein** | „Liste der IT-Dienste" (elev, informell) | **teilweise** | **KORRIGIERT** v. erfüllt; G3/G8 |
|
||||
| 45 | 7.1.1 | M×2 / S×1 | n.a. | n.a. | Compliance-/Rechtsregister (ISMS-Tool) | erfüllt | Register vorhanden |
|
||||
| 46 | 7.1.2 | M×3 | n.a. | n.a. | VVT (ISMS-Tool); BL-DEL-01 | **teilweise** | **KORRIGIERT** v. erfüllt; G4 (Betroffenenrechte/Löschfristen-Prozess) → VA-18 |
|
||||
|
||||
---
|
||||
|
||||
## 4. GAP-Tabelle
|
||||
|
||||
Legende Schwere: **hoch** = unmittelbar auditrelevant / Inhaltslücke · **mittel** = schwächt Nachweisführung / Konsistenz · **niedrig** = Feinschliff.
|
||||
GAP-Typen: G1 zu generisch · G2 kein/eindeutiger Nachweisort fehlt · G3 fehlende Inline-Verlinkung · G4 fehlende VA/Register · G5 Verantwortlicher unklar · G6 Widerspruch/Redundanz/veraltet/Rendering · G7 Schutzbedarf nicht adressiert · G8 Baseline-/Register-Referenz fehlt.
|
||||
|
||||
| # | Richtlinie | Control | Anf. (M/S/H/V) | Umsetzung heute (Kurz) | GAP-Typ | Schwere | Empfehlung | Konkreter Textvorschlag | Ziel-Referenz |
|
||||
|---|-----------|---------|----------------|------------------------|---------|---------|------------|--------------------------|---------------|
|
||||
| **N1** | R01 | **1.2.3** | M/S/H | „Klassifizierung anhand Kriterienkatalog; Einstufung im {{TOOL_TICKET}} **bzw. ISMS-Tool**; Maßnahmen als Aufgaben" — keine VA, doppeldeutiger Ort, Kriterienkatalog/Projektregister nicht referenziert | **G4, G2, G8, G6** | **hoch** | Neue VA „Informationssicherheit in Projekten"; Kriterienkatalog + Projektregister als verwaltete Artefakte; eindeutigen Ort setzen; Rendering fixen | siehe A-N1 | Neue **VA-19**, **REG-PROJECTS**, Kriterienkatalog (BL-PROJ-01) |
|
||||
| G-B1 | R05 | 2.1.1 | M×3 / S×2 | „Sensible Tätigkeiten sind bestimmt; Eignung im rechtlich zulässigen Rahmen geprüft" — ohne Register, ohne Einstellungs-/Verifizierungs-VA, WER unklar | G1, G2, G4, G5 | **hoch** | Register sensibler Tätigkeitsbereiche + VA-14 (Eignungs-/Verifizierungsprozess) | siehe A-G-B1 | Neue **VA-14**, **REG-SENS-ROLES** |
|
||||
| G-B2 | R07 | 3.1.3 | — (leer) | **Anforderungsblock leer**; IMPL-Stub ohne `REQ`/Mapping; **ISA 3.1.2 fehlt ganz** | G6, G1 | **hoch** | Scope 3.1.2/3.1.3 klären; REQ-Anker + Mapping ergänzen **oder** Stub entfernen | siehe A-G-B2 | `mapping.json`, R07 |
|
||||
| N2 | R05 | 2.1.2 | M/S | „Ein Verfahren zum Umgang mit Verstößen ist beschrieben" — Verfahren nicht verortet/verlinkt | G1, G2 | mittel | Verstoß-/Disziplinarverfahren benennen & verorten (Dok/VA-14) | „… ein dokumentiertes Verfahren zum Umgang mit Verstößen **(siehe {{LINK:VA-14}})** ist etabliert; Nachweis in der Personalakte." | {{LINK:VA-14}} / Personalakte |
|
||||
| N3 | R07 | 3.1.1 | M/S/H | Besuchermanagement, Zutrittsvergabe/-entzug (S1/S2) nur als „berücksichtigt" pauschaliert | G1, G3 | mittel | Zutritts-/Besuchermanagement-Verfahren verorten | „… Zutrittsrechte werden über {{TOOL_TICKET}} vergeben/entzogen **(Ablauf siehe {{LINK:VA-17}})**; Besuchermanagement (Registrierung/Begleitung) ist geregelt (BL-PHY-…)." | Neue **VA-17** |
|
||||
| N4 | R10 | 5.2.6 | M/S/H/V | Härtung/technische Prüfungen; VA-06 erfüllt 5.2.6-M1, aber **nicht inline** referenziert | G3 | mittel | VA-06 im IMPL 5.2.6 inline referenzieren | „… risikoorientiert geprüft **(siehe {{LINK:VA-06}})**; Ergebnisse werden gespeichert, der Leitung berichtet …" | {{LINK:VA-06}} |
|
||||
| N5 | R04 | 5.2.8 | M/S/H/V | Kritische IT-Dienste „identifiziert"; RTO/RPO nur im `-elev`-Block; kein Register | G8 | mittel | Register kritischer IT-Dienste inkl. BIA/RTO/RPO referenzieren | „Kritische IT-Dienste sind mit Geschäftsauswirkung im **Register kritischer IT-Dienste ({{LINK:REG-CRIT-SERVICES}})** (inkl. RTO/RPO, Wiederanlaufreihenfolge) erfasst … (siehe {{LINK:VA-02}})." | **REG-CRIT-SERVICES** |
|
||||
| N6 | R12 | 5.3.4-KI | M/S | „Freigabeliste im ISMS-Tool" ohne Register-ID/Attribute/Turnus | G8, G4 | mittel | KI-/externe Dienste als verwaltetes Register mit Lieferant+Asset-Kopplung | siehe A-N6 | **REG-EXT-SERVICES**, {{LINK:VA-11}} |
|
||||
| N7 | R13 | 6.1.3 | M/S/H | VA-10 erfüllt 6.1.3-M1, IMPL nicht inline; „Liste IT-Dienste/Dienstleister" (elev) informell | G3, G8 | mittel | VA-10 inline; Dienste-/Dienstleister-Register formalisieren | „… Verantwortlichkeiten … definiert **(siehe {{LINK:VA-10}})**; betroffene IT-Dienste und Dienstleister im **{{LINK:REG-EXT-SERVICES}}** geführt." | {{LINK:VA-10}}, **REG-EXT-SERVICES** |
|
||||
| N8 | R14 | 7.1.2 | M | VVT im Tool; kein referenzierter Prozess für Betroffenenrechte/Löschfristen-Review | G4 | mittel | Datenschutz-/Compliance-Pflege-VA referenzieren | siehe A-N8 | Neue **VA-18** |
|
||||
| N9 | R09 | 5.1.2 | M/S/H/V | VA-07 erfüllt 5.1.2-M1/S1, IMPL 5.1.2 verweist nicht inline; Netzdienste nur „identifiziert" | G3, G8 | mittel | VA-07 inline; Netzdienste-Register | „Genutzte Netzdienste sind im **{{LINK:REG-NET}}** identifiziert/dokumentiert; Krypto-/Schlüsselverwaltung **(siehe {{LINK:VA-07}})**." | {{LINK:VA-07}}, **REG-NET** |
|
||||
| F3 | R02 | 1.3.1, 1.3.2 | M/S | IMPL ohne Inline-Verweis auf VA-08 | G3 | mittel | VA-08 im Umsetzungstext inline referenzieren | „… als Katalog gepflegt **(siehe {{LINK:VA-08}})**; Zu-/Abgänge über {{TOOL_TICKET}}." | {{LINK:VA-08}} |
|
||||
| F4 | R03 | 1.4.1 | M/S | „Das dokumentierte Risikomanagement-Verfahren …" ohne Inline-Link auf VA-09 | G3 | mittel | VA-09 inline referenzieren | „Das dokumentierte Risikomanagement-Verfahren **(siehe {{LINK:VA-09}})** …" | {{LINK:VA-09}} |
|
||||
| F5 | R04 | 1.6.1, 1.6.2 | M/S/H/V | „nach einem definierten Incident-Verfahren im {{TOOL_TICKET}}" ohne Inline-Link auf VA-01 | G3 | mittel | VA-01 inline referenzieren | „… nach einem definierten Incident-Verfahren **(siehe {{LINK:VA-01}})** … behandelt und dokumentiert." | {{LINK:VA-01}} |
|
||||
| F6 | R04 | 1.6.3 | M/S/H/V | Krisenmanagement generisch; VA-02 nur im Anhang | G3, G8 | mittel | VA-02 inline; Übungsfrequenz in Baseline | „Ein Krisenmanagement … ist etabliert **(Auslösung/Wiederanlauf siehe {{LINK:VA-02}})** (Übungen BL-IR-01)." | {{LINK:VA-02}}, **BL-IR-01** |
|
||||
| F7 | R05 | 2.1.3 | M/S | Awareness stark (BL-HR-01); VA-12 nur im Anhang | G3 | mittel | VA-12 inline referenzieren | „… mindestens {{REVIEW_CYCLE}} … geschult **(Ablauf siehe {{LINK:VA-12}})**." | {{LINK:VA-12}} |
|
||||
| F8 | R08 | 4.1.1, 4.1.3, 4.2.1 | M/S/H/V | JML/Rezertifizierung stark, aber VA-03 nur im Anhang | G3 | mittel | VA-03 inline referenzieren | „Benutzerkonten werden über einen definierten Lebenszyklus (Joiner/Mover/Leaver) **(siehe {{LINK:VA-03}})** … verwaltet." | {{LINK:VA-03}} |
|
||||
| F9 | R10 | 5.2.1 | M/S/H | „formales Change-Verfahren … im {{TOOL_TICKET}} (BL-OPS-09)" ohne Inline-Link auf VA-04 | G3 | mittel | VA-04 inline referenzieren | „Änderungen durchlaufen ein formales Change-Verfahren **(siehe {{LINK:VA-04}})** …" | {{LINK:VA-04}} |
|
||||
| F10 | R02 | 1.3.4 | M/S/V | „Liste zugelassener Software (Whitelist) … im ISMS-Tool" ohne Register-ID, Lieferant/Freigabestatus | G8, G4 | mittel | REG-SW-WHITELIST mit Lieferant- UND Asset-Kopplung | siehe A-N3 (Miss #3) | **REG-SW-WHITELIST** |
|
||||
| F11 | R02 / R12 | 1.3.3 / 5.3.4 | M/S | „Freigabeliste im ISMS-Tool" für externe/Cloud-/KI-Dienste — generisch | G8, G4 | mittel | Gemeinsames REG-EXT-SERVICES mit Schutzbedarf/Exit/Lieferant | siehe A-N6 | **REG-EXT-SERVICES**, {{LINK:VA-11}} |
|
||||
| F12 | R03 | 1.5.1, 1.5.2 | M/S | Audits „nach einem Auditplan"; kein Audit-Verfahren, keine Verortung/Frequenz | G2, G4, G8 | mittel | Audit-Verfahren (VA-15) + Audit-Programm-Register + Baseline-Frequenz | siehe A-F12 | Neue **VA-15**, **REG-AUDIT-PLAN**, **BL-GOV-01** |
|
||||
| F13 | R11 | 5.3.1, 5.3.2 | M/S/H/V | Security-by-Design/Abnahme, aber keine VA; 5.3.2 „über ein Verfahren umgesetzt" | G4, G1 | mittel | VA-16 (Sichere Beschaffung/Entwicklung & Abnahme) inline | siehe A-F13 | Neue **VA-16** |
|
||||
| F14 | R09 / R10 | 5.1.2 / 5.2.7 | M/S/H | „Netzplan/Segmentierungskonzept wird gepflegt", „Netzdienste identifiziert" — ohne Register-ID | G2, G8 | niedrig | Verwaltetes Netz-/Netzdienste-Register mit Turnus | „… ein aktueller Netzplan/Segmentierungskonzept wird im **{{LINK:REG-NET}}** gepflegt (Review {{REVIEW_CYCLE}})." | **REG-NET** |
|
||||
| F16 | R06 | 2.1.4 | M/S/H | „Mobiles Arbeiten ist in einer Regelung festgelegt" — welche, wo? | G2, G1 | niedrig | Regelung konkret benennen/verorten | „Mobiles Arbeiten ist in der **Regelung mobiles Arbeiten (im ISMS-Tool ({{TOOL_NAME}}) hinterlegt)** festgelegt …" | {{TOOL_NAME}} |
|
||||
| F17 | — (Tooling) | — | — | `mapping.json` ohne `implementation`-Feld (0/316); Integrationsleitfaden §5/§8 setzt es voraus (Assessment-Export) | G6 | mittel | Feld `implementation` ergänzen **oder** Leitfaden korrigieren (`impl_anchor`-Auflösung dokumentieren) | siehe A-F17 | `mapping.json` / `00_Integrationsleitfaden_Wizard.md` |
|
||||
| F18 | Alle (elev) | div. | H/V | `-elev`-Blöcke mischen HOCH- und SEHR-HOCH-Sätze unter **einem** `FLAG_ELEVATED_PROTECTION`; bei nur HOCH erscheint „Bei sehr hohem Schutzbedarf …" | G6, G7 | niedrig | SEHR-HOCH-Sätze in `{{#if FLAG_VERY_HIGH_PROTECTION}}` auslagern | siehe A-F18 | R04/R08/R10 u. a. `-elev`-Blöcke |
|
||||
| F19 | R13 | 6.1.2 | M/S | NDA-Prozess stark; VA-10 deckt 6.1.2-M1/S1, IMPL nicht inline | G3 | niedrig | VA-10 auch bei NDA inline referenzieren | „… gültige NDAs auf Basis geprüfter Standardvorlagen **(Ablauf siehe {{LINK:VA-10}})** …" | {{LINK:VA-10}} |
|
||||
| F21 | VA-10 | 6.1.x | — | RACI-Schritttexte in der Tabelle abgeschnitten („… (Schutzb", „…(Selbstauskunft/Nac") | G6 | niedrig | Spaltentext vervollständigen | RACI-Schrittbezeichnungen ausschreiben | VA-10 |
|
||||
| **R-1..R-11** | R01/R04/R05/R08/R10/R11 | div. | — | **Rendering-Doppelartikel** „im {{TOOL_TICKET/TOOL_NAME/TOOL_IAM}}" → „im **das** …" | G6 | mittel | Präposition anpassen (siehe §6) | „… dokumentiert **im Ticketsystem ({{TOOL_TICKET}})** …" bzw. „… **im {{TOOL_TICKET}}**" → „… **in {{TOOL_TICKET}}**"-Muster entschärfen | §6 |
|
||||
|
||||
---
|
||||
|
||||
## 5. Empfohlene neue VAs / Register
|
||||
|
||||
### 5.1 Neue Verfahrensanweisungen
|
||||
|
||||
| ID | Titel | Zweck | Betroffene Controls | Priorität |
|
||||
|----|-------|-------|---------------------|-----------|
|
||||
| **VA-19** *(NEU, Miss #1)* | **Informationssicherheit in Projekten** | Projektklassifizierung nach dokumentiertem Kriterienkatalog; Risikobewertung in früher Phase & bei Änderungen; Maßnahmenableitung/-verfolgung; Pflege des Projektregisters; ISB-Einbindung bei erhöhtem Schutzbedarf | 1.2.3 (M1, S1–S3, H1) | **hoch** |
|
||||
| **VA-14** | Personalsicherheit – Eignungsprüfung & sensible Tätigkeiten | Definition sensibler Bereiche; Einstellungs-/Verifizierungsprozess (Identität, Referenzen, Führungszeugnis im rechtlich zulässigen Rahmen); Umgang mit Verstößen gegen IS-/Vertraulichkeitspflichten | 2.1.1 (M1–M3, S1–S2), 2.1.2 | **hoch** |
|
||||
| **VA-15** | Interne Audits & Complianceprüfungen | Auditprogramm, -planung, Durchführung, Berichterstattung, Maßnahmenverfolgung; unabhängige Überprüfung | 1.5.1 (M1–M5, S1), 1.5.2 (M1–M2, S1) | mittel |
|
||||
| **VA-16** | Sichere Beschaffung, Entwicklung & Abnahme | Sicherheitsanforderungen in Design/Beschaffung/Änderung; Abnahmetests; (bei Eigenentwicklung) Secure-Coding/SAST/Dependency-Scan; Testdaten-Handling | 5.3.1 (M1–M4, S1–S5, V1), 5.3.2 | mittel |
|
||||
| **VA-17** *(optional)* | Zutritts- & Besuchermanagement (physisch) | Vergabe/Entzug Zutrittsrechte, Besucherregistrierung/-begleitung, Umgang mit Betriebsmitteln | 3.1.1 (S1–S5), 3.1.3 | niedrig |
|
||||
| **VA-18** *(optional)* | Datenschutz- & Compliance-Pflege | Rechtsregister-Review, Löschfristen/Löschkonzept, Betroffenenrechte, VVT-Pflege | 7.1.1, 7.1.2 | niedrig |
|
||||
|
||||
### 5.2 Neue / zu formalisierende Register
|
||||
|
||||
| Register-ID | Inhalt / Pflichtattribute | Cross-Link | Ersetzt heutige Formulierung in | Priorität |
|
||||
|-------------|---------------------------|-----------|----------------------------------|-----------|
|
||||
| **REG-SW-WHITELIST** *(Miss #3)* | Software, Version/Patch-Stand, **Quelle/Lieferant/Dienstleister**, Freigabestatus, Freigeber/Verantwortlich, Review-Datum | **R13/VA-10** (Lieferant steuerbar) **+ R02/VA-08** (als Asset geführt) | R02 1.3.4 („Liste zugelassener Software") | mittel |
|
||||
| **REG-EXT-SERVICES** *(Miss #3 analog)* | Externe/Cloud/KI-Dienste: Schutzbedarf, Datenlokation (EU), Verschlüsselung, Exit-Strategie, **Quelle/Lieferant**, Freigabestatus, Freigeber | **R13/VA-10 + R02/VA-08** | R02 1.3.3; R12 5.3.4 / 5.3.4-KI; R13 6.1.3 | mittel |
|
||||
| **REG-SENS-ROLES** | Sensible Tätigkeitsbereiche/Rollen, geforderte Eignungsnachweise, Prüftiefe | R05/VA-14 | R05 2.1.1 | **hoch** |
|
||||
| **REG-PROJECTS** *(NEU, Miss #1)* | Projekte, IS-Klassifizierung, Risikobewertung, abgeleitete Maßnahmen/Status, ISB-Einbindung | R01/VA-19 | R01 1.2.3 | **hoch** |
|
||||
| **REG-CRIT-SERVICES** | Kritische IT-Dienste, BIA-Einstufung, RTO/RPO, Abhängigkeiten, Wiederanlaufreihenfolge | R04/VA-02 | R04 5.2.8; R13 6.1.3 | mittel |
|
||||
| **REG-NET** | Netzplan/Segmentierung, Netzdienste, Zonen, Review-Turnus | R09/R10, VA-07 | R09 5.1.2; R10 5.2.7 | niedrig |
|
||||
| **REG-AUDIT-PLAN** | Auditprogramm: Zeitplan, Umfang, geprüfte Controls, Prüfer, Ergebnisse | R03/VA-15 | R03 1.5.1 (S1) | mittel |
|
||||
|
||||
> Mehrere „Register" existieren heute implizit als Datensätze im ISMS-Tool. Empfehlung: als **benannte, verwaltete Register mit Register-ID** führen und über `{{LINK:REG-…}}` konsistent referenzieren (analog zur Baseline-/VA-Mechanik). Dazu Link-Auflösungstabelle (Integrationsleitfaden §6) und ggf. `variables.schema.json` um die neuen Ziele erweitern.
|
||||
|
||||
### 5.3 Ergänzung Baseline
|
||||
|
||||
| BL-ID | Parameter | Vorschlag |
|
||||
|-------|-----------|-----------|
|
||||
| **BL-GOV-01** | Audit-/Prüfzyklus | Interne Prüfung {{REVIEW_CYCLE}}; unabhängige Prüfung/Assessment mind. alle 3 Jahre bzw. nach grundlegenden Änderungen |
|
||||
| **BL-IR-01** | Krisen-/Notfallübungen | Tabletop {{REVIEW_CYCLE}} (HOCH); Vollübung mit Entscheidungsträgern (SEHR HOCH) |
|
||||
| **BL-PROJ-01** | Projekt-Klassifizierungskriterien | Dokumentierter Kriterienkatalog zur IS-Klassifizierung von Projekten (Auslöser/Schwellen für ISB-Einbindung) |
|
||||
|
||||
---
|
||||
|
||||
## 6. Konsistenz-/Rendering-Befunde (G6)
|
||||
|
||||
**Ursache:** Mehrere Variablen-Defaults beginnen bereits mit einem Artikel: `{{TOOL_TICKET}}`=„das Ticketsystem", `{{TOOL_NAME}}`=„das ISMS-Tool", `{{TOOL_IAM}}`=„das zentrale Verzeichnis (Entra ID / Active Directory)", `{{TECH_MDM}}`=„das eingesetzte MDM", `{{TECH_MFA}}`=„die eingesetzte MFA-Lösung" usw. Steht davor eine kontrahierte Präposition („im", „in"), entsteht beim Rendern ein **Doppelartikel** („im **das** Ticketsystem") bzw. ein Kasus-Fehler.
|
||||
|
||||
**Konkrete Fundstellen (Datei : Zeile — Control):**
|
||||
|
||||
| # | Fundstelle | Muster (rendert zu) | Control |
|
||||
|---|-----------|----------------------|---------|
|
||||
| R-1 | R01_ISMS-Organisation-und-Rollen.md:110 | „im {{TOOL_TICKET}}" → „im **das** Ticketsystem" (**2×** in der Zeile) | 1.2.3 |
|
||||
| R-2 | R04_Incident-…:69 | „im {{TOOL_TICKET}} **bzw. ISMS-Tool**" (Doppelartikel **+** doppeldeutiger Ort G2) | 1.6.1 |
|
||||
| R-3 | R04_Incident-…:126 | „im {{TOOL_TICKET}}" → „im **das** Ticketsystem" | 1.6.2 |
|
||||
| R-4 | R05_Personalsicherheit-…:111 | „im {{TOOL_NAME}}" → „im **das** ISMS-Tool" | 2.1.3 |
|
||||
| R-5 | R08_Identitaets-…:45 | „im {{TOOL_TICKET}}" → „im **das** Ticketsystem" | 4.1.1 |
|
||||
| R-6 | R08_Identitaets-…:153 | „**in** {{TOOL_IAM}}" → „in **das** zentrale Verzeichnis …" (Doppelartikel **+** Kasus: müsste „im zentralen Verzeichnis") | 4.1.3 |
|
||||
| R-7 | R08_Identitaets-…:199 | „im {{TOOL_TICKET}}" → „im **das** Ticketsystem" | 4.2.1 |
|
||||
| R-8 | R10_Betriebssicherheit.md:57 | „im {{TOOL_TICKET}}" → „im **das** Ticketsystem" | 5.2.1 |
|
||||
| R-9 | R10_Betriebssicherheit.md:203 | „im {{TOOL_TICKET}}" → „im **das** Ticketsystem" | 5.2.5 |
|
||||
| R-10 | R11_Sichere-Systembeschaffung-…:67 | „im {{TOOL_TICKET}}" → „im **das** Ticketsystem" | 5.3.1 |
|
||||
| R-11 | R01_…:110 (2. Vorkommen) | „als Aufgaben im {{TOOL_TICKET}} nachgehalten" → „im **das** …" | 1.2.3 |
|
||||
|
||||
> **Zusätzlich doppeldeutig verortet (G2, „… bzw. ISMS-Tool"):** R01:110 („im {{TOOL_TICKET}} **bzw. ISMS-Tool**") und R04:69 („Formular im {{TOOL_TICKET}} **bzw. ISMS-Tool**"). Diese Stellen brechen den Grundsatz „ein Nachweisort je Sachverhalt" und sind Auslöser der Herabstufung von 1.2.3 (und Mitgrund bei 1.6.1).
|
||||
>
|
||||
> **Grammatikalisch unkritisch** (kein Fix nötig) sind Vorkommen ohne kontrahierte Präposition, z. B. „über {{TOOL_IAM}}", „und {{TOOL_TICKET}}", „{{TOOL_TICKET}}-Aufträge" — hier passt der eingebettete Artikel bzw. es entsteht keine Doppelung.
|
||||
|
||||
**Empfohlener Fix (zwei Varianten):**
|
||||
- **Variante A (Text):** Präpositionsmuster „im {{VAR}}" → „**in {{VAR}}**" bzw. Artikel explizit ausschreiben: „**im Ticketsystem ({{TOOL_TICKET}})**". Bei R08:153 zusätzlich Kasus/Präposition „**im** {{TOOL_IAM}}" verwenden.
|
||||
- **Variante B (Daten):** Variablen-Defaults ohne führenden Artikel definieren (`{{TOOL_TICKET}}`=„Ticketsystem") und Artikel im Fließtext setzen. **Achtung:** wirkt global auf alle Fundstellen; nur konsistent umsetzen.
|
||||
|
||||
---
|
||||
|
||||
## 7. Priorisierte Roadmap
|
||||
|
||||
**Priorität 1 — Inhalts-GAPs & Fehleinstufungen mit hoher Auditrelevanz:**
|
||||
1. **N1 / VA-19 / REG-PROJECTS** — R01 1.2.3 Informationssicherheit in Projekten: VA anlegen, Kriterienkatalog (BL-PROJ-01) + Projektregister formalisieren, eindeutigen Ort setzen, Rendering fixen. *(Miss #1)*
|
||||
2. **G-B1 / VA-14 / REG-SENS-ROLES** — R05 2.1.1 Personalsicherheit konkretisieren.
|
||||
3. **G-B2** — R07 3.1.3 leeren Anforderungsblock beheben; ISA-Scope 3.1.2/3.1.3 klären; Mapping ergänzen oder Stub entfernen.
|
||||
|
||||
**Priorität 2 — Nachweiskette & Konsistenz (geringer Aufwand, hoher Nutzen):**
|
||||
4. **F3–F9, F19, N4, N7, N9** — Inline-Verlinkung der Verfahren in den 15 Umsetzungstexten vereinheitlichen (VA-01/02/03/04/06/07/08/09/10/12).
|
||||
5. **§6 / R-1..R-11** — Rendering-Doppelartikel `{{TOOL_TICKET}}` u. ä. beheben; doppeldeutige Orte („bzw. ISMS-Tool") auflösen. *(Miss #2)*
|
||||
6. **F17** — `mapping.json` ↔ Integrationsleitfaden abgleichen (`implementation`-Feld ergänzen oder Leitfaden korrigieren).
|
||||
|
||||
**Priorität 3 — Register formalisieren (Reifegrad):**
|
||||
7. **F10/F11/N5/N6/N7 / REG-SW-WHITELIST, REG-EXT-SERVICES, REG-CRIT-SERVICES, REG-NET** — verwaltete Register mit Pflichtattributen + `{{LINK:REG-…}}`; **REG-SW-WHITELIST/REG-EXT-SERVICES mit Lieferant- UND Asset-Kopplung**. *(Miss #3)*
|
||||
8. **F12 / VA-15 / REG-AUDIT-PLAN / BL-GOV-01** und **F13 / VA-16** — Audit- und Secure-Development-Verfahren.
|
||||
|
||||
**Priorität 4 — Feinschliff:**
|
||||
9. **N2, N3, N8, F14, F16, F18, F21** — Verstoß-Verfahren verorten; VA-17/VA-18 (optional); Netz-/mobile-Regelung verorten; SEHR-HOCH-`{{#if}}`-Trennung; VA-10 RACI-Text.
|
||||
|
||||
---
|
||||
|
||||
## 8. Anhang: Einfügefertige Textvorschläge
|
||||
|
||||
Alle Vorschläge im bestehenden Stil (Variablen `{{…}}`, Baseline-/VA-/Register-Verweise), **nicht** eingepflegt.
|
||||
|
||||
### A-N1 — R01 §3.3 (ISA 1.2.3), IMPL 1.2.3 (Ersatztext, Miss #1)
|
||||
|
||||
> Projekte werden zu Beginn anhand des **dokumentierten Kriterienkatalogs (BL-PROJ-01)** hinsichtlich Informationssicherheitsbedarf klassifiziert; Einstufung, Risikobewertung und abgeleitete Maßnahmen werden im **Projektregister ({{LINK:REG-PROJECTS}})** geführt. In einer frühen Projektphase und bei Änderungen erfolgt eine Risikobewertung nach dem **Verfahren Informationssicherheit in Projekten ({{LINK:VA-19}})**; Maßnahmen werden als Aufgaben **in {{TOOL_TICKET}}** nachgehalten und vor Projektabschluss geprüft. Verantwortlich ist die Projektleitung; bei erhöhtem Schutzbedarf wird {{ROLE_ISB}} eingebunden.
|
||||
|
||||
*Ergänzung Abschnitt 8 „Verwandte Dokumente" von R01:* `- Zugehörige Verfahren: {{LINK:VA-19}}; Register: {{LINK:REG-PROJECTS}}`
|
||||
|
||||
*Hinweis:* Damit entfällt die doppeldeutige Verortung („{{TOOL_TICKET}} bzw. ISMS-Tool"), der Kriterienkatalog wird als Baseline-Artefakt (BL-PROJ-01) geführt, und die fehlende VA/das fehlende Register werden geschlossen.
|
||||
|
||||
### A-G-B1 — R05 3.1 (ISA 2.1.1), IMPL 2.1.1 (Ersatztext)
|
||||
|
||||
> Sensible Arbeitsbereiche und Tätigkeiten sind im **Register sensibler Tätigkeiten ({{LINK:REG-SENS-ROLES}})** bestimmt und mit der geforderten Prüftiefe hinterlegt; Anforderungen an Positionen sind in Stellenbeschreibungen dokumentiert und werden erfüllt. Identitätsverifizierung sowie die persönliche und – bei sensiblen Rollen – erweiterte Eignungsprüfung (Gespräch, Referenzen, Führungszeugnis im rechtlich zulässigen Rahmen) erfolgen nach dem **Eignungs- und Verifizierungsverfahren ({{LINK:VA-14}})**; Verantwortlich: {{ROLE_HR_LEAD}}; Nachweis in der Personalakte.
|
||||
|
||||
### A-G-B2 — R07 3.2 (ISA 3.1.3) Anforderungsblock (heute leer)
|
||||
|
||||
**(a) Falls 3.1.3 im ISA-Scope ist** — Anforderungstext + Anker ergänzen und `mapping.json`-Einträge nachziehen:
|
||||
> `<!-- REQ 3.1.3-M1 -->`
|
||||
> - **[MUSS]** Der Umgang mit unterstützenden Betriebsmitteln (z. B. Verkabelung, Strom-/Klimaversorgung, Serverräume) ist bestimmt; Schutz gegen Ausfall, Wartung und Überwachung sind geregelt.
|
||||
|
||||
**(b) Falls 3.1.3 nicht im Scope ist** — Abschnitt 3.2 samt IMPL-Stub entfernen, damit kein Umsetzungstext ohne zugehörige Anforderung/Mapping verbleibt.
|
||||
|
||||
In beiden Fällen: Klären, ob **ISA 3.1.2** bewusst ausgelassen ist (fehlt in R07 und `mapping.json`) und dokumentieren.
|
||||
|
||||
### A-N3 — R02 3.4 (ISA 1.3.4), IMPL 1.3.4 (REG-SW-WHITELIST, Miss #3)
|
||||
|
||||
> Software (inkl. Spezial-/Wartungssoftware) wird vor Einsatz freigegeben. Zugelassene Software wird im **Register Software-Whitelist ({{LINK:REG-SW-WHITELIST}})** mit Version/Patch-Stand, **Quelle/Lieferant**, Freigabestatus und Freigeber geführt; jeder Eintrag ist mit dem verantwortlichen **Lieferanten ({{LINK:VA-10}} / {{LINK:R13}})** und – als verwaltetes Asset – mit dem **Asset-Inventar ({{LINK:VA-08}} / {{LINK:R02}})** verknüpft. Beschaffung/Freigabe läuft über {{TOOL_TICKET}}; Repositorys sind gegen Manipulation geschützt; Verantwortlich: {{ROLE_IT_LEAD}}; Review {{REVIEW_CYCLE}}.
|
||||
|
||||
### A-N6 — R12 3.1 (ISA 5.3.4 / 5.3.4-KI), IMPL (REG-EXT-SERVICES)
|
||||
|
||||
> … Cloud-/KI-Dienste werden vor Nutzung bewertet (Schutzbedarf, Datenlokation/EU, Verschlüsselung, Exit) und von {{ROLE_ISB}} freigegeben; Freigaben werden im **Register externe IT-/Cloud-/KI-Dienste ({{LINK:REG-EXT-SERVICES}})** mit Schutzbedarf, Datenlokation, **Quelle/Lieferant**, Freigabestatus und Freigeber geführt und mit **Lieferantensteuerung ({{LINK:VA-10}})** sowie **Asset-Inventar ({{LINK:VA-08}})** verknüpft (Ablauf siehe {{LINK:VA-11}}); die ausschließliche Nutzung freigegebener Dienste wird {{REVIEW_CYCLE}} geprüft.
|
||||
|
||||
### A-N8 — R14 (ISA 7.1.2), IMPL 7.1.2 (Datenschutz-Pflege-VA)
|
||||
|
||||
> … das Verzeichnis der Verarbeitungstätigkeiten wird im ISMS-Tool ({{TOOL_NAME}}) geführt, TOM und Löschkonzepte (BL-DEL-01) sind geregelt; Rechtsregister-Review, Löschfristen und Betroffenenrechte werden nach dem **Datenschutz-/Compliance-Pflegeverfahren ({{LINK:VA-18}})** bearbeitet; Verantwortlich: {{ROLE_DPO}}.
|
||||
|
||||
### A-F12 — R03 3.2 (ISA 1.5.1), IMPL 1.5.1 (VA-/Register-Verweis)
|
||||
|
||||
> Die Einhaltung von Richtlinien, Verfahren und technischen Anforderungen wird organisationsweit nach dem **Audit-Programm ({{LINK:REG-AUDIT-PLAN}})** und dem **Audit-/Complianceprüfungs-Verfahren ({{LINK:VA-15}})** durch interne Audits und Kontrollen regelmäßig überprüft (Turnus BL-GOV-01); Ergebnisse werden aufgezeichnet und aufbewahrt, Abweichungen als Maßnahmen im {{TOOL_NAME}} nachverfolgt; Verantwortlich: {{ROLE_ISB}}.
|
||||
|
||||
### A-F13 — R11 3.1 (ISA 5.3.1), IMPL 5.3.1 (VA-Verweis)
|
||||
|
||||
> Informationssicherheitsanforderungen sind fester Bestandteil von Design, Beschaffung, Erweiterung und Änderung von IT-Diensten (Security by Design); Anforderungsspezifikation, Prüfung und Abnahmetests unter Sicherheitsaspekten erfolgen nach dem **Verfahren Sichere Beschaffung/Entwicklung & Abnahme ({{LINK:VA-16}})**; Produktivsetzung erst nach Prüfung **in {{TOOL_TICKET}}**. Produktivdaten in Tests werden vermieden/anonymisiert, Testsysteme angemessen geschützt.{{#if FLAG_DEV_INHOUSE}} Für die Eigenentwicklung gelten Secure-Coding-Vorgaben mit Code-Reviews und automatisierten Sicherheitstests (SAST/Dependency-Scan) gemäß {{LINK:VA-16}}.{{/if}}
|
||||
|
||||
### A-F17 — `mapping.json` / Integrationsleitfaden
|
||||
|
||||
**Variante 1 (Daten an Leitfaden angleichen):** je Anforderung ein Feld `implementation` mit dem gebündelten Umsetzungstext (bzw. eindeutiger Kennung des Control-IMPL-Blocks) aufnehmen, damit der Assessment-Export (§8, „Implementation description") direkt aus `mapping.json` speisbar ist.
|
||||
|
||||
**Variante 2 (Leitfaden an Daten angleichen, geringerer Aufwand):** In §5/§8 dokumentieren, dass `implementation` **nicht** in `mapping.json` liegt, sondern zur Laufzeit über `impl_anchor` (control-gebündelter Anker `IMPL <control>`) aus der jeweiligen `.md` aufgelöst wird. **Zusätzlich klären:** Für Control **1.1.1** ist `impl_anchor == req_anchor` (kein `IMPL 1.1.1`-Block; Leitlinien-Prosa) — diese Sonderauflösung im Leitfaden explizit ausweisen.
|
||||
|
||||
### A-F18 — Trennung SEHR-HOCH in `-elev`-Blöcken (Muster)
|
||||
|
||||
Statt eines gemeinsamen `{{#if FLAG_ELEVATED_PROTECTION}}`-Blocks, der HOCH- und SEHR-HOCH-Sätze mischt:
|
||||
|
||||
> `{{#if FLAG_HIGH_PROTECTION}}` … HOCH-Umsetzungssätze … `{{/if}}`
|
||||
> `{{#if FLAG_VERY_HIGH_PROTECTION}}` … „Bei sehr hohem Schutzbedarf …" … `{{/if}}`
|
||||
|
||||
So erscheint der SEHR-HOCH-Umsetzungstext nur, wenn auch die zugehörigen `[SEHR HOCH]`-Anforderungen im Set sind (betrifft u. a. IMPL 1.2.2-elev, 1.6.2-elev, 1.6.3-elev, 4.1.2-elev, 4.2.1-elev, 5.1.2-elev, 5.2.4-elev, 5.2.6-elev, 5.2.9-elev, 6.1.1-elev).
|
||||
|
||||
---
|
||||
|
||||
## 9. Positiv-Befunde (zur Absicherung, kein Handlungsbedarf)
|
||||
|
||||
- **Baseline-Disziplin:** konkrete Werte durchgängig in `Technische-Sicherheits-Baseline.md` zentralisiert (31 BL-IDs); Umsetzungstexte referenzieren korrekt (z. B. R08 4.1.2 → BL-IAM-01/02, R10 5.2.9 → BL-OPS-05).
|
||||
- **Vorbildliche Referenzketten:** 5.1.1, 5.2.4, 5.2.8, 5.2.9, 6.1.1 verbinden IMPL ↔ VA ↔ Baseline eindeutig — Zielbild für die übrigen Controls.
|
||||
- **Mapping-Integrität:** 316 REQ-Anker ↔ 316 Mapping-IDs, keine Waisen (verifiziert); VA-`FULFILLS`-Header stimmen mit `mapping.json → verfahren` überein.
|
||||
- **Schutzbedarf:** `-elev`-Abdeckung für alle Controls mit HOCH/SEHR-HOCH-Anforderungen vorhanden (Trennungs-Feinschliff siehe F18).
|
||||
- **KI-/GenAI-Ergänzung (R12 3.2)** inhaltlich stark und aktuell (Datenklassen je Dienst, kein Training auf Eingaben, Human-in-the-Loop, EU AI Act) — die Herabstufung von 5.3.4-KI betrifft ausschließlich die Register-Formalisierung, nicht den Sachinhalt.
|
||||
@@ -0,0 +1,78 @@
|
||||
# Umsetzungspaket — Sicherheit & Administration (1 Entwickler)
|
||||
|
||||
> Claude-Code-Prompt. Basis-Branch **`dev`**; je Story ein Feature-Branch `dev/sec<n>-…` (PR-Ziel `dev`). Grundlage: `Sicherheit-und-Administration-Konzept.md` + Ist-Stand `STAND-dev-branch.md`.
|
||||
> **Entscheidungen (fix):** Mail via **SMTP** · **1 Entwickler** (sequenziell) · **2FA bleibt optional**, aber **pro Tenant im Adminportal als Pflicht** einstellbar · **Passkeys** dabei · **DSGVO-Funktionen** dabei.
|
||||
|
||||
## Vorhandenes wiederverwenden (nicht neu bauen)
|
||||
- **MFA-Kern** (TOTP + Recovery-Codes) für Plattform- und Mandanten-Nutzer: `src/server/mfa.ts`; Policy-Flag `securityPolicy.mfaRequired` existiert.
|
||||
- **Passwort**: `src/lib/password-policy.ts` (Validierung) + `src/server/password.ts` (Argon2id + Generator); **Force-Change**-Gate im `(app)`-Layout.
|
||||
- **Auth**: zwei NextAuth-Instanzen — Mandant `src/server/auth.ts` (`/login`), Plattform `src/server/platform-auth.ts` (`/platform/login`). **`PlatformAdmin`**-Store getrennt.
|
||||
- **Queue**: BullMQ + Redis im Stack. **Audit-Log** mit `tenantId` nullable (`scope=platform`). **Task/TaskComment** für Ticket-/Freigabe-Ereignisse.
|
||||
- **Modul-Guard**: neue Server-Actions in `scripts/check-module-guards.ts` eintragen; tenant-Modelle in `TENANT_MODELS`+RLS.
|
||||
|
||||
## Betriebs-/DNS-Voraussetzungen (kein Code, aber Vorbedingung)
|
||||
Dedizierte Absenderdomain (`no-reply@certvia.de`) mit **SPF, DKIM, DMARC**; TLS/HSTS; SMTP-Zugangsdaten + alle Secrets aus **Env/Secret-Store** (nicht im Repo).
|
||||
|
||||
---
|
||||
|
||||
## Reihenfolge (sequenziell, 1 Entwickler)
|
||||
SEC1 → SEC2 → SEC3 → SEC4 → SEC5 → SEC6. Einzelne P0-Härtungen (Rate-Limit an Login/Reset/MFA, Token-Hashing) landen **inline** in SEC2/SEC3; die globalen Härtungen bündelt SEC5.
|
||||
|
||||
---
|
||||
|
||||
## SEC1 — SMTP-Mail-Fundament (`dev/sec1-mail-smtp`) [L]
|
||||
**Ziel:** zuverlässiger, gebrandeter, asynchroner Mail-Versand als Fundament für Reset/Einladung/Benachrichtigung.
|
||||
- **Mail-Service** `src/server/mail/**` mit **SMTP-Transport** (nodemailer, TLS) hinter einem Interface `sendMail(template, to, vars, locale)` — Provider später austauschbar.
|
||||
- **Queue/Worker** über BullMQ/Redis: asynchron, **Retry mit Backoff**, Dead-Letter, Rate-Limit; Fehler/Bounce ins Log.
|
||||
- **Templates** (Certvia-gebrandet, **de/en**, HTML + Text-Alternative): Einladung, Passwort-Reset, „Passwort geändert", E-Mail-Änderung bestätigen, „MFA geändert", **Ticket-/Freigabe-/Fristen-Benachrichtigung**.
|
||||
- **Benachrichtigungsregeln**: je Nutzer/Ereignis opt-in/opt-out + Sprache; strikt mandantengetrennt. Trigger aus Task-Ereignissen (Zuweisung, Freigabe-Anfrage, Entscheidung, Fälligkeit).
|
||||
- **Admin-Testversand** (eine Aktion „Test-Mail senden") zur Zustellprüfung.
|
||||
- **AK:** Mail wird asynchron mit Retry versendet; Templates gebrandet + zweisprachig; Bounces/Fehler geloggt; Ticket-Benachrichtigung wird bei Task-Zuweisung/Freigabe ausgelöst; keine Secrets im Repo.
|
||||
|
||||
## SEC2 — Passwort-Self-Service & Sessions (`dev/sec2-auth-selfservice`) [M–L] · Abh. SEC1
|
||||
- **Passwort-Reset**: „Passwort vergessen" → **Single-Use-Token**, kurzlebig (30–60 Min), **serverseitig gehasht** gespeichert, an E-Mail gebunden. **Enumeration-Schutz** (immer gleiche Antwort), **Rate-Limit** je IP/Konto. Nach Reset: **alle Sessions invalidieren** + Bestätigungs-Mail + Audit; deaktivierte/gesperrte Konten erhalten keinen Reset.
|
||||
- **Passwort selbst ändern**: Profilseite mit **Alt-Passwort-Bestätigung**, Policy-Prüfung, danach **andere Sessions abmelden** (aktuelle behalten), Bestätigungs-Mail + Audit.
|
||||
- **E-Mail-Änderung**: **Double-Opt-in** an neue Adresse + Benachrichtigung an alte; Audit.
|
||||
- **Session-Invalidierung** als wiederverwendbarer Baustein (bei Reset/Änderung/Deaktivierung/MFA-Änderung).
|
||||
- **AK:** Reset-Token single-use/gehasht/rate-limited/enumeration-safe; Self-Change funktioniert; E-Mail-Änderung verifiziert; Sessions werden korrekt invalidiert; alle Ereignisse im Audit.
|
||||
|
||||
## SEC3 — MFA pro Tenant erzwingen + Passkeys (`dev/sec3-mfa-passkeys`) [L] · Abh. SEC1
|
||||
- **Optional bleibt Default.** Im **Adminportal** kann pro Mandant `securityPolicy.mfaRequired` gesetzt werden (Superadmin) → **Enrollment-Gate**: Nutzer dieses Mandanten werden beim nächsten Login zur MFA-Einrichtung gezwungen (analog Force-Change-Gate im `(app)`-Layout). Ebenso erzwingbar für **alle Plattform-Admins**.
|
||||
- **Passkeys/WebAuthn** als zusätzlicher 2. Faktor (`@simplewebauthn/server` + Browser-API): Registrierung + Login; Nutzer kann **TOTP oder Passkey** verwenden; Credentials verwaltbar (anlegen/entfernen).
|
||||
- **Step-up-Re-Auth** für sensible Aktionen: MFA deaktivieren, Plattform-Admin anlegen, Datenexport, Mandant löschen.
|
||||
- **TOTP-Secret at rest verschlüsselt** (falls noch Klartext) + **Rate-Limit** auf Code-Eingabe; Recovery-Codes-Flow (Anzeige/Regenerierung, Verbrauch protokolliert) abrunden.
|
||||
- **AK:** Admin setzt `mfaRequired` je Tenant → betroffene Nutzer müssen beim Login enrollen; Passkey-Registrierung + -Login funktionieren; Step-up greift bei sensiblen Aktionen; TOTP-Secret verschlüsselt; MFA global weiterhin optional, wenn Policy es nicht verlangt.
|
||||
|
||||
## SEC4 — Plattform-Admin-Verwaltung (`dev/sec4-platform-admins`) [M] · Abh. SEC1, SEC3
|
||||
- **Verwaltungs-UI** im Adminportal (`src/app/(platform)/admin/**`, Actions `platform*.ts`): weitere **`PlatformAdmin`** anlegen (Einladung via SEC1 oder Initial-Passwort), **Rollen** (z. B. „Voll-Admin" vs. „Support/Read-only"), **sperren/reaktivieren**, Passwort-Reset, **MFA-Pflicht** für Plattform-Admins.
|
||||
- **Selbst-Aussperr-Schutz** auf Plattform-Ebene (letzter Voll-Admin nicht entfernbar/deaktivierbar); kritische Aktionen mit **Step-up** (SEC3).
|
||||
- **Vollständiges Plattform-Audit** (`scope=platform`) jeder Aktion.
|
||||
- **AK:** ein zweiter Voll-Admin ist anlegbar und kann verwalten; Rollen greifen (Read-only kann nichts ändern); Last-Admin-Schutz aktiv; jede Aktion protokolliert.
|
||||
|
||||
## SEC5 — Härtung P0 (quer) (`dev/sec5-hardening`) [M]
|
||||
- **HTTP-Security-Header** (zentrale Middleware): CSP, HSTS, `X-Frame-Options`/`frame-ancestors`, `X-Content-Type-Options`, `Referrer-Policy`, `Permissions-Policy`.
|
||||
- **Rate-Limiting/Brute-Force** global an Login/Reset/MFA/Admin-Aktionen (IP **und** kontobezogen), ergänzt den bestehenden Konto-Lockout.
|
||||
- **Security-Audit erweitern**: Logins (Erfolg/Fehlschlag), Rechte-/Rollenänderungen, MFA-Änderungen, Exporte, Admin-Aktionen; **append-only**/manipulationssicher; Aufbewahrung definiert.
|
||||
- **Passwort-Breach-Check** (HaveIBeenPwned k-Anonymity) beim Setzen/Ändern zusätzlich zur Policy.
|
||||
- **Token-/Secret-Hygiene**: alle Tokens single-use + gehasht (Konsistenz zu SEC2/SEC3); **Secret-Scanning** in CI.
|
||||
- **AK:** Header messbar gesetzt (z. B. securityheaders-Check); Rate-Limits greifen; Audit-Ereignisse vorhanden; bekannte kompromittierte Passwörter werden abgelehnt.
|
||||
|
||||
## SEC6 — DSGVO-Funktionen (`dev/sec6-dsgvo`) [L] · Abh. SEC1, SEC3 (Step-up)
|
||||
- **Mandanten-Datenexport** (vollständig, maschinenlesbar, z. B. JSON/ZIP), Admin-getriggert, **asynchron** via Queue, Download-Link mit Ablauf.
|
||||
- **Löschung/Retention**: Mandanten-Löschung (Soft→Hard mit Karenz), **Aufbewahrungsfristen**/Löschkonzept, RLS-bewusste Kaskaden; Audit; Step-up-Bestätigung.
|
||||
- **Betroffenenrechte**: Export/Löschung nutzerbezogener Daten, soweit anwendbar.
|
||||
- **Doku-Bausteine** (Inhalt, kein Code): AVV/DPA + TOMs — als offener fachlicher Punkt markieren.
|
||||
- **AK:** vollständiger Tenant-Export erzeugbar; Löschung respektiert Retention + Audit + Step-up; DSGVO-Aktionen protokolliert.
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done (jede Story)
|
||||
`npx tsc --noEmit` → `npm run lint` → `npm run build` (Guard-Check) grün · neue Actions in `check-module-guards.ts` · neue tenant-Modelle in `TENANT_MODELS`+RLS+Migration (RLS-DO-Block) · Security-Verifikation (Header/Rate-Limit/Token) · Browser-Test der Flows · Demo-Umgebung lauffähig · **Secrets nur aus Env**.
|
||||
|
||||
## Hot Files (koordiniert, da 1 Entwickler → nur Reihenfolge beachten)
|
||||
`prisma/schema.prisma` + Migrationsreihenfolge · zentrale **Middleware** (Header/Rate-Limit) · `(app)`- und `(platform)`-Layouts (Enrollment-/Force-Gates) · `src/server/auth.ts` / `platform-auth.ts` / `mfa.ts` · `scripts/check-module-guards.ts`.
|
||||
|
||||
## Offene fachliche Punkte
|
||||
- DNS: SPF/DKIM/DMARC vor Produktivversand aktiv.
|
||||
- AVV/DPA-Texte + TOMs (Datenschutz/ISB).
|
||||
- Aufbewahrungsfristen je Datenart festlegen (Grundlage für SEC6-Retention).
|
||||
@@ -0,0 +1,19 @@
|
||||
# Sicherheit & Administration — Übergabepaket
|
||||
|
||||
## Inhalt / Reihenfolge
|
||||
1. **Sicherheit-und-Administration-Konzept.md** — PO-Konzept: Ist-Abgleich, Empfehlungen, Roadmap.
|
||||
2. **Aufgabenpaket-Sicherheit-Administration.md** — Ein-Entwickler-Backlog SEC1–SEC6 (Branches `dev/sec<n>-…`).
|
||||
3. **SEC1-Mail-Fundament-Detail.md** — ausgearbeiteter Prompt: SMTP-Mail (Fundament).
|
||||
4. **SEC2-Auth-SelfService-Detail.md** — ausgearbeiteter Prompt: Passwort-Reset, Passwort ändern, E-Mail-Änderung, Session-Invalidierung.
|
||||
|
||||
## Fixierte Entscheidungen
|
||||
- Mail via **SMTP** (nodemailer) im ersten Schritt.
|
||||
- **1 Entwickler**, sequenziell: SEC1 → SEC2 → SEC3 → SEC4 → SEC5 → SEC6.
|
||||
- **2FA optional**, aber pro Tenant im **Adminportal** als Pflicht (`mfaRequired`) erzwingbar; **Passkeys** dabei.
|
||||
- **DSGVO-Funktionen** enthalten.
|
||||
|
||||
## Naht SEC1 ↔ SEC2
|
||||
SEC1 liefert Versand + Templates; **SEC2 erzeugt die Tokens** (single-use, gehasht) und übergibt SEC1 nur die fertige `actionUrl` — keine Klartext-Secrets im MailLog.
|
||||
|
||||
## Start
|
||||
Mit **SEC1** beginnen, dann **SEC2**. DNS-Vorbedingung: SPF/DKIM/DMARC vor Produktivversand. Secrets nur aus Env/Secret-Store.
|
||||
@@ -0,0 +1,125 @@
|
||||
# SEC1 — SMTP-Mail-Fundament (Detail-Prompt)
|
||||
|
||||
> Claude-Code-Prompt für **einen** Entwickler. Basis `dev` → Branch **`dev/sec1-mail-smtp`** (PR-Ziel `dev`).
|
||||
> Ziel: zuverlässiger, gebrandeter, **asynchroner** Mail-Versand über **SMTP** — Fundament für Passwort-Reset (SEC2), Einladung, MFA-Hinweise (SEC3) und Ticket-/Freigabe-/Fristen-Benachrichtigungen. Stack vorhanden: **BullMQ + Redis**, Next.js/TS, Prisma, i18n (de/en), Task/TaskComment, Audit-Log, `TenantSettings`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Architektur (Zielbild)
|
||||
|
||||
```
|
||||
Aufrufer (Action/Event) Worker-Prozess
|
||||
│ enqueueMail({template,to, ┌───────────────────────────┐
|
||||
│ locale,vars,tenantId}) │ BullMQ "mail"-Queue │
|
||||
▼ │ → render(template,locale) │
|
||||
MailService ──push job──► Redis ───────► │ → MailProvider.send() │
|
||||
│ │ → MailLog(status) │
|
||||
└─ MailLog(pending) │ → Retry/Backoff/DLQ │
|
||||
└───────────────────────────┘
|
||||
Provider-Interface ← SMTP-Impl (nodemailer) [später austauschbar]
|
||||
```
|
||||
|
||||
Trennung in vier Schichten: **Provider** (SMTP), **Templates** (Render), **Queue/Worker** (Zustellung + Retry), **Service/Trigger** (Aufruf + Regeln + Log).
|
||||
|
||||
---
|
||||
|
||||
## 2. Datenmodelle (Prisma, mit Migration + RLS)
|
||||
|
||||
- **`MailLog`** (Auditierbarkeit + Idempotenz): `id`, `tenantId` (nullable → Plattform-Mails), `to`, `template`, `locale`, `status` (`pending|sent|failed|bounced|suppressed`), `providerMessageId?`, `error?`, `dedupeKey?` (unique, für Idempotenz), `createdAt`, `sentAt?`. → in `TENANT_MODELS`+RLS (Plattform-Zeilen mit `tenantId=null`, `scope=platform`).
|
||||
- **`NotificationPreference`**: `userId`, `eventType`, `email` (bool, default true), `locale?`. Default = opt-in; UI kommt später — jetzt Modell + Default-Auflösung.
|
||||
- Migrationen im Prisma-7-Flow (RLS-DO-Block manuell anhängen).
|
||||
|
||||
---
|
||||
|
||||
## 3. Konfiguration (Env / Secret-Store — nichts ins Repo)
|
||||
|
||||
`SMTP_HOST`, `SMTP_PORT`, `SMTP_SECURE` (true=TLS/465, false=STARTTLS/587), `SMTP_USER`, `SMTP_PASS`, `MAIL_FROM` (`no-reply@certvia.de`), `MAIL_FROM_NAME` (`Certvia`), `APP_BASE_URL`, `MAIL_REPLY_TO?`.
|
||||
- **Boot-Validierung** (z. B. zod): fehlt Konfig → klarer Fehler, Versand deaktiviert (Jobs bleiben `pending`, Warnung im Log). Kein stiller Fehlversand.
|
||||
|
||||
---
|
||||
|
||||
## 4. Provider & Service
|
||||
|
||||
- **Interface** `src/server/mail/provider.ts`: `send(msg: {from,to,replyTo?,subject,html,text,headers?}): Promise<{messageId}>`. So bleibt der Provider austauschbar (heute SMTP, später API).
|
||||
- **SMTP-Impl** `src/server/mail/provider-smtp.ts`: **nodemailer** (Pool, TLS, Timeouts). Verbindung wiederverwenden.
|
||||
- **Service** `src/server/mail/service.ts`:
|
||||
- `enqueueMail(input)` → `dedupeKey` bilden (z. B. `template:to:refId`), `MailLog(pending)` anlegen (unique verhindert Doppelversand), Job in Queue.
|
||||
- `renderMail(template, locale, vars)` → `{subject, html, text}` (Abschnitt 5).
|
||||
- Action-Datei in `scripts/check-module-guards.ts` als **`EXEMPT`** eintragen (Infrastruktur, kein gegatetes Modul).
|
||||
|
||||
---
|
||||
|
||||
## 5. Templates (gebrandet, de/en, HTML + Text)
|
||||
|
||||
- **Basis-Layout** `src/server/mail/templates/_layout.*`: Certvia-Kopf (Logo/Wortmarke), Markenfarben (Violett `#5d52a3` / Magenta-Akzent `#812d80`), **Inline-CSS** (E-Mail-Client-tauglich; MJML oder handgepflegtes Table-Layout), Fußzeile „**Certvia — ein Produkt von GEFIM**" + Impressum/Abmelde-Hinweis. Immer **Text-Alternative** mitliefern.
|
||||
- **i18n:** je Template `de`/`en` über die bestehenden Message-Kataloge; `locale` aus Nutzer/`NotificationPreference`, Fallback `de`.
|
||||
- **Template-Set (Erststufe):**
|
||||
|
||||
| Template-Key | Anlass | Kern-Variablen | Auslöser |
|
||||
|---|---|---|---|
|
||||
| `invitation` | Nutzer-Onboarding | `name, tenantName, actionUrl, expires` | SEC1/SEC4 (Einladung) |
|
||||
| `password_reset` | Reset angefordert | `name, actionUrl, expires` | **SEC2** (Token wird dort erzeugt) |
|
||||
| `password_changed` | Passwort geändert | `name, when, ip?` | SEC2 |
|
||||
| `email_change_verify` | E-Mail-Änderung bestätigen | `name, actionUrl, expires` | SEC2 |
|
||||
| `mfa_changed` | MFA aktiviert/deaktiviert/Recovery neu | `name, change, when` | SEC3 |
|
||||
| `notification` | Ticket/Freigabe/Fälligkeit | `name, subject, body, actionUrl, taskType` | Task-Events (Abschnitt 6) |
|
||||
|
||||
> **Wichtig:** Reset-/Verify-/Einladungs-**Tokens** werden von SEC2/SEC3/SEC4 erzeugt (single-use, gehasht). SEC1 liefert nur Template + Versand und bekommt die fertige `actionUrl` als Variable — **keine** Klartext-Secrets ins MailLog/Log schreiben.
|
||||
|
||||
---
|
||||
|
||||
## 6. Benachrichtigungs-Trigger (Ticket-/Freigabe-/Fristen)
|
||||
|
||||
- **Task-Ereignisse** (bestehendes `Task`/`TaskComment` + `submitForApproval`): bei **Zuweisung**, **Freigabe-Anfrage**, **Freigabe-Entscheidung** (angenommen/abgelehnt) → `notification`-Mail an den jeweils Zuständigen, sofern `NotificationPreference.email` aktiv.
|
||||
- **Fristen-Erinnerung:** **BullMQ Repeatable Job** (z. B. täglich) prüft fällige/überfällige Aufgaben (`dueDate`) und versendet gebündelte Erinnerungen (keine Spam-Schleifen — je Aufgabe max. definierte Frequenz, `dedupeKey`).
|
||||
- Alle Trigger **mandantenisoliert**; Sprache je Empfänger.
|
||||
|
||||
---
|
||||
|
||||
## 7. Queue / Worker / Robustheit
|
||||
|
||||
- **Queue** `mail` (BullMQ). **Worker** `src/server/mail/worker.ts`: `render → provider.send → MailLog(sent|failed)`.
|
||||
- **Retry:** z. B. 5 Versuche, exponentielles Backoff; nach Ausschöpfung `status=failed` + **Dead-Letter** (separate Queue/Flag) + Alarm-Logeintrag.
|
||||
- **Rate-Limit** je Empfänger/Domain (BullMQ Limiter), **Concurrency** begrenzt, **Graceful Shutdown**.
|
||||
- **Idempotenz:** `dedupeKey`-Unique + „bereits gesendet"-Kurzschluss.
|
||||
- **Betriebsmodus dokumentieren:** Worker als eigener Prozess (Coolify) **oder** im App-Container gestartet — entscheiden und im README festhalten.
|
||||
|
||||
---
|
||||
|
||||
## 8. Sicherheit / Datenschutz
|
||||
|
||||
- **TLS erzwingen** (STARTTLS/implicit), Zertifikatsprüfung an. Secrets nur aus Env/Secret-Store.
|
||||
- **Keine sensiblen Inhalte** in Mails über das Nötige hinaus; **keine Tokens** in Logs/MailLog (nur `dedupeKey`/`providerMessageId`).
|
||||
- **Abmelde-/Präferenz-Hinweis** in Benachrichtigungs-Mails (nicht in sicherheitskritischen Transaktionsmails wie Reset).
|
||||
- **Enumeration-Schutz** ist Sache von SEC2 (Reset) — SEC1 versendet nur, was ihm übergeben wird.
|
||||
- **Audit:** Versandereignisse (ohne Inhalt) ins Security-Audit (Erweiterung in SEC5 kompatibel halten).
|
||||
- **DNS-Vorbedingung:** SPF, DKIM, DMARC für die Absenderdomain (Ops; vor Produktivversand).
|
||||
|
||||
---
|
||||
|
||||
## 9. Admin-Testversand
|
||||
- Aktion „Test-Mail senden" im Adminportal (an eigene Adresse), zeigt Ergebnis/MailLog-Status → schnelle Zustell-/DKIM-Prüfung.
|
||||
|
||||
---
|
||||
|
||||
## 10. Akzeptanzkriterien
|
||||
- `enqueueMail(...)` legt `MailLog(pending)` an und stellt asynchron über SMTP zu; bei Erfolg `sent` + `providerMessageId`, bei Fehler Retry→`failed`/DLQ.
|
||||
- Templates rendern **de und en**, HTML **und** Text, mit Certvia-Branding und „ein Produkt von GEFIM".
|
||||
- **Ticket-Benachrichtigung** wird bei Task-Zuweisung/Freigabe ausgelöst und respektiert `NotificationPreference` + Mandantenisolation.
|
||||
- **Fristen-Erinnerung** läuft als wiederkehrender Job ohne Doppelversand.
|
||||
- Fehlende SMTP-Konfig → klarer Fehler, kein stiller Fehlversand; keine Secrets/Tokens im Repo oder Log.
|
||||
- Lokaler Test gegen **Mailpit/Mailhog** dokumentiert; Admin-Testversand funktioniert.
|
||||
|
||||
## 11. Definition of Done
|
||||
`npx tsc --noEmit` → `npm run lint` → `npm run build` (Guard-Check) grün · Mail-Action als `EXEMPT` registriert · `MailLog`/`NotificationPreference` in `TENANT_MODELS`+RLS+Migration (RLS-DO-Block) · Worker-Betriebsmodus im README · lokaler Mailpit-Testnachweis (Screenshots) · Demo-Umgebung lauffähig.
|
||||
|
||||
## 12. Testplan (Kurz)
|
||||
1. **Lokal Mailpit** (`docker run mailpit`) als SMTP-Ziel; Env setzen; Test-Mail senden → in Mailpit sichtbar (HTML+Text, de/en).
|
||||
2. **Retry:** Provider künstlich fehlschlagen lassen → Job retryt, landet nach N Versuchen in DLQ, `MailLog=failed`.
|
||||
3. **Idempotenz:** zweimal gleicher `dedupeKey` → nur eine Mail.
|
||||
4. **Trigger:** Aufgabe zuweisen / Freigabe anfragen → `notification`-Mail; `NotificationPreference.email=false` → keine Mail.
|
||||
5. **Fristen-Job:** überfällige Aufgabe → genau eine Erinnerung je Zyklus.
|
||||
|
||||
## 13. Bibliotheken
|
||||
`nodemailer` (SMTP) · `bullmq` (vorhanden) · optional `mjml` für Template-Rendering · `zod` (Env-Validierung, i. d. R. vorhanden).
|
||||
Nächste Pakete bauen darauf auf: **SEC2** (Reset/Change nutzen `password_reset`/`password_changed`/`email_change_verify`), **SEC3** (`mfa_changed`), **SEC4** (`invitation`).
|
||||
@@ -0,0 +1,100 @@
|
||||
# SEC2 — Passwort-Reset, Passwort ändern, E-Mail-Änderung & Sessions (Detail-Prompt)
|
||||
|
||||
> Claude-Code-Prompt für **einen** Entwickler. Basis `dev` → Branch **`dev/sec2-auth-selfservice`** (PR-Ziel `dev`). **Abhängigkeit: SEC1** (Mail-Templates `password_reset`, `password_changed`, `email_change_verify`).
|
||||
> Ziel: sicherer **Self-Service** — Passwort vergessen/zurücksetzen, Passwort selbst ändern, E-Mail-Adresse ändern (verifiziert) — plus ein wiederverwendbarer **Session-Invalidierungs-Baustein**. Gilt für **Mandanten-Nutzer** (`/login`) **und Plattform-Admins** (`/platform/login`).
|
||||
|
||||
## Vorhandenes wiederverwenden
|
||||
- `src/lib/password-policy.ts` (Validierung, client-safe) + `src/server/password.ts` (**Argon2id** + Generator). **Nicht** neu implementieren.
|
||||
- Zwei NextAuth-Instanzen: `src/server/auth.ts` (Mandant) · `src/server/platform-auth.ts` (Plattform). **Force-Change-Gate** im `(app)`-Layout als Muster.
|
||||
- Konto-**Lockout** (Tenant) + `User.mustChangePassword` vorhanden. Audit-Log (`scope=platform` für Plattform-Ereignisse). SEC1-Mailservice (`enqueueMail`).
|
||||
|
||||
---
|
||||
|
||||
## 1. Token-Modell (single-use, gehasht)
|
||||
|
||||
**`AuthToken`** (eigenes Modell, nicht im JWT):
|
||||
`id`, `principalType` (`tenant_user` | `platform_admin`), `principalId`, `tenantId?` (nur bei tenant_user, für RLS), `type` (`password_reset` | `email_change`), `tokenHash` (SHA-256 des Rohtokens), `newEmail?` (nur bei email_change), `expiresAt`, `usedAt?`, `createdAt`, `requestIp?`.
|
||||
- **Roh-Token** = 32 Byte CSPRNG, base64url; nur im **Link** (nie in DB/Log). In DB nur der **Hash**. Lookup per Hash, **konstante-Zeit**-Vergleich.
|
||||
- **Gültigkeit** kurz (Reset 30–60 Min, E-Mail-Verify 60 Min); **single-use** (`usedAt` setzen); alte offene Tokens desselben Typs beim Neuanfordern invalidieren.
|
||||
- tenant_user-Zeilen unter RLS (`tenantId`); platform_admin-Zeilen `tenantId=null` (`scope=platform`). Migration + RLS-DO-Block.
|
||||
|
||||
---
|
||||
|
||||
## 2. Passwort-Reset (Self-Service)
|
||||
|
||||
**2a Anfrage** — „Passwort vergessen?" auf `/login` **und** `/platform/login`:
|
||||
- Eingabe E-Mail → **immer gleiche Antwort** („Falls ein Konto existiert, wurde eine E-Mail gesendet."). **Kein** Rückschluss auf Existenz (Enumeration-Schutz).
|
||||
- **Rate-Limit**: je IP **und** je Konto (z. B. 5/Stunde); zusätzlich globaler Missbrauchsschutz.
|
||||
- Existiert das Konto **und** ist aktiv/nicht gesperrt: `AuthToken(password_reset)` erzeugen, Link `"{APP_BASE_URL}/reset?token=…"` per SEC1 (`password_reset`) senden. **Deaktivierte/gesperrte** Konten: keine Mail, keine Fehlermeldung.
|
||||
|
||||
**2b Einlösung** — `/reset?token=…`:
|
||||
- Token per Hash validieren (existiert, nicht abgelaufen, nicht benutzt, Konto aktiv). Ungültig → generische Meldung + Angebot „neu anfordern".
|
||||
- Neues Passwort setzen: **Policy-Prüfung** (`password-policy.ts`) + Argon2id (`password.ts`). Bei Wiederverwendung: **Breach-Check-Hook** vorsehen (Implementierung in SEC5).
|
||||
- Danach: `usedAt` setzen, **alle Sessions invalidieren** (Abschnitt 5), `mustChangePassword=false`, **Bestätigungs-Mail** (`password_changed`), **Audit**-Eintrag (ohne Token).
|
||||
- Redirect zum passenden Login (`/login` bzw. `/platform/login`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Passwort selbst ändern
|
||||
|
||||
Profilseite (Mandanten-App **und** Plattform-Profil):
|
||||
- Felder: aktuelles Passwort, neues, Wiederholung. **Alt-Passwort verifizieren** (Argon2id), Policy-Prüfung.
|
||||
- Erfolg: Passwort setzen, **andere Sessions abmelden** (aktuelle behalten — Abschnitt 5), Bestätigungs-Mail (`password_changed`), Audit.
|
||||
- Fehler generisch; Rate-Limit auf Alt-Passwort-Versuche.
|
||||
|
||||
---
|
||||
|
||||
## 4. E-Mail-Adresse ändern (verifiziert, Double-Opt-in)
|
||||
|
||||
- Nutzer gibt neue Adresse ein → **Alt-Passwort bestätigen** (Step-up folgt in SEC3). Prüfen, dass die neue Adresse **frei** ist (mandantenweit bzw. plattformweit), ohne Enumeration nach außen.
|
||||
- `AuthToken(email_change, newEmail)` erzeugen; **Verifizierungslink an die NEUE Adresse** (`email_change_verify`).
|
||||
- Klick auf Link: Token validieren → E-Mail aktualisieren, `usedAt` setzen; **Benachrichtigung an die ALTE Adresse** („Ihre E-Mail wurde geändert"); Audit. Login-Identität konsistent halten (E-Mail ist Login).
|
||||
- Kollisionsfall (Adresse zwischenzeitlich vergeben): sauber ablehnen.
|
||||
|
||||
---
|
||||
|
||||
## 5. Session-Invalidierung (wiederverwendbarer Baustein)
|
||||
|
||||
NextAuth v5 nutzt **JWT (stateless)** → globale Invalidierung über eine **Versionsmarke**:
|
||||
- Feld **`sessionsValidAfter`** (Timestamp) bzw. `tokenVersion` an `User` **und** `PlatformAdmin`.
|
||||
- JWT trägt `iat`/Version; im **Auth-Callback bzw. Layout-Check** (die DB wird ohnehin schon für Kontostatus/`mustChangePassword` geprüft) zusätzlich `sessionsValidAfter` vergleichen → ältere Tokens sind ungültig → Abmeldung.
|
||||
- **Bump-Auslöser:** Passwort-Reset (2b), Passwort ändern (3, andere Sessions), Konto-Deaktivierung, MFA-Änderung (SEC3), E-Mail-Änderung.
|
||||
- **„Aktuelle Session behalten"** (bei Self-Change): nach Bump das **aktuelle** JWT mit neuer Version neu ausstellen.
|
||||
- **AK:** ein Bump macht bestehende Sessions serverseitig ungültig; Self-Change meldet **nur** die anderen ab.
|
||||
- *Optionaler Folgeschritt (nicht SEC2-Pflicht):* „aktive Sitzungen anzeigen + einzeln abmelden" braucht Session-Records — als P1 vermerken.
|
||||
|
||||
---
|
||||
|
||||
## 6. Sicherheit (verbindlich)
|
||||
- Tokens: CSPRNG, **nur gehasht** gespeichert, single-use, kurzlebig, konstante-Zeit-Vergleich; **nie** in Logs/MailLog.
|
||||
- **Enumeration-Schutz** überall (Reset, E-Mail-Änderung): generische, einheitliche Antworten und Timing.
|
||||
- **Rate-Limiting** an Reset-Anfrage, Reset-Einlösung, Alt-Passwort-Prüfung (IP + Konto) — bindet an den globalen Limiter aus SEC5, hier aber schon inline scharf.
|
||||
- Reset/Änderung an **gesperrten/deaktivierten** Konten unmöglich.
|
||||
- Alle Ereignisse ins **Audit** (wer/wann/was, ohne Secrets); kompatibel zur SEC5-Audit-Erweiterung.
|
||||
- Kein Auto-Login direkt nach Reset (Nutzer meldet sich neu an) — reduziert Token-Missbrauch.
|
||||
|
||||
---
|
||||
|
||||
## 7. Akzeptanzkriterien
|
||||
- „Passwort vergessen" auf `/login` **und** `/platform/login` erzeugt (nur bei aktivem Konto) eine Reset-Mail; Antwort ist **immer** enumeration-neutral; Rate-Limit greift.
|
||||
- Reset-Link ist **single-use**, abgelaufen/benutzt → generische Ablehnung; nach Reset sind **alle Sessions ungültig**, Bestätigungs-Mail + Audit vorhanden.
|
||||
- Passwort-Selbständerung mit Alt-Passwort-Prüfung + Policy; **andere** Sessions werden abgemeldet, aktuelle bleibt.
|
||||
- E-Mail-Änderung erst nach **Verifizierung der neuen Adresse** wirksam; **alte Adresse** wird informiert.
|
||||
- Token-Hashes in DB (keine Klartext-Tokens), keine Secrets in Logs.
|
||||
- Funktioniert für Mandanten-Nutzer **und** Plattform-Admins.
|
||||
|
||||
## 8. Definition of Done
|
||||
`tsc` → `lint` → `build` (Guard-Check) grün · neue Actions in `check-module-guards.ts` · `AuthToken` + `sessionsValidAfter`-Felder in Migration (+RLS-DO-Block, `AuthToken` in `TENANT_MODELS` für tenant-Zeilen) · Browser-Test aller Flows (Tenant + Plattform) gegen Mailpit · Demo-Umgebung lauffähig.
|
||||
|
||||
## 9. Testplan (Kurz)
|
||||
1. **Reset happy path** (Tenant + Plattform): Anfrage → Mail (Mailpit) → Link → neues Passwort → alte Sessions abgemeldet → Login neu.
|
||||
2. **Enumeration:** unbekannte E-Mail → identische Antwort/Timing, keine Mail.
|
||||
3. **Token-Missbrauch:** abgelaufen / bereits benutzt / manipuliert → generische Ablehnung.
|
||||
4. **Rate-Limit:** viele Anfragen → gedrosselt.
|
||||
5. **Self-Change:** falsches Alt-Passwort → Ablehnung; korrekt → andere Session (zweiter Browser) wird ungültig, aktuelle bleibt.
|
||||
6. **E-Mail-Änderung:** Verify-Link an neue Adresse nötig; alte Adresse erhält Hinweis; unbestätigt → keine Änderung.
|
||||
7. **Deaktiviertes Konto:** kein Reset möglich.
|
||||
|
||||
## 10. Bibliotheken / Bausteine
|
||||
`crypto` (CSPRNG/SHA-256, konstante-Zeit) · vorhandene `password-policy.ts`/`password.ts` · SEC1-`enqueueMail` · Rate-Limit-Util (mit SEC5 teilen).
|
||||
Folgepaket **SEC3** nutzt den Session-Invalidierungs-Baustein (MFA-Änderung) und ergänzt **Step-up-Re-Auth** für die E-Mail-Änderung/kritische Aktionen.
|
||||
@@ -0,0 +1,105 @@
|
||||
# Sicherheit & Administration — Konzept & Empfehlung (PO)
|
||||
|
||||
Grundlage: `STAND-dev-branch.md` (Ist-Stand `dev`). Ziel: die genannten Punkte umsetzen **und** — weil Certvia selbst ein ISMS-Produkt ist — ein Sicherheitsniveau erreichen, das man dem Kunden vorlebt („eat your own dog food"). Status-Legende: ✅ vorhanden · 🟡 teilweise · 🟥 neu.
|
||||
|
||||
---
|
||||
|
||||
## 1. Eure Punkte im Ist-Abgleich (wichtig: nicht doppelt bauen)
|
||||
|
||||
| Anforderung | Status heute | Was fehlt / zu tun |
|
||||
|---|---|---|
|
||||
| **E-Mail-Versand** (Onboarding, Reset, Ticket-/Fristen-Benachrichtigungen) | 🟥 offen | „Paket 4" bewusst zurückgestellt; Aktivierung ist bereits **gekapselt**. Kompletter SMTP-/Mail-Layer + Templates neu. |
|
||||
| **Passwort-Reset** | 🟥 offen | Hängt am Mail-Versand; aktuell nur Initial-/Einmal-Passwort. Self-Service-Reset via signiertem, kurzlebigem Token neu. |
|
||||
| **Passwort ändern (selbst)** | 🟡 teilweise | **Force-Change** (`/change-password`) + Passwort-Policy (Argon2id) vorhanden. **Freiwillige** Änderung im Profil ergänzen (mit Alt-Passwort-Bestätigung). |
|
||||
| **2FA / MFA** | 🟡 teilweise | **TOTP optional** (Plattform-Admins *und* Mandanten-Nutzer) + Recovery-Codes vorhanden; Policy-Flag `mfaRequired` da. **Fehlt:** Enrollment-**Erzwingung** beim Login (Gate), optional WebAuthn/Passkeys. |
|
||||
| **Weiterer übergreifender Admin im Adminportal** | 🟡 teilweise | Getrennter **`PlatformAdmin`-Store** + eigener Login (`/platform/login`) + MFA existiert. **Fehlt:** CRUD-UI im Adminportal, um **weitere Plattform-Admins** anzulegen/zu verwalten (Rollen, Sperren, Reset, MFA-Pflicht). |
|
||||
|
||||
**Kernbotschaft:** 2FA und der getrennte Superadmin-Store sind **im Kern schon da** — hier geht es um *Erzwingung* bzw. *Verwaltungs-UI*, nicht um Neubau. Der echte Neubau ist der **Mail-Layer** (und alles, was daran hängt: Reset, Einladung, Benachrichtigungen).
|
||||
|
||||
---
|
||||
|
||||
## 2. Bausteine für die genannten Punkte
|
||||
|
||||
### 2.1 E-Mail-Infrastruktur (Fundament — schaltet Reset/Einladung/Benachrichtigung frei) 🟥
|
||||
- **Transaktionaler Mail-Provider** (SMTP oder API): z. B. Postmark/SendGrid/Mailgun/Amazon SES **oder** eigener SMTP. Auswahl = offene Entscheidung (§5).
|
||||
- **Domänen-Authentifizierung**: **SPF, DKIM, DMARC** einrichten (sonst Spam/Spoofing). Dediziert Absender-Domain (z. B. `no-reply@certvia.de`).
|
||||
- **Template-Engine** (gebrandet, Certvia): Layout-Basis + Bausteine für Einladung, Passwort-Reset, Passwort-geändert-Bestätigung, MFA-Änderung, Ticket-/Freigabe-/Fristen-Benachrichtigung.
|
||||
- **Queue + Retry** (BullMQ/Redis ist im Stack) für zuverlässigen, asynchronen Versand; Fehler-/Bounce-Handling; Rate-Limit.
|
||||
- **Benachrichtigungsregeln** je Nutzer/Ereignis (opt-in/opt-out, Sprache de/en), respektiert Mandanten-Isolation.
|
||||
|
||||
### 2.2 Passwort-Reset (Self-Service) 🟥
|
||||
- **Single-Use-Token**, **kurzlebig** (z. B. 30–60 Min), **serverseitig gehasht** gespeichert (nicht im Klartext), an E-Mail gebunden.
|
||||
- **Enumeration-Schutz**: „Falls ein Konto existiert, wurde eine E-Mail gesendet." (immer gleiche Antwort), **Rate-Limit** pro IP/Konto.
|
||||
- Nach Reset: **alle Sessions invalidieren**, Bestätigungs-Mail „Passwort geändert", Audit-Log-Eintrag. Deaktivierte/geblockte Konten: kein Reset.
|
||||
|
||||
### 2.3 Passwort selbst ändern 🟡
|
||||
- Profilseite „Passwort ändern": **Alt-Passwort-Bestätigung**, Policy-Prüfung (bestehende `password-policy.ts`), danach **andere Sessions abmelden** (aktuelle behalten), Bestätigungs-Mail + Audit.
|
||||
|
||||
### 2.4 2FA scharfschalten & härten 🟡→
|
||||
- **MFA-Enrollment-Gate**: bei `securityPolicy.mfaRequired` (tenant-weit) oder für Plattform-Admins Enrollment beim Login **erzwingen** (analog Force-Change-Gate).
|
||||
- **Recovery-Codes**: Anzeige/Regenerierung, Verbrauch protokolliert (vorhanden — Flow abrunden).
|
||||
- **Optional/Ausbau**: **WebAuthn/Passkeys** (phishing-resistent) als 2. Faktor; **Re-Auth** (Step-up) für sensible Aktionen (MFA deaktivieren, Admin anlegen, Export).
|
||||
- **TOTP-Secret** at rest **verschlüsselt** speichern (falls noch Klartext) + Rate-Limit auf Code-Eingabe.
|
||||
|
||||
### 2.5 Weiterer übergreifender Plattform-Admin 🟡→
|
||||
- **Plattform-Admin-Verwaltung** im Adminportal (`/platform/...`): Liste, **anlegen** (Initial-Passwort/Einladung), Rollen/Rechte (z. B. „Voll-Admin" vs. „Support/Read-only"), **sperren/reaktivieren**, Passwort-Reset, **MFA-Pflicht für alle Plattform-Admins**.
|
||||
- **Vier-Augen für kritische Plattform-Aktionen** (mind. 2 Admins, kein Self-Lockout — der Lockout-Schutz existiert bereits für Tenant-Rollen, hier fürs Plattform-Level ergänzen).
|
||||
- **Vollständiges Audit** jeder Plattform-Admin-Aktion (`scope=platform`, ist im Log-Modell vorgesehen).
|
||||
|
||||
---
|
||||
|
||||
## 3. Weitere sinnvolle Sicherheitsmaßnahmen (Empfehlung, priorisiert)
|
||||
|
||||
**P0 — sollte mit diesem Block kommen (hoher Nutzen, moderat):**
|
||||
- **HTTP-Security-Header**: CSP, HSTS, `X-Frame-Options`/`frame-ancestors`, `X-Content-Type-Options`, `Referrer-Policy`, `Permissions-Policy`. (Zentraler Middleware-Layer.)
|
||||
- **Rate-Limiting/Brute-Force** an Login, Reset, MFA, API — ergänzt den vorhandenen Konto-Lockout (IP- **und** kontobezogen).
|
||||
- **Session-Härtung**: kurze Idle-/Absolute-Timeouts, **Session-Invalidierung** bei Passwort-Reset/Deaktivierung/MFA-Änderung, **„aktive Sitzungen" anzeigen + einzeln abmelden**.
|
||||
- **Sichere Token-/Secret-Behandlung**: alle Tokens single-use + gehasht; Secrets nur aus Env/Secret-Store, nie im Repo; **Secret-Scanning** in CI.
|
||||
- **Audit-/Security-Event-Log erweitern**: Logins (Erfolg/Fehlschlag), Rechteänderungen, MFA-Änderungen, Exporte, Admin-Aktionen; **append-only**/manipulationssicher; Aufbewahrung definiert.
|
||||
- **Passwort-Breach-Check** beim Setzen (HaveIBeenPwned k-Anonymity) zusätzlich zur Policy.
|
||||
|
||||
**P1 — kurz danach (Betrieb/Compliance):**
|
||||
- **Tenant-Isolationstests** automatisiert (RLS-Regression) — Kernrisiko bei Multi-Tenant.
|
||||
- **Verschlüsselung at rest** (DB + **Backups**), **TLS/HSTS** überall, Key-Rotation; TOTP-/sensible Felder verschlüsselt.
|
||||
- **Backups + regelmäßige Restore-Tests** (dogfooding: das fordert ihr selbst als Control ein), DR-Konzept, RTO/RPO.
|
||||
- **Dependency-/Container-Scanning** (SCA), **SAST**, `npm audit`/Renovate; Patch-SLA.
|
||||
- **DSGVO-Funktionen** (Admin Phase 2): mandantenvollständiger **Export**, **Löschkonzept/Retention**, AVV/DPA-Bausteine, TOMs dokumentiert.
|
||||
- **Impersonation** (Admin Phase 2) **nur** zeitlich begrenzt, protokolliert, mit „Support-Sitzung aktiv"-Banner (Support-Zugriff sicher machen).
|
||||
- **E-Mail-Change-Verifizierung** (Double-Opt-in bei Adressänderung) + Benachrichtigung an alte Adresse.
|
||||
|
||||
**P2 — mittelfristig / Reifegrad:**
|
||||
- **WebAuthn/Passkeys**, **SSO (OIDC/SAML)** für Enterprise-Kunden (steht im Backlog).
|
||||
- **Datei-Upload-Sicherheit** (sobald Storage kommt): AV-Scan, MIME/Größen-Limits, kein HTML-Serving, signierte URLs.
|
||||
- **WAF/Reverse-Proxy** + DDoS-Schutz vor der App; least-privilege DB-User; Netzsegmentierung.
|
||||
- **Responsible-Disclosure**: `security.txt`, Kontaktpfad, ggf. Bug-Bounty.
|
||||
- **Externer Pen-Test** vor „Go-Live/Skalierung"; Ergebnisse als Maßnahmen ins eigene ISMS.
|
||||
- **Incident-Response-Prozess** für Certvia selbst (passt zum NIS2-/Vorfälle-Modul, das ihr ohnehin baut).
|
||||
|
||||
---
|
||||
|
||||
## 4. Vorschlag: Priorisierte Roadmap (integriert eure Punkte + P0)
|
||||
|
||||
| Reihe | Paket | Inhalt |
|
||||
|---|---|---|
|
||||
| **1** | **Mail-Fundament** | Provider + SPF/DKIM/DMARC, Queue/Retry, Certvia-Templates, Benachrichtigungsregeln |
|
||||
| **2** | **Auth-Self-Service** | Passwort-Reset (Token), Passwort selbst ändern, E-Mail-Change-Verifizierung, Session-Invalidierung |
|
||||
| **3** | **MFA scharf** | Enrollment-Gate erzwingen, Recovery-Codes-Flow, TOTP-Secret verschlüsselt, Step-up für sensible Aktionen |
|
||||
| **4** | **Plattform-Admin-Verwaltung** | Weitere Superadmins anlegen/verwalten, Rollen, Vier-Augen, Plattform-Audit |
|
||||
| **5** | **Härtung P0** | Security-Header, Rate-Limiting, Audit-Erweiterung, Breach-Check, Secret-Scanning |
|
||||
| **6+** | **P1/P2** | RLS-Tests, at-rest-Verschlüsselung, Backups/Restore, DSGVO, Impersonation, WebAuthn/SSO, Pen-Test |
|
||||
|
||||
Pakete 1–4 sind stark verzahnt (alles hängt am Mail-Fundament); 5 läuft quer und sollte **mit** 1–4 kommen, nicht danach.
|
||||
|
||||
---
|
||||
|
||||
## 5. Offene Entscheidungen (bevor wir Tasks schneiden)
|
||||
1. **Mail-Provider**: API-Dienst (Postmark/SendGrid/SES …) **oder** eigener SMTP? (beeinflusst Zustellbarkeit, DSGVO-Ort, Aufwand)
|
||||
2. **2FA-Ausbau**: reicht TOTP scharfschalten, oder direkt **WebAuthn/Passkeys** mitnehmen?
|
||||
3. **Plattform-Admin-Rollen**: nur „Voll-Admin", oder abgestufte Rollen (Support/Read-only)?
|
||||
4. **DSGVO-Umfang** jetzt (Export/Löschung/Retention) oder in eigener Runde?
|
||||
5. **Team-Setup**: 1, 2 oder 3 Entwickler parallel — dann schneide ich analog zum Wizard vertikale Lanes.
|
||||
|
||||
---
|
||||
|
||||
## 6. Nächster Schritt
|
||||
Auf dieser Basis schneide ich — wie beim Wizard — **Entwickler-Aufgabenpakete** (mit Branch-Konvention unter `dev`, Akzeptanzkriterien, DoD). Sag mir die Antworten zu §5 (v. a. Mail-Provider und Team-Größe), dann lege ich los. Reihenfolge-Empfehlung: **Mail-Fundament zuerst**, weil Reset/Einladung/Benachrichtigung daran hängen.
|
||||
@@ -0,0 +1,168 @@
|
||||
# Contracts-Checkliste — Kickoff Dev A × Dev B (15 Min.)
|
||||
|
||||
> Zweck: Die Naht zwischen **Paket Dev A** (Wizard-Shell/Scoping/AL) und **Paket Dev B**
|
||||
> (Engines/Fragebogen/Richtlinien) **einmal gemeinsam bestätigen**, bevor beide parallel starten.
|
||||
> Grundlage: der identische *Contracts-Anhang* §1–§6 in beiden Entwicklerpaketen.
|
||||
> Vorgehen: Punkt für Punkt durchgehen, abhaken, offene Entscheidungen unten eintragen, beide signieren.
|
||||
> Danach laufen A und B konfliktarm parallel — einzige echte Nahtstellen sind
|
||||
> `prisma/schema.prisma`, `scripts/check-module-guards.ts` und die Step-Registry.
|
||||
|
||||
**Basis-Branch:** `dev` · **Feature-Branches:** `dev/a*-…` (A) bzw. `dev/b*-…` (B) · **PR-Ziel:** `dev`
|
||||
Kein Push durch die Agenten; häufig auf `dev` rebasen; kleine PRs je Story.
|
||||
|
||||
---
|
||||
|
||||
## §1 Task-Objekt — **Owner: Dev B** (A konsumiert)
|
||||
|
||||
Dev B besitzt das Modell + `createTask`-Action; Dev A / Wizard-Gates rufen sie auf.
|
||||
|
||||
- [ ] `type`: `document_create | evidence_provide | technical | organizational | validation | policy_approval`
|
||||
- [ ] Felder: `owner`, `dueDate`, `priority: 'hoch'|'mittel'|'niedrig'`, `status`
|
||||
- [ ] `resources` (JSON): `{ tool, budget, personnel, time }`
|
||||
- [ ] `origin` (Herkunft/Trigger) vorhanden
|
||||
- [ ] `links` (polymorph): `{ control?, risk?, document?, asset? }`
|
||||
- [ ] Bestehender `policy_approval`-Flow bleibt unverändert lauffähig (Regression grün)
|
||||
- [ ] **Signatur der `createTask`-Action steht fix**, bevor A ihre Gates verdrahtet
|
||||
→ Signatur hier notieren: `_____________________________________________`
|
||||
|
||||
## §2 Validierungsstatus — **Owner: Dev A** (B konsumiert)
|
||||
|
||||
- [ ] `enum ObjectReviewStatus { offen, in_bearbeitung, zur_validierung, validiert, zurueckgewiesen }`
|
||||
- [ ] Zusatzfelder: `reviewComment`, `reviewerId`
|
||||
- [ ] Regel bestätigt: **„Nur `validiert` zählt als bestätigt."**
|
||||
- [ ] RBAC-Recht `validate_objects` + Rolle `external_validator` (klonbar) angelegt
|
||||
- [ ] Feld-Konvention (an welchen Objekten der Status hängt) für Wizard-Gates fix
|
||||
|
||||
## §3 Flags in `variables.schema.json` — **Owner: Dev B** (Namen fix, A entwickelt dagegen)
|
||||
|
||||
- [ ] Namen unverändert übernommen (keine Umbenennung ohne beidseitige Abstimmung):
|
||||
`FLAG_INCLUDE_SHOULD, FLAG_HIGH_PROTECTION, FLAG_VERY_HIGH_PROTECTION,
|
||||
FLAG_ELEVATED_PROTECTION, FLAG_PERSONAL_DATA, FLAG_PROTOTYPE_PROTECTION,
|
||||
FLAG_CLOUD_USED, FLAG_AI_USED, FLAG_OT_USED, FLAG_DEV_INHOUSE, FLAG_MOBILE_WORK,
|
||||
FLAG_MOBILE_DEVICES, FLAG_CRYPTO_PKI, FLAG_EXTERNAL_IT, FLAG_CUSTOMER_SYSTEMS,
|
||||
FLAG_ISB_EXTERNAL, FLAG_ISB_INTERNAL`
|
||||
- [ ] `FLAG_ELEVATED_PROTECTION` bleibt **abgeleitet** (`applyProtection`) — nie manuell setzen
|
||||
- [ ] Nach Schema-Änderung: `python3 seed/isms-vorlagenpaket-v2/_verify.py` → **OK**
|
||||
|
||||
## §4 Prüfziele — beidseitig fix
|
||||
|
||||
- [ ] Werte: `informationssicherheit | prototypenschutz | datenschutz`
|
||||
- [ ] Wirkung bestätigt: Kapitel `8.x` nur bei Prototyp, `9.x` nur bei Datenschutz
|
||||
|
||||
## §5 Step-Registry — **Owner: Dev A** (B konsumiert)
|
||||
|
||||
- [ ] Signatur fix: `registerStep({ key, title, order, guard, component })`
|
||||
- [ ] Schritt-Keys/Reihenfolge:
|
||||
`1 scoping · 2 context · 3 roles · 4 policies · 5 assets · 6 risks · 7 controls · 8 gap · 9 readiness`
|
||||
- [ ] Klar: **B liefert die Komponenten für `context` (Schritt 2) und `policies` (Schritt 4)**;
|
||||
A stellt die Registry-Schnittstelle stabil bereit, bevor B einklinkt
|
||||
|
||||
## §6 Migrations-Protokoll — beidseitig verbindlich
|
||||
|
||||
- [ ] Vor jedem Migrations-Erzeugen zuerst auf `dev` rebasen
|
||||
- [ ] **Migrationen nie gleichzeitig ohne Absprache** erstellen
|
||||
- [ ] Je Branch **genau eine Migration pro Story**
|
||||
- [ ] Prisma-7-Flow: `migrate diff --from-config-datasource … --to-schema … --script`
|
||||
→ RLS-DO-Block manuell anhängen → `migrate deploy` → `generate`
|
||||
- [ ] Neue tenant-gebundene Modelle → `TENANT_MODELS` (`src/server/db.ts`) **und** RLS-Policy
|
||||
- [ ] Neue Server-Action-Datei → in `scripts/check-module-guards.ts` eintragen (sonst Build-Fail)
|
||||
|
||||
---
|
||||
|
||||
## Erwartete Migrations-Reihenfolge (gemeinsam festlegen)
|
||||
|
||||
Beide erzeugen Migrationen an `schema.prisma` — Reihenfolge vorab abstimmen, um Konflikte zu vermeiden.
|
||||
Vorschlag (an tatsächlicher Story-Reihenfolge ausrichten):
|
||||
|
||||
| # | Story | Owner | Migration (Arbeitsname) |
|
||||
|---|-------|-------|-------------------------|
|
||||
| 1 | A1-1 | A | `onboarding_progress` |
|
||||
| 2 | F1 | B | `tasks_wizard_fields` |
|
||||
| 3 | F2 | A | (Enum `ObjectReviewStatus` + `external_validator`) |
|
||||
| 4 | A2-2 | A | `wizard_scope` |
|
||||
| 5 | B3 | B | `wizard_facts` |
|
||||
|
||||
- [x] Reihenfolge oben bestätigt / angepasst — A1-1(A) → F1(B) → F2(A) → A2-2(A) → B3(B)
|
||||
- [x] Wer erzeugt die **erste** Migration? → **Dev A** (`onboarding_progress`, A1-1) — von Dev B bestätigt; B rebast danach zuerst
|
||||
|
||||
## Offene Fachpunkte (aus C0 — vor bzw. begleitend zu klären)
|
||||
|
||||
- [ ] Neue `FLAG_*` in `variables.schema.json` ergänzt (F4, Dev B)
|
||||
- [ ] Vorlagen `P01`/`D01` + `VA-20` angelegt (B4-3, Dev B)
|
||||
- [ ] Baseline `BL-*` normalisiert
|
||||
- [ ] ISB-Freigabe der neuen/geänderten Texte (fachlich, kein Code)
|
||||
|
||||
---
|
||||
|
||||
## Sign-off
|
||||
|
||||
- Dev A bestätigt §1–§6 + Migrations-Reihenfolge: **Claude (Dev A)** (Datum: 2026-07-28)
|
||||
- Dev B bestätigt §1–§6 + Migrations-Reihenfolge: **Claude (Dev B)** (Datum: 2026-07-28)
|
||||
|
||||
> Änderungen an §1–§6 nach dem Kickoff nur **gemeinsam** und mit Update dieser Datei
|
||||
> **und** von `docs/STAND-dev-branch.md`.
|
||||
|
||||
---
|
||||
|
||||
## Dev A — Kickoff-Vorbereitung (Positionen & Vorschläge, warten auf B-Bestätigung)
|
||||
|
||||
> Nicht-bindend bis zum gemeinsamen Sign-off. „A-Vorschlag" = braucht B's Ja; „A bestätigt" =
|
||||
> liegt in A's Hoheit und ist von A's Seite geklärt.
|
||||
|
||||
**§1 Task-Objekt (Owner B):** A bestätigt die Feldliteralwerte (`type`-Werte, `priority`, `resources`,
|
||||
`origin`, `links`) wie im Anhang. **A braucht von B eine fixe `createTask`-Signatur, bevor A Gates/Trigger
|
||||
verdrahtet.** A-Vorschlag als Startpunkt:
|
||||
`createTask(input: { type, title, origin, owner?, dueDate?, priority?, resources?, links? }): Promise<Task>`
|
||||
(Server-Action in B's Hoheit; A ruft nur auf). → **B bestätigt/ändert Signatur:** ✅ **bestätigt (unverändert)** —
|
||||
`createTask(input: { type, title, origin, owner?, dueDate?, priority?, resources?, links? }): Promise<Task>`.
|
||||
Mapping/Defaults (B-Hoheit, F1): `owner` → DB-Spalte `assigneeId` (eine verantwortliche Person; optional, da B1-Vorschläge unassigned starten);
|
||||
`priority` default `'mittel'`; `resources = { tool?, budget?, personnel?, time? }` (alle optional); `links = { control?, risk?, document?, asset? }` (IDs/Refs).
|
||||
`status` setzt die Action **serverseitig** (Default `OPEN`; auto-generierte B1-Vorschläge starten im Vorschlags-Status zur Bestätigung) — **kein** Input-Feld.
|
||||
Bestehende `entityType/entityId/entityRef` bleiben für den `policy_approval`-Flow erhalten (F1 fügt nur Felder hinzu); `links.document` bildet den Dokumentbezug ab.
|
||||
|
||||
**§2 Validierungsstatus (Owner A) — A bestätigt:**
|
||||
- `enum ObjectReviewStatus { offen, in_bearbeitung, zur_validierung, validiert, zurueckgewiesen }` + `reviewComment`, `reviewerId`.
|
||||
- Regel „Nur `validiert` zählt als bestätigt" gilt für alle Wizard-Gates.
|
||||
- RBAC-Recht `validate_objects` + klonbare Rolle `external_validator`.
|
||||
- **Feld-Konvention (Gate-Quelle):** In A1-1 trägt der Schritt-Datensatz `OnboardingProgress` den Review-Status;
|
||||
das „Weiter"-Gate liest den Status des Vorgänger-Schritts. Sobald Domänenobjekte je Schritt existieren
|
||||
(spätere Stories), wandert die Statusquelle auf das jeweilige Primärobjekt (Generalisierung = A3).
|
||||
→ **B nimmt das für seine Schritte (2 context, 4 policies) so an:** ✅ **ja** — B liest für `context` (2) und `policies` (4)
|
||||
den Review-Status des Vorgänger-Schritts aus `OnboardingProgress` (Quelle A1-1); „nur `validiert` zählt". B schreibt in diesen Schritten
|
||||
nur Fakten/Flags bzw. Richtlinien-Objekte, **nicht** den Gate-Status selbst. Hinweis: Schritt 4 nutzt weiterhin den bestehenden
|
||||
`policy_approval`-Workflow für die inhaltliche Freigabe; das Wizard-„Weiter"-Gate hängt aber am `OnboardingProgress`-Status, nicht am Task.
|
||||
|
||||
**§3 Flags (Owner B):** A übernimmt die Namen aus §3 **unverändert**, benennt nichts um, behandelt
|
||||
`FLAG_ELEVATED_PROTECTION` als abgeleitet (nie manuell). A entwickelt `scope-filter.ts` gegen diese Namen,
|
||||
**bevor** F4 landet. → **B bestätigt Namensliste final:** ✅ **final** — die 17 Namen bleiben unverändert. Ist-Stand geprüft:
|
||||
**14 bereits** in `variables.schema.json` vorhanden; F4 ergänzt **genau die 3 fehlenden** `FLAG_PROTOTYPE_PROTECTION`, `FLAG_ISB_EXTERNAL`,
|
||||
`FLAG_ISB_INTERNAL` (+ fehlende `ROLE_*/TECH_*` aus C2, **ohne** FLAG-Namen anzufassen). `FLAG_ELEVATED_PROTECTION` bleibt abgeleitet. Nach F4: `_verify.py` → OK.
|
||||
|
||||
**§4 Prüfziele:** A bestätigt `informationssicherheit | prototypenschutz | datenschutz`; Kap. `8.x` nur bei
|
||||
Prototyp, `9.x` nur bei Datenschutz (C1-Methodik).
|
||||
|
||||
**§5 Step-Registry (Owner A) — A bestätigt & stellt bereit:**
|
||||
- Signatur `registerStep({ key, title, order, guard, component })`, Keys/Reihenfolge
|
||||
`1 scoping · 2 context · 3 roles · 4 policies · 5 assets · 6 risks · 7 controls · 8 gap · 9 readiness`.
|
||||
- A liefert die stabile Registry-Schnittstelle in A1-1, **bevor** B `context` (2) und `policies` (4) einklinkt.
|
||||
→ **B bestätigt Schnittstelle als ausreichend:** ✅ **ausreichend** — `registerStep({ key, title, order, guard, component })` + Keys 1–9
|
||||
genügen, um `context` (2) und `policies` (4) einzuklinken. Einzige Bitte an A: `guard` muss das **Ausblenden** eines Schrittes erlauben
|
||||
(z. B. `policies` nur bei aktivem Richtlinien-Modul) und die `component`-Client/Server-Boundary sauber halten. Keine weiteren Felder von B benötigt.
|
||||
|
||||
**§6 Migrations-Reihenfolge — A-Vorschlag:**
|
||||
|
||||
| # | Story | Owner | Migration | Anmerkung |
|
||||
|---|-------|-------|-----------|-----------|
|
||||
| 1 | A1-1 | A | `onboarding_progress` | **A erzeugt die erste Migration** |
|
||||
| 2 | F1 | B | `tasks_wizard_fields` | B rebast danach zuerst auf `dev` |
|
||||
| 3 | F2 | A | `object_review_status` (Enum + `external_validator`) | |
|
||||
| 4 | A2-2 | A | `wizard_scope` | |
|
||||
| 5 | B3 | B | `wizard_facts` | |
|
||||
|
||||
→ **Wer erzeugt die erste Migration? A-Vorschlag: Dev A (A1-1).** B bestätigt: ✅ **ja** — Dev A erzeugt `onboarding_progress` zuerst;
|
||||
B rebast danach zuerst auf `dev` und erzeugt dann `tasks_wizard_fields` (F1).
|
||||
→ Reihenfolge oben bestätigt/angepasst: ✅ **bestätigt (unverändert)** — A1-1(A) → F1(B) → F2(A) → A2-2(A) → B3(B); je Branch genau eine Migration, nie gleichzeitig.
|
||||
|
||||
**Nicht-blockierend für A1-1** (betrifft spätere A-Stories bzw. B/Berater): neue `FLAG_*` in
|
||||
`variables.schema.json` (F4), `seed/scoping/c1-scope.json` erzeugt A aus der C1-Tabelle (445 Zeilen),
|
||||
P01/D01/VA-20 + Baseline-Normalisierung (B4/Berater), ISB-Freigabe (fachlich).
|
||||
@@ -0,0 +1,82 @@
|
||||
# Umsetzungspaket **Dev A** — Wizard-Fundament, Scoping & AL2/AL3 zentral
|
||||
|
||||
> Claude-Code-Prompt für Entwickler A. Parallel zu **Paket Dev B**. Basis-Branch **`dev`**. Fachcontent: `Fachcontent_Wizard_C1-C9/C1_Scoping-AL-Pruefziel.md`. Repo-Doku: `docs/HANDOVER-DEV.md`, `STAND-dev-branch.md`.
|
||||
|
||||
## Auftrag (Kurz)
|
||||
Baue das **Wizard-Grundgerüst**, den **Scoping-Schritt** und verlege den **AL2/AL3-Schalter zentral ins Admin-/Superadmin-Portal**. Du lieferst die Klammer, in die Dev B seine Schritt-Inhalte einklinkt.
|
||||
|
||||
## Branches (unter `dev` abzweigen, PR-Ziel `dev`)
|
||||
- `dev/a1-wizard-shell`
|
||||
- `dev/a2-scoping-admin-al`
|
||||
Häufig auf `dev` rebasen. Kleine PRs je Story.
|
||||
|
||||
## Datei-Hoheit (nur DU fasst diese an)
|
||||
`src/app/(app)/onboarding/**` · `src/server/actions/onboarding.ts` · `src/lib/scope-filter.ts` · `src/app/(platform)/admin/**` (AL-Einstellung) · `src/lib/modules.ts` (nur Eintrag `onboarding`) · Scope-/Progress-Modelle in `prisma/schema.prisma`.
|
||||
**Koordiniert (mit Dev B abstimmen, siehe Contracts-Anhang):** `prisma/schema.prisma` (Migrations-Reihenfolge), `scripts/check-module-guards.ts` (deine neuen Actions eintragen), Validierungsstatus-Enum.
|
||||
|
||||
---
|
||||
|
||||
## Story A1 — Wizard-Shell & Navigation (`dev/a1-wizard-shell`)
|
||||
|
||||
**A1-1 Step-Registry & State-Machine (L)**
|
||||
- Neues Modul **`onboarding`** in `src/lib/modules.ts` (Default aktiv für Bestands-Tenants).
|
||||
- Bereich `src/app/(app)/onboarding/**` mit einer **Step-Registry**: Schritte registrieren sich mit `{ key, title, order, guard, component }`. Dev B klinkt „context" (Schritt 2) und „richtlinien" (Schritt 4) ein — definiere die Registry-Schnittstelle stabil (Contracts-Anhang §5).
|
||||
- **State-Machine**: `offen → in_bearbeitung → zur_validierung → validiert` je Schritt; **Gate**: „Weiter" ist gesperrt, solange das Vorgänger-Objekt nicht `validiert` ist (nutzt Validierungsstatus, Contracts §2).
|
||||
- **Persistenter Fortschritt** je Mandant: Modell `OnboardingProgress` (tenant-gebunden, `TENANT_MODELS`+RLS), Migration `onboarding_progress`.
|
||||
- Server-Action-Datei `src/server/actions/onboarding.ts` über `moduleGuard("onboarding")`; in `scripts/check-module-guards.ts` eintragen.
|
||||
- **AK:** Fortschritt resumierbar; Gate blockiert korrekt; Schritte via Registry einklinkbar; `build`/Guard-Check grün.
|
||||
|
||||
**A1-2 Dashboard-Kachel (S)**
|
||||
- Kachel „Onboarding-Fortschritt" in `dashboard/page.tsx` analog der bestehenden Freigabe-Kachel (Anteil erledigter Schritte, nächster offener Schritt).
|
||||
|
||||
---
|
||||
|
||||
## Story F2 (dein Anteil der Foundation) — Validierungsstatus-Enum (`dev/a1-wizard-shell`)
|
||||
- Lege das **wiederverwendbare Enum** `ObjectReviewStatus` + Feld-Konvention an (Contracts §2), das Wizard-Gates und später A3 nutzen. RBAC-Recht `validate_objects`; Rolle **`external_validator`** ergänzen.
|
||||
- **AK:** Enum + Recht vorhanden; Wizard-Gate liest den Status; Rolle im RBAC klonbar.
|
||||
- **Hinweis:** Die vollständige Generalisierung über alle Objekttypen ist Story A3 (späterer Branch) — hier nur Enum + Wizard-Nutzung.
|
||||
|
||||
---
|
||||
|
||||
## Story A2 — Scoping + AL2/AL3 zentral im Adminportal (`dev/a2-scoping-admin-al`)
|
||||
|
||||
**A2-1 AL2/AL3 zentral (M)** — *explizite Anforderung*
|
||||
- Der Assessment-Level (AL2/AL3) wird **ausschließlich** im **Admin-/Superadmin-Portal je Mandant** gesetzt → **einzige Quelle der Wahrheit**. UI in `src/app/(platform)/admin/**`, Action in `src/server/actions/admin.ts`/`platform.ts`.
|
||||
- Mandanten-`/settings` und der Scoping-Schritt zeigen AL nur **read-only** an (kein Änderungsrecht mehr im Tenant).
|
||||
- AL treibt die bestehenden Flags `FLAG_HIGH_PROTECTION`/`FLAG_VERY_HIGH_PROTECTION` und den vorhandenen Coverage-Filter (Coverage zeigt bei AL2 keine „sehr hoch"-Controls — Verhalten beibehalten, Quelle umziehen).
|
||||
- **AK:** AL ist nur im Adminportal änderbar; Änderung propagiert in Coverage + Zusatzanforderungen; Tenant kann AL nicht mehr selbst setzen.
|
||||
|
||||
**A2-2 Scope-Objekt + Filter-Engine (M)**
|
||||
- Scoping (Schritt 1) erfasst: **Prüfziele** (Informationssicherheit / Prototypenschutz / Datenschutz), Standorte, Geltungsbereich, Ausschlüsse → Modell `WizardScope` (tenant-gebunden, RLS).
|
||||
- **`src/lib/scope-filter.ts`**: gegeben (AL, gesetzte `FLAG_*`, aktive Prüfziele) → liefert die **aktiven Anforderungen**. Datengrundlage: **C1-Tabelle** (412 Zeilen: `Control · Anforderungs-ID · Typ · AL2 · AL3 · Prüfziel · Scope-Bedingung(Flag)`), als Seed/JSON `seed/scoping/c1-scope.json` einlesen (ID = `mapping.json`-`id`).
|
||||
- Filterlogik exakt nach C1-Methodik: MUSS/SOLL = AL2+AL3 (SOLL über `FLAG_INCLUDE_SHOULD`); HOCH nur bei `FLAG_HIGH_PROTECTION`; SEHR HOCH nur bei `FLAG_VERY_HIGH_PROTECTION`; Kapitel 8.x nur bei Prüfziel Prototyp, 9.x nur bei Datenschutz.
|
||||
- **AK / Tests:** Unit-Tests gegen repräsentative C1-Zeilen (z. B. `1.2.2-H1` erscheint nur bei `FLAG_HIGH_PROTECTION`; `1.1.1-S1` nur bei `FLAG_INCLUDE_SHOULD`; `8.*` nur bei Prototyp). Geänderter Scope blendet nachgelagerte Schritte korrekt.
|
||||
|
||||
**Fachcontent:** `C1_Scoping-AL-Pruefziel.md`. **Abhängigkeit:** A1 (Shell), Contracts §2 (Status), §3 (Flags-Namen von Dev B/F4 — bis dahin gegen die im Contracts-Anhang fixierten Namen entwickeln).
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done (jede Story)
|
||||
`npx tsc --noEmit` → `npm run lint` → `npm run build` (Guard-Check) grün · neue Action in `check-module-guards.ts` · neue tenant-Modelle in `TENANT_MODELS`+RLS+Migration (RLS-DO-Block) · Browser-Verifikation · Demo-Seed lauffähig.
|
||||
|
||||
## Reihenfolge
|
||||
A1-1 → F2 → A1-2 → A2-1 → A2-2. Danach (Folge-Paket): A3 (Validierung generalisieren), A5/A6/A7/A8.
|
||||
|
||||
---
|
||||
|
||||
## Contracts-Anhang (identisch in Paket A und B — an der Naht abstimmen)
|
||||
|
||||
**§1 Task-Objekt (Dev B besitzt das Modell, du konsumierst es):**
|
||||
`Task { type: 'document_create'|'evidence_provide'|'technical'|'organizational'|'validation'|'policy_approval', owner, dueDate, priority: 'hoch'|'mittel'|'niedrig', status, resources: {tool,budget,personnel,time}, origin, links: {control?,risk?,document?,asset?} }`. Gates/Trigger erzeugen Aufgaben über die Action von Dev B.
|
||||
|
||||
**§2 Validierungsstatus (du besitzt das Enum):**
|
||||
`enum ObjectReviewStatus { offen, in_bearbeitung, zur_validierung, validiert, zurueckgewiesen }` + `reviewComment`, `reviewerId`. Rolle `external_validator`. „Nur `validiert` zählt als bestätigt."
|
||||
|
||||
**§3 Flags (Dev B pflegt `variables.schema.json`, Namen sind fix):**
|
||||
`FLAG_INCLUDE_SHOULD, FLAG_HIGH_PROTECTION, FLAG_VERY_HIGH_PROTECTION, FLAG_ELEVATED_PROTECTION, FLAG_PERSONAL_DATA, FLAG_PROTOTYPE_PROTECTION, FLAG_CLOUD_USED, FLAG_AI_USED, FLAG_OT_USED, FLAG_DEV_INHOUSE, FLAG_MOBILE_WORK, FLAG_MOBILE_DEVICES, FLAG_CRYPTO_PKI, FLAG_EXTERNAL_IT, FLAG_CUSTOMER_SYSTEMS, FLAG_ISB_EXTERNAL, FLAG_ISB_INTERNAL`.
|
||||
|
||||
**§4 Prüfziele:** `informationssicherheit | prototypenschutz | datenschutz`.
|
||||
|
||||
**§5 Step-Registry (du definierst, B konsumiert):** `registerStep({ key, title, order, guard, component })`; Schritt-Keys: `1 scoping · 2 context · 3 roles · 4 policies · 5 assets · 6 risks · 7 controls · 8 gap · 9 readiness`.
|
||||
|
||||
**§6 Migrations-Protokoll:** Vor dem Erzeugen einer Migration auf `dev` rebasen; Migrationen nie gleichzeitig ohne Absprache erstellen; je Branch genau eine Migration pro Story.
|
||||
@@ -0,0 +1,100 @@
|
||||
# Umsetzungspaket **Dev B** — Aufgaben, Regel-Engine, Fragebogen & Richtlinien-Import/Upload
|
||||
|
||||
> Claude-Code-Prompt für Entwickler B. Parallel zu **Paket Dev A**. Basis-Branch **`dev`**. Fachcontent: `C2_Fragenkatalog-Wirkung.md`, `C3_Vorlagen-Annotation.md`, `C0_README` (offene Punkte). Repo-Doku: `docs/HANDOVER-DEV.md`, `STAND-dev-branch.md`.
|
||||
|
||||
## Auftrag (Kurz)
|
||||
Baue die **Regel-Engine**, den **Fragebogen**, die **Aufgaben-Erzeugung** und die **Richtlinien: Import bei Modul-Aktivierung + manueller Upload**. Du lieferst die Inhalte/Engines, die sich in die Wizard-Shell von Dev A einklinken.
|
||||
|
||||
## Branches (unter `dev` abzweigen, PR-Ziel `dev`)
|
||||
- `dev/b1-tasks-erweiterung`
|
||||
- `dev/b2-regel-engine`
|
||||
- `dev/b3-fragebogen`
|
||||
- `dev/b4-richtlinien-import-upload`
|
||||
Häufig auf `dev` rebasen. Kleine PRs je Story.
|
||||
|
||||
## Datei-Hoheit (nur DU fasst diese an)
|
||||
`src/server/actions/tasks.ts` (Task-Modell/Logik) · `src/lib/rules/**` · `seed/isms-vorlagenpaket-v2/variables.schema.json` · Fragebogen unter `src/app/(app)/onboarding/steps/context/**` und `.../policies/**` (in Dev-A-Registry eingeklinkt) · `prisma/import-policies.ts` · `src/app/(app)/policies/**` (Upload/Import-Einstieg) · `seed/isms-vorlagenpaket-v2/` (P01/D01/VA-20).
|
||||
**Koordiniert (mit Dev A abstimmen):** `prisma/schema.prisma` (Migrations-Reihenfolge), `scripts/check-module-guards.ts`, Step-Registry-Schnittstelle (§5).
|
||||
|
||||
---
|
||||
|
||||
## Story F1 — Aufgaben-Objekt-Schema erweitern (`dev/b1-tasks-erweiterung`)
|
||||
- Erweitere das bestehende `Task`/`TaskComment` (heute Typ `policy_approval`) um die Felder aus Contracts §1 (`type`, `owner`, `dueDate`, `priority`, `status`, `resources` JSON, `origin`, polymorphe `links`). Bestehender Freigabe-Flow bleibt lauffähig.
|
||||
- Migration `tasks_wizard_fields`; `TENANT_MODELS`+RLS bleiben.
|
||||
- **AK:** neue Felder vorhanden/typisiert; `policy_approval`-Flow unverändert grün.
|
||||
|
||||
## Story B1 — Auto-Generierung mit Bestätigung (`dev/b1-tasks-erweiterung`)
|
||||
- Aus Triggern (Schritt 3/4/6/7/8 + Zurückweisung) **Aufgabenvorschlag** erzeugen (Vorschlag → Bearbeiter bestätigt/verwirft). Trigger-Set exakt aus **C2 §8** (z. B. „ISB nicht benannt" → `organizational`/Control 1.2.2; „externe IT-Dienstleister = ja" → `evidence_provide`/Control 6.1.1; „kein Restore-Test" → `technical`/BL-OPS-06/Control 5.2.9).
|
||||
- Anzeige/Filter im Modul „Aufgaben" (`src/app/(app)/tasks/`), Ressourcenfelder editierbar.
|
||||
- **AK:** Trigger erzeugt korrekt verknüpften Vorschlag; Bestätigung übernimmt; Verwerfen dokumentiert.
|
||||
|
||||
---
|
||||
|
||||
## Story F4 — Variablen/Flags erweitern (`dev/b2-regel-engine`)
|
||||
- In `seed/isms-vorlagenpaket-v2/variables.schema.json` ergänzen: `FLAG_PROTOTYPE_PROTECTION`, `FLAG_ISB_EXTERNAL`, `FLAG_ISB_INTERNAL` + fehlende `ROLE_*`/`TECH_*` aus C2. Namen = Contracts §3 (fix, da Dev A darauf entwickelt).
|
||||
- **AK:** `python3 seed/isms-vorlagenpaket-v2/_verify.py` → **OK**.
|
||||
|
||||
## Story F3 + B2 — Regel-/Mapping-Engine (`dev/b2-regel-engine`)
|
||||
- **DSL** (Contracts §7) als Typen in `src/lib/rules/dsl.ts`; **Engine** in `src/lib/rules/engine.ts`: `Bedingung(Antwort|Scope|Flag) → Wirkung(Klausel ein/aus · Control relevant · Risiko/Asset-Bezug · Aufgabe)`.
|
||||
- Koppelt an vorhandene `{{#if FLAG}}`-Render-Flags und die Lieferanten-Anforderungs-Engine (Muster).
|
||||
- **Regeldaten** aus **C2 §5** (Q-FEAT-01…10) als Regelobjekte hinterlegen (z. B. `FLAG_CLOUD_USED` → R12-Klauseln + Controls 5.3.2/5.3.4/6.1.3 + Risiken R-CLOUD-*).
|
||||
- **AK / Tests:** Unit-Tests, die für jede Q-FEAT-Antwort die erwarteten Wirkungen prüfen; Antwortänderung propagiert deterministisch.
|
||||
|
||||
## Story B3 — Fragebogen/Fakten (Schritt 2) (`dev/b3-fragebogen`)
|
||||
- Dynamischer, **bedingter** Fragebogen mit Abschnitten **A–F aus C2** (Antworttypen + Anzeige-Bedingungen); Antworten als **wiederverwendbare Faktenobjekte** (Migration `wizard_facts`, RLS).
|
||||
- Abschnitt **E** (Baseline) als **vorbelegte Defaults** aus `Technische-Sicherheits-Baseline.md` — nur bestätigen/anpassen, keine Ersteingabe.
|
||||
- Zentrale Variablen bleiben serverseitig gesperrt (nur `/settings`, siehe `src/lib/policy-variables.ts`) — Fragebogen schreibt Fakten/Flags, nicht die gesperrten Variablen.
|
||||
- Einklinken über Dev-A-Step-Registry (§5), Schritt-Key `context`.
|
||||
- **AK:** Fragen A–F vorhanden; bedingte Sichtbarkeit über Flags; Antwort propagiert in abhängige Objekte (via B2); Baseline-Defaults vorbelegt.
|
||||
|
||||
---
|
||||
|
||||
## Story B4 — Richtlinien: Import bei Aktivierung + manueller Upload (`dev/b4-richtlinien-import-upload`)
|
||||
|
||||
**B4-1 Vorlagen-Import bei Modul-Aktivierung (M)** — *explizite Anforderung*
|
||||
- Aktiviert der Superadmin das **Richtlinien-Modul** für einen Mandanten, wird das Vorlagenpaket **mandantenweit nicht-destruktiv importiert**: kapsle die bestehende Logik `prisma/import-policies.ts` (Diff/Upsert/`archivedAt`, `{dryRun}`) als **serverseitig aufrufbare Action/Job**. Zusätzlich Button „Vorlagen importieren/aktualisieren" in Admin **und** unter `/policies`.
|
||||
- **AK:** Modul-Aktivierung triggert Import; idempotent; Status/Freigabe/Overrides/Variablenwerte bleiben erhalten; Änderungsreport sichtbar.
|
||||
|
||||
**B4-2 Manueller Upload eigener Richtlinien im Menü (M)** — *explizite Anforderung; Storage später*
|
||||
- Unter `/policies` Einstieg „Eigene Richtlinie hochladen" mit **Pflicht-Control-Zuordnung** (Multi-Select aus Control-Katalog, optional Anforderungs-IDs) gemäß **C3 §4**.
|
||||
- Datei-Persistenz über ein **gestubbtes Storage-Adapter-Interface** `src/server/storage/adapter.ts` (echtes Backend = Folge-Epic S1). Upload legt Metadaten + Block-Modell + Control-Mapping an; die Zuordnung fließt wie ein `<!-- REQ -->`-Anker in die Nachweislage (Schritt 7).
|
||||
- **AK:** „Eigene Richtlinie hochladen" vorhanden mit Control-Zuordnung; Storage-Adapter gekapselt (später ohne UI-Änderung verdrahtbar); hochgeladenes Dokument erscheint in der Coverage/Nachweislage.
|
||||
|
||||
**B4-3 Proto/DS-Vorlagen P01/D01 + VA-20 + mapping.json (M)**
|
||||
- Neue Vorlagen `P01_Prototypenschutz.md` (+ Verfahren `VA-20_Prototypen-Zutritt-und-Transport`) und `D01_Datenschutz.md` nach **C3 §2-Konvention** anlegen; `mapping.json`-Einträge im gleichen Schema für 8.x/9.x (IDs aus C1/C6-Dekomposition); Prototyp-Klauseln in `{{#if FLAG_PROTOTYPE_PROTECTION}}`.
|
||||
- `_verify.py` um die neuen Verzeichnisse/Anker erweitern.
|
||||
- **AK:** `python3 _verify.py` → **OK**; neue Anforderungen erscheinen im Scope, wenn Prüfziel Prototyp/Datenschutz aktiv (Dev-A-Filter).
|
||||
|
||||
**Fachcontent:** `C3` (Annotationskonvention + P01/D01), `C2` (Flag-Wirkung), `C0` (offene Punkte 1–3).
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done (jede Story)
|
||||
`npx tsc --noEmit` → `npm run lint` → `npm run build` (Guard-Check) grün · neue Action in `check-module-guards.ts` · neue tenant-Modelle in `TENANT_MODELS`+RLS+Migration (RLS-DO-Block) · bei Seed-Änderung `_verify.py` → **OK** · Browser-Verifikation.
|
||||
|
||||
## Reihenfolge
|
||||
F1 → B1 → F4 → (F3+B2) → B3 → B4-1 → B4-2 → B4-3. Danach (Folge-Paket): A6-Risikokatalog-Anbindung (C4), B5 Umsetzungshinweise (C6), B6 Versionierung, B7 Export (C9).
|
||||
|
||||
---
|
||||
|
||||
## Contracts-Anhang (identisch in Paket A und B — an der Naht abstimmen)
|
||||
|
||||
**§1 Task-Objekt (du besitzt das Modell):**
|
||||
`Task { type: 'document_create'|'evidence_provide'|'technical'|'organizational'|'validation'|'policy_approval', owner, dueDate, priority: 'hoch'|'mittel'|'niedrig', status, resources: {tool,budget,personnel,time}, origin, links: {control?,risk?,document?,asset?} }`. Dev A/Wizard-Gates rufen deine `createTask`-Action zum Erzeugen von Aufgaben.
|
||||
|
||||
**§2 Validierungsstatus (Dev A besitzt das Enum, du konsumierst):**
|
||||
`enum ObjectReviewStatus { offen, in_bearbeitung, zur_validierung, validiert, zurueckgewiesen }` + `reviewComment`, `reviewerId`. Rolle `external_validator`.
|
||||
|
||||
**§3 Flags (du pflegst `variables.schema.json`, Namen sind fix):**
|
||||
`FLAG_INCLUDE_SHOULD, FLAG_HIGH_PROTECTION, FLAG_VERY_HIGH_PROTECTION, FLAG_ELEVATED_PROTECTION, FLAG_PERSONAL_DATA, FLAG_PROTOTYPE_PROTECTION, FLAG_CLOUD_USED, FLAG_AI_USED, FLAG_OT_USED, FLAG_DEV_INHOUSE, FLAG_MOBILE_WORK, FLAG_MOBILE_DEVICES, FLAG_CRYPTO_PKI, FLAG_EXTERNAL_IT, FLAG_CUSTOMER_SYSTEMS, FLAG_ISB_EXTERNAL, FLAG_ISB_INTERNAL`.
|
||||
|
||||
**§4 Prüfziele:** `informationssicherheit | prototypenschutz | datenschutz`.
|
||||
|
||||
**§5 Step-Registry (Dev A definiert, du konsumierst):** `registerStep({ key, title, order, guard, component })`; du lieferst Komponenten für `context` (Schritt 2) und `policies` (Schritt 4).
|
||||
|
||||
**§6 Migrations-Protokoll:** Vor dem Erzeugen einer Migration auf `dev` rebasen; Migrationen nie gleichzeitig ohne Absprache erstellen; je Branch genau eine Migration pro Story.
|
||||
|
||||
---
|
||||
|
||||
## Gemeinsamer Kickoff (15 Min., beide Entwickler, vor Story-Start)
|
||||
Contracts §1–§6 gemeinsam bestätigen (Feldnamen, Enum-Werte, Flag-Namen, Registry-Signatur, Migrations-Reihenfolge). Danach arbeiten beide Pakete konfliktarm parallel; einzige echte Nahtstellen sind `schema.prisma`, `check-module-guards.ts` und die Step-Registry — alle drei sind im Contracts-Anhang fixiert.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Anweisung an den Berater — Fachcontent-Zulieferung (parallel zur Entwicklung)
|
||||
|
||||
Der Onboarding-Wizard hat seinen größten Engpass **nicht im Code, sondern im Fachcontent**. Die folgenden Arbeitspakete **C1–C9** laufen **parallel** zur Entwicklung und schalten jeweils eine oder mehrere Entwickler-Epics scharf. Bitte im angegebenen **Format** liefern und die **„muss vorliegen bis"**-Reihenfolge einhalten — sonst werden C2/C3/C4/C5/C6 zum kritischen Pfad.
|
||||
|
||||
> Bezug: Entwickler-Epics siehe `Wizard-Entwickler-Backlog.md`. Bestehendes Vorlagenpaket: `seed/isms-vorlagenpaket-v2/` (34 Dokumente, `mapping.json`, `_verify.py`).
|
||||
|
||||
---
|
||||
|
||||
## Übersicht (was schaltet was frei)
|
||||
|
||||
| WP | Inhalt | Schaltet frei | Format | Muss vorliegen bis |
|
||||
|---|---|---|---|---|
|
||||
| **C1** | AL2/AL3-Kennzeichnung + Prüfziel-Zuordnung je Control | A2 (Scoping/Filter) | Tabelle/CSV je Control | vor M2 |
|
||||
| **C2** | Fragenkatalog + Antwort→Wirkung-Mapping | B2 Regel-Engine, B3 Fragebogen | strukturierte Tabelle | vor M1/M2 |
|
||||
| **C3** | Regelfähige Vorlagen-Auszeichnung | B4 Richtlinien | Annotation im Vorlagenpaket | vor M2 |
|
||||
| **C4** | VDA-/Standard-Risiko-Katalog + Standardmaßnahmen | A6 Risiko | Tabelle/CSV | vor M4 |
|
||||
| **C5** | Reifegrad-Logik je Control | A7 Control-Assessment | Regeltabelle | vor M5 |
|
||||
| **C6** | Umsetzungshinweise je Teilanforderung | B5 + A7 | strukturierter Text je Anforderung | fortlaufend, Kern vor M3 |
|
||||
| **C7** | ISMS-Soll-Rollenmodell + Funktionstrennung | A4 Rollen | Regelliste + Vorlagen | vor M3 |
|
||||
| **C8** | Priorisierungslogik Gap + Quick-Wins | A8 Gap | Regeltext | vor M6 |
|
||||
| **C9** | Auswertungs-/Interpretationstexte + Export-Layout | B7 Readiness | Text + Layout-Skizze | vor M6 |
|
||||
|
||||
---
|
||||
|
||||
## Arbeitspakete im Detail
|
||||
|
||||
### C1 — Scoping-Grundlage (→ A2)
|
||||
Je VDA-ISA-Control angeben: Zutreffen bei **AL2 / AL3** (SEHR HOCH), Zuordnung zu **Prüfzielen** (Info-Sicherheit / Prototypenschutz / Datenschutz), typische **Ausschluss-/Scope-Regeln**.
|
||||
**Format:** eine Zeile je Control/Teilanforderung mit Spalten `Control-ID · Typ (MUSS/SOLL/HOCH/SEHR HOCH) · AL2? · AL3? · Prüfziel · Scope-Bedingung`. (Baut auf den vorhandenen Flags/Typen im `mapping.json` auf.)
|
||||
|
||||
### C2 — Fragenkatalog + Antwort→Wirkung-Mapping (→ B2, B3)
|
||||
Der geführte Fragebogen (Schritt 2) **und** die Regel-Engine hängen hieran. Je Frage: Text, Antworttyp, **Bedingung** (wann anzeigen), und die **Wirkung** jeder Antwort: welche **Variable/Platzhalter** gefüllt wird, welche **Klausel** ein-/ausgeblendet wird, welche **Controls/Assets/Risiken** betroffen sind, ob eine **Aufgabe** entsteht.
|
||||
**Format:** Tabelle `Frage-ID · Frage · Antwortoptionen · Anzeige-Bedingung · Wirkung(Variable / Klausel / Control / Risiko / Aufgabe)`. **Kritischer Pfad — bitte zuerst.**
|
||||
|
||||
### C3 — Regelfähige Vorlagen-Auszeichnung (→ B4)
|
||||
Die 34 Vorlagen so **annotieren**, dass klar ist: welche **Klausel/Baustein** bei welcher **Antwort/Flag** erscheint bzw. entfällt, und welche **Controls** ein Dokument belegt.
|
||||
**Format:** Auszeichnung direkt im Vorlagenpaket-Stil (bestehende `{{#if FLAG}}`-Mechanik + `mapping.json`-Control-Verknüpfung); danach `python3 _verify.py` → **OK**.
|
||||
|
||||
### C4 — Risiko-Katalog (→ A6)
|
||||
Kuratierter **Standard- und VDA-geforderter Risiko-Katalog**: je Risiko Beschreibung, betroffene **Assets/Controls**, empfohlene **Standardmaßnahmen**, Default-Bewertungshinweis.
|
||||
**Format:** Tabelle `Risiko-ID · Titel · Beschreibung · Controls · Asset-Typen · Standardmaßnahme(n) · Default-Einschätzung`.
|
||||
|
||||
### C5 — Reifegrad-Logik (→ A7)
|
||||
Regeln, wie aus vorhandenen **Belegen** (Dokument/Risiko/Asset + Validierungsstatus) ein **Reifegrad-Vorschlag** je Control entsteht, und was der **Zielreifegrad** ist. Vorschlag ist regelbasiert, **Bestätigung durch Bearbeiter Pflicht**.
|
||||
**Format:** Regeltabelle `Control · Bedingung(Belege) · Reifegrad-Vorschlag · Zielreifegrad · offene-Punkt-Kriterium`.
|
||||
|
||||
### C6 — Umsetzungshinweise (→ B5, A7)
|
||||
Je **Teilanforderung** ein Hinweis mit: **organisatorischer** Umsetzungsoption, **technischer** Option, typischen **Nachweisen**, passender **Vorlage** (Verweis), **Ressourcenindikation** (Tool/Personal/Budget/Zeit). Filterbar nach AL2/AL3.
|
||||
**Format:** strukturierter Block je Anforderungs-ID (Felder org/tech/Nachweise/Vorlage/Ressourcen). **Fortlaufend, Kern-Set vor M3.**
|
||||
|
||||
### C7 — ISMS-Soll-Rollenmodell + Funktionstrennung (→ A4)
|
||||
Soll-Rollen (GF, ISB, DSB, IT-Verantwortung), **Funktionstrennungs-Regeln** (welche Kombination unzulässig), und die **Bestellungs-/Ernennungs-Vorlagen** (ISB-Bestellung etc.) mit Rollen-Platzhaltern.
|
||||
**Format:** Regelliste + Vorlagen im Paket-Stil (Platzhalter).
|
||||
|
||||
### C8 — Priorisierungslogik Gap (→ A8)
|
||||
Wie offene Punkte priorisiert werden (Muss-/AL3-kritisch = hoch), Dedup-Kriterien, Definition **Quick-Wins**.
|
||||
**Format:** kurzer Regeltext + Beispiel-Priorisierung.
|
||||
|
||||
### C9 — Auswertung & Export (→ B7)
|
||||
Interpretationstexte fürs Reifegrad-Dashboard, empfohlene nächste Schritte vor dem Assessment, und das **Layout des VDA-ISA-Katalog-Exports** (Reihenfolge, Felder, „bestätigt/unbestätigt").
|
||||
**Format:** Textbausteine + Layout-Skizze.
|
||||
|
||||
---
|
||||
|
||||
## Prozess-Hinweise
|
||||
- Zulieferung **iterativ** je Kapitel/Control-Gruppe möglich (nicht „alles auf einmal") — die Entwicklung kann teilbefüllt starten.
|
||||
- **ISB-Freigabe** der neuen/angepassten Texte (VA/Richtlinien) ist ein eigener fachlicher Schritt (steht bereits offen auf `dev`).
|
||||
- Alle Vorlagen-/Katalog-Änderungen nach dem Einspielen mit **`python3 seed/isms-vorlagenpaket-v2/_verify.py` → OK** gegenprüfen.
|
||||
@@ -0,0 +1,120 @@
|
||||
# Onboarding-Wizard — Machbarkeitsanalyse (Product Owner)
|
||||
|
||||
Bewertung des Berater-Fahrplans (`Onboarding_Wizard_Fahrplan_Detail.md`) gegen den dokumentierten Funktionsstand (`HANDOVER-PM.md`, Stand 2026-07-20). Ziel: Umsetzbarkeit, Wiederverwendung vorhandener Funktionen, neue Funktionen, Komplexitäten — als Grundlage für die anschließende Aufgaben-/Epic-Definition.
|
||||
|
||||
**Status-Legende:** ✅ Vorhanden (direkt nutzbar) · 🟡 Teilweise (erweitern) · 🟥 Neu (bauen)
|
||||
**Aufwand:** S ≤ 1 Tag · M 2–4 Tage · L > 1 Woche (Entwicklung; Fachcontent separat)
|
||||
|
||||
---
|
||||
|
||||
## 1. Gesamturteil
|
||||
|
||||
**Der Wizard ist umsetzbar — und sitzt auf einem für dieses Vorhaben ungewöhnlich starken Fundament.** Rund zwei Drittel der fachlichen Bausteine existieren bereits produktiv (Assets/BIA, Risikoanalyse, Richtlinien-/Template-Engine mit Control-Mapping, importierter VDA-ISA-Katalog mit 316 Anforderungen/45 Controls, AL2/AL3-Schalter, Vier-Augen-Freigabe, Lieferanten-Reifegrad-/Gate-Logik, Coverage-Matrix, Audit-Log, Mandantenfähigkeit).
|
||||
|
||||
Der Wizard ist damit **weniger „neues Modul" als vielmehr eine geführte Orchestrierung vorhandener Module** plus einige neue Querschnitts-Engines. Der eigentliche Aufwand liegt — wie der Fahrplan selbst richtig betont — **nicht in der Software, sondern im Fachcontent** (regelfähige Vorlagen, VDA-Risiko-Katalog, Umsetzungshinweise, Reifegrad-Logik). Das ist der kritische Pfad und zugleich die Stelle, an der die GEFIM-Projekt-DNA (~100 Projekte) zum Tragen kommt.
|
||||
|
||||
**Drei Dinge müssen früh und sauber gebaut werden, sonst werden sie später teuer nachgezogen:** (1) ein generisches Aufgaben-Modul, (2) der generische Validierungs-Workflow, (3) der Regel-/Mapping-Layer. Sie sind die Klammer um alle Schritte.
|
||||
|
||||
---
|
||||
|
||||
## 2. Querschnittsmechaniken (Kap. 2 des Fahrplans)
|
||||
|
||||
| Mechanik | Status | Vorhanden (wiederverwendbar) | Neu zu bauen | Aufwand | Risiko |
|
||||
|---|:--:|---|---|:--:|---|
|
||||
| **2.1 Validierungs-Workflow** | 🟡 | Vier-Augen-Freigabe Richtlinien (Entwurf→In Freigabe→Freigegeben), Lieferanten-ISB-Reifegrad-Freigabe, RBAC, Audit-Log | **Generisches** Status-/Review-Modell über alle Objekttypen (Modul/Richtlinie/Risiko/Control-Bewertung), Rolle „externer Berater" als Validierer, Kommentare, „unbestätigt zählt nicht" in der Auswertung | M | Querschnitt — früh bauen, nicht anflanschen |
|
||||
| **2.2 Umsetzungshinweise** | 🟡→🟥 | `implementation`-Feld je Anforderung im Katalog, Anwender-Handbuch (kuratiert, Deep-Links) | Strukturiertes Hinweis-Modell (org/tech/Nachweise/Vorlagen-Verweis/**Ressourcenindikation**), Scope-/Antwort-Filter, Inline-Panel | Backend S · FE S · **Content L** | Content-Flaschenhals (SME) |
|
||||
| **2.3 Maßnahmen → Aufgaben-Modul** | 🟡 | Maßnahmen-Kanban (risikobezogen), berechnetes Restrisiko | **Generisches** Aufgaben-Objekt (Typ/Verantwortlich/Fälligkeit/Priorität/**Ressourcen**/Herkunft/Verknüpfung Control·Risiko·Dok·Asset), Auto-Vorschlag aus Triggern + Bestätigung | M–L | **Keystone** — alle Schritte hängen daran |
|
||||
| **2.4 Audit-Trail & Versionierung** | 🟡 | Audit-Log vorhanden | Echte Versionierung (Richtlinien-Diff ist offen), Versionierung von Katalog/Templates/Risiko-Katalog + Instanz-Referenz + Update-Propagation | M–L | Verzahnt mit offener „Versionierung+Diff" & destruktivem Re-Import |
|
||||
|
||||
---
|
||||
|
||||
## 3. Fachliche Bausteine / Datenobjekte (Kap. 3)
|
||||
|
||||
| Baustein | Status | Vorhanden | Neu / Lücke | Aufwand |
|
||||
|---|:--:|---|---|:--:|
|
||||
| Control-Katalog VDA ISA | ✅ | Import 316 Anforderungen / 45 Controls, je Anforderung adressierbar, Typen MUSS/SOLL/HOHER/SEHR HOHER | Ggf. explizite AL2/AL3-Kennzeichnung je Anforderung sichtbar machen (Flags vorhanden) | S |
|
||||
| Template-Bibliothek | ✅ | 28 Dokumente, Platzhalter/Variablen, optionale Klauseln via `{{#if}}`, Control-Verknüpfung, Freigabe | Regel-Tagging über Feature-Flags hinaus (Scope/Antwort-getrieben) | S–M |
|
||||
| Upload eigener Dokumente | 🟡 | (geplant) Word-Upload als Block-Modell + Anhang, versioniert | Control-Zuordnung des Uploads in die Nachweislage; Upload selbst ist noch offen | M |
|
||||
| Fakten-/Fragemodell | 🟡 | Variablen-Pflegestelle, Stammdaten (Settings) → ISMS-Variablen | **Dynamischer, bedingter Fragebogen** als wiederverwendbare Faktenobjekte | M |
|
||||
| Risiko-Katalog | 🟡 | Bedrohungs-/Schwachstellen-Kataloge, Risikoregister, Control-Verknüpfung | Kuratierter **Standard-/VDA-Risiko-Katalog** (vordefiniert, erweiterbar) | Backend M · **Content L** |
|
||||
| Regel-/Mapping-Layer | 🟡 | Handlebars-Flags, Variablen-Mapping, Lieferanten-Anforderungs-Engine (Schutzbedarf→Stufen) | **Generalisierung:** Antwort → betroffene Controls/Assets/Risiken (nicht nur Dokument-Klauseln) | L |
|
||||
| Reifegrad-/Gap-Engine | 🟡 | Coverage-Matrix (Control↔Dokument), Lieferanten-Reifegrad-Freigabe, Gate→Risiko | Control-**Scoring aus Belegen** + Markierung offener Teilanforderungen | Backend M–L · SME M |
|
||||
|
||||
---
|
||||
|
||||
## 4. Die neun Schritte (Kap. 4)
|
||||
|
||||
| Schritt | Status | Trägt auf vorhandenem auf | Neu zu bauen | Aufwand |
|
||||
|---|:--:|---|---|:--:|
|
||||
| **1 Scoping** | 🟡 | AL2/AL3-Schalter (global + Override), TISAX-Level in Settings | Scope-Objekt (Prüfziele/Standorte/Geltungsbereich/Ausschlüsse) + **Filterung** der Control-/Template-/Risiko-Sets | FE S · Backend M |
|
||||
| **2 Kontextaufnahme** | 🟡 | Stammdaten→Variablen | Geführter, **bedingter Fragebogen** + wiederverwendbare Faktenobjekte + Propagation | M |
|
||||
| **3 Rollen & Verantwortlichkeiten** | 🟡 | RBAC/Rollen je Mandant, RACI-Matrix (Lieferanten) | ISMS-Rollenmodell (GF/ISB/DSB/IT), **Funktionstrennungs-Prüfung**, Rollen-Platzhalter in Dokumenten (ISB-Bestellung) | Backend M · FE S |
|
||||
| **4 Richtlinien & VA** | ✅🟡 | Template-Tailoring (a) voll: variablenbasiert, Klausel-Ein/Ausblendung, Freigabe | (b) Upload+Control-Mapping (Upload offen); (c) „später erstellen" → Aufgabe (hängt an 2.3) | (a) ✅ · (b) M · (c) S |
|
||||
| **5 Asset-Inventar** | ✅ | Assets & BIA: C/I/A, Schutzbedarf, Eigentümer, Vererbung, Abhängigkeiten, Risiko-Verknüpfung | „unvollständig/kein Eigentümer" → Aufgabe (Trigger) | S |
|
||||
| **6 Risikomanagement** | ✅🟡 | 5×5-Heatmap, Register, Behandlung, Maßnahmen, Control-Verknüpfung | VDA-Risiko-Katalog-Auswahl; Maßnahme→Aufgabe (2.3); Methodik konfigurierbar (siehe Offen #2) | M |
|
||||
| **7 Control-Zuordnung & Reifegrad** | 🟡→🟥 | Coverage-Matrix, Beleg-Verknüpfung, Lieferanten-Reifegrad-Muster | **Control-Assessment-Oberfläche** (SoA ist bisher Platzhalter) + Reifegrad-Selbsteinschätzung + Gap-Markierung je Teilanforderung | Backend L · FE L · SME L |
|
||||
| **8 Gap- & Maßnahmenableitung** | 🟥 | Ergebnisse aus 6/7 | Aggregation/Dedup/Priorisierung → konsolidierte Gap-Liste (hängt an 2.3) | M |
|
||||
| **9 Assessment-Readiness** | 🟥 | validierte Objekte, Coverage-Daten | Reifegrad-Dashboard + vorausgefüllte VDA-ISA-Katalogsicht + **Export** (koppelt an offenen DOCX/PDF-Export) | Backend M · FE L |
|
||||
| **Wizard-Shell (implizit)** | 🟥 | — | Geführter Multi-Step-Flow: Zustand, Fortschritt, Gates, Wiederaufnahme, „bestätigt/unbestätigt"-Propagation | M–L |
|
||||
|
||||
---
|
||||
|
||||
## 5. Was wirklich neu gebaut werden muss (verdichtete Liste)
|
||||
|
||||
1. **Wizard-Shell / State-Machine** (Flow, Fortschritt, Gates, Resume). 🟥 M–L
|
||||
2. **Generisches Aufgaben-Modul** (2.3) — Keystone. 🟡→ M–L
|
||||
3. **Generischer Validierungs-Workflow** (2.1) inkl. externer-Berater-Rolle. 🟡→ M
|
||||
4. **Regel-/Mapping-Layer generalisiert** (Antwort→Controls/Assets/Risiken). 🟡→ L
|
||||
5. **Scope-Objekt + Filter-Engine** (Schritt 1). 🟥 M
|
||||
6. **Dynamischer Fragebogen** (Schritt 2). 🟥 M
|
||||
7. **ISMS-Rollenmodell + Funktionstrennung** (Schritt 3). 🟥 M
|
||||
8. **Control-Assessment / Reifegrad-Gap-Engine** (Schritt 7, SoA-Surface). 🟥 L
|
||||
9. **Gap-Konsolidierung** (Schritt 8). 🟥 M
|
||||
10. **Assessment-Readiness-Dashboard + Export** (Schritt 9, koppelt an DOCX/PDF-Export). 🟥 L
|
||||
11. **Umsetzungshinweis-Content-Modell + Inline-Panel** (2.2). 🟡→ Backend/FE S, Content L
|
||||
12. **Versionierung/Diff + Update-Propagation** (2.4; löst zugleich offenen destruktiven Re-Import). 🟡→ M–L
|
||||
|
||||
**Direkt wiederverwendbar (kaum/kein Neubau):** Assets/BIA · Risikoanalyse (Kern) · Richtlinien-Template-Engine · Control-Katalog VDA-ISA · AL2/AL3-Schalter · Vier-Augen-Freigabe (als Muster) · Coverage-Matrix · Lieferanten-Anforderungs-/Reifegrad-Engine (als Muster) · Audit-Log · Multi-Tenant/RBAC · Stammdaten→Variablen.
|
||||
|
||||
---
|
||||
|
||||
## 6. Größte Komplexitäten & Risiken (priorisiert)
|
||||
|
||||
1. **Fachcontent ist der kritische Pfad** (bestätigt der Fahrplan selbst): regelfähige Vorlagen, VDA-Risiko-Katalog, **Umsetzungshinweise je Teilanforderung**, Reifegrad-Logik. Muss **parallel und früh** von der Beratung erstellt werden — sonst blockiert er M3/M4/M5/M7.
|
||||
2. **Regel-/Mapping-Engine (Generalisierung).** Heute: Klausel-Flags + Variablen + Lieferanten-Engine. Neu: eine Antwort steuert Dokument-Klauseln **und** Control-Relevanz **und** Risiko-/Asset-Bezug. Architektur-Kernrisiko — Regel-Syntax und Testbarkeit früh festzurren.
|
||||
3. **Control-Assessment/Reifegrad (Schritt 7).** Das „SoA & Controls"-Modul ist bisher nur Platzhalter; hier entsteht die eigentliche Assessment-Oberfläche. Größter einzelner FE/Backend-Block.
|
||||
4. **Versionierung & Update-Propagation.** Solange Re-Import destruktiv ist und Richtlinien keine echte Versionierung haben, sind laufende Kundeninstanzen bei Katalog-/Template-Updates gefährdet. Muss vor „Katalog lebt beim Kunden" gelöst sein.
|
||||
5. **Keystones Aufgaben-Modul & Validierungs-Workflow** früh, sonst teurer Umbau (Schritte 3–9 hängen daran).
|
||||
6. **Export/North-Star** (vorausgefüllter VDA-ISA-Katalog) koppelt an den offenen DOCX/PDF-Export.
|
||||
|
||||
---
|
||||
|
||||
## 7. Antworten auf die offenen Entscheidungspunkte des Fahrplans (Kap. 7), PO-Sicht
|
||||
|
||||
1. **Upload-Gap-Check:** Start mit **manueller Control-Zuordnung** (deckt sich mit dem bereits geplanten Word-Upload); automatischer Inhalt↔Anforderung-Abgleich später als KI-Ausbaustufe (koppelt an geplanten „KI-Wizard").
|
||||
2. **Risiko-Methodik:** **mandantenspezifisch konfigurierbar**, aber zuvor die zwei bestehenden Matrizen (5×5 Risikoanalyse / 4×4 FB-80-04 im Richtlinienmodul) **auf eine zentrale Skala vereinheitlichen** (steht bereits als offener Punkt).
|
||||
3. **Versionierung/Propagation:** **nicht-destruktives Update mit Diff** und expliziter Übernahme je Instanz (löst zugleich den destruktiven Re-Import). Voraussetzung für „Katalog beim Kunden".
|
||||
4. **Validierungs-Granularität:** **pro Objekt** (einzelne Richtlinie/Risiko/Control-Bewertung) **plus** Modul-Gate — die Freigabe-Logik ist heute schon objektbezogen (Richtlinien) und wird generalisiert.
|
||||
5. **Aufgaben-Modul:** existiert **nur teilweise** (Maßnahmen-Kanban, risikobezogen) → **muss generalisiert werden**; die Task-Erzeugung ist mitzuplanen (Keystone).
|
||||
6. **Reifegrad-Vorschlag:** **regelbasiert vorgeschlagen, mit Pflicht zur Bestätigung** durch den Bearbeiter (entspricht dem vorhandenen Lieferanten-Reifegrad-Freigabe-Muster).
|
||||
|
||||
---
|
||||
|
||||
## 8. Empfohlene Reihenfolge (für die Aufgaben-Definition)
|
||||
|
||||
Angelehnt an M1–M7 des Fahrplans, sortiert nach Abhängigkeit und Wiederverwendung:
|
||||
|
||||
1. **Querschnitt-Keystones zuerst:** Aufgaben-Modul (2.3), Validierungs-Workflow (2.1), Versionierung/Diff (2.4), Wizard-Shell. *(sonst später teurer Umbau)*
|
||||
2. **Regel-/Scope-Fundament:** Scope-Objekt + Filter (Schritt 1), Regel-/Mapping-Layer, Fragebogen (Schritt 2).
|
||||
3. **Wiederverwendung einklinken:** Richtlinien (Schritt 4, größtenteils vorhanden), Assets (Schritt 5, vorhanden), Risiko (Schritt 6, Kern vorhanden + VDA-Katalog).
|
||||
4. **Neuer Kern:** Control-Assessment/Reifegrad (Schritt 7), Gap-Konsolidierung (Schritt 8).
|
||||
5. **Output:** Assessment-Readiness-Dashboard + Export (Schritt 9).
|
||||
6. **Durchgängig parallel:** Fachcontent (SME/Beratung) + Umsetzungshinweise (2.2).
|
||||
|
||||
---
|
||||
|
||||
## 9. Nächster Schritt
|
||||
Auf dieser Basis die **Entwickler-Aufgaben als Epics/Stories** definieren — vorgeschlagene Epic-Schnitte:
|
||||
**E1** Aufgaben-Modul · **E2** Validierungs-Workflow · **E3** Wizard-Shell & Navigation · **E4** Scope & Regel-/Mapping-Layer · **E5** Fragebogen/Fakten · **E6** ISMS-Rollen & Funktionstrennung · **E7** Richtlinien-Anbindung (Upload/Control-Mapping) · **E8** Risiko-Katalog & -Anbindung · **E9** Control-Assessment/Reifegrad-Gap · **E10** Gap-Konsolidierung · **E11** Assessment-Readiness/Export · **E12** Versionierung/Propagation · **E13** Umsetzungshinweise (Content+Panel) · **C1** Fachcontent (querlaufend).
|
||||
|
||||
> Offen für die Feinspezifikation: Regel-Syntax, Aufgaben-Objekt-Schema, Reifegrad-Scoring-Formel, Export-Format des VDA-ISA-Katalogs. Diese vier zuerst festzurren — sie determinieren den Rest.
|
||||
@@ -0,0 +1,133 @@
|
||||
# Onboarding-Wizard — Entwickler-Backlog (2 Full-Stack-Lanes, parallel auf `dev`)
|
||||
|
||||
Grundlage: `Onboarding_Wizard_Fahrplan_Detail.md` (Berater), `STAND-dev-branch.md` (Ist-Stand `dev`, 2026-07-24), `Onboarding-Wizard-Machbarkeitsanalyse.md`.
|
||||
Aufbau: **2 Entwickler**, je **vertikaler Feature-Slice** (BE+FE+Migration) auf eigenem **Feature-Branch unter `dev`**. Umfang: **kompletter Wizard**. Manueller Richtlinien-Upload: **UI/Modell jetzt, Datei-Speicher später** (Storage-Adapter gestubbt).
|
||||
|
||||
> Fachliche Zulieferungen (SME/Berater) sind je Epic mit **🧩 SME** markiert und in `Berater-Anweisung-Fachcontent.md` als Arbeitspakete C1–C9 ausformuliert.
|
||||
|
||||
---
|
||||
|
||||
## 0. Arbeitsmodell, Branching & Definition of Done
|
||||
|
||||
**Branching**
|
||||
- Basis-Branch: **`dev`** (nicht `main`). Alle Feature-Branches zweigen von `dev` ab, PR-Ziel ist `dev`.
|
||||
- Namensschema: **`dev/<lane><n>-<slug>`** — z. B. `dev/a1-wizard-shell`, `dev/b2-regel-engine`.
|
||||
- **Dev A = Lane A** („Flow, Governance & Bewertung"), **Dev B = Lane B** („Engines, Inhalte & Ausgabe").
|
||||
- Häufig auf `dev` rebasen (mind. täglich), kleine PRs je Epic, Review durch die jeweils andere Person.
|
||||
|
||||
**Definition of Done (jede Story)**
|
||||
- `npx tsc --noEmit` → `npm run lint` → `npm run build` grün (der `prebuild`-Guard-Check läuft mit).
|
||||
- Neue Server-Action-Datei ist in **`scripts/check-module-guards.ts`** eingetragen (Modul-Key oder `EXEMPT`).
|
||||
- Neues tenant-gebundenes Modell in **`TENANT_MODELS`** (`src/server/db.ts`) **und** RLS-Policy in der Migration.
|
||||
- Migration erstellt (Prisma-7-Flow) inkl. manuell angehängtem **RLS-DO-Block**; läuft via `migrate deploy`.
|
||||
- Wenn Seed/Vorlagenpaket berührt: `python3 seed/isms-vorlagenpaket-v2/_verify.py` → **OK**.
|
||||
- Browser-Verifikation der Kern-Flows; Demo-Daten/Seed weiterhin lauffähig.
|
||||
|
||||
**Geteilte „Hot Files" — nur koordiniert anfassen (Konflikt-Risiko):**
|
||||
`prisma/schema.prisma` · Migrationsreihenfolge · `src/lib/modules.ts` · `scripts/check-module-guards.ts` · `src/server/db.ts` (`TENANT_MODELS`) · das Wizard-Shell-Step-Registry (Lane A liefert, Lane B registriert Steps).
|
||||
→ Migrationen **nie gleichzeitig** ohne Absprache erzeugen; jede Lane hält ihre Migration isoliert und rebased vor dem Erstellen.
|
||||
|
||||
---
|
||||
|
||||
## 1. Zuerst festzurren — Foundation-Contracts (gemeinsam, VOR den Lanes)
|
||||
|
||||
Ein kurzer gemeinsamer Branch **`dev/foundation-contracts`** (1 Person federführend, andere reviewt), **zuerst nach `dev` gemergt**. Legt die vier Verträge fest, die alles andere determinieren:
|
||||
|
||||
1. **Aufgaben-Objekt-Schema** — Erweiterung des bestehenden `Task`/`TaskComment` (heute Typ `policy_approval`) um: `type` (`document_create` / `evidence_provide` / `technical` / `organizational` / `validation`), `owner`, `dueDate`, `priority`, `status`, **`resources` (JSON: tool/budget/personnel/time)**, **`origin` (auslösender Schritt)**, polymorphe Verknüpfung (`control` / `risk` / `document` / `asset`). RLS wie gehabt.
|
||||
2. **Objekt-Validierungs-Status** — einheitliches Enum `offen → in_bearbeitung → zur_validierung → validiert | zurueckgewiesen(+Kommentar)` als wiederverwendbares Feld/Mixin über Objekttypen; Rolle **`external_validator`** (externer Berater).
|
||||
3. **Regel-/Mapping-DSL** — Vertrag: `Bedingung(Antwort/Scope/Flag) → Wirkung(Klausel ein/aus · Control relevant/irrelevant · Risiko/Asset-Bezug · Aufgabe)`. JSON-basiert, testbar; baut auf vorhandenen Handlebars-Flags + Lieferanten-Anforderungs-Engine auf.
|
||||
4. **Assessment-Readiness-Export-Format** — Datenschema des vorausgefüllten VDA-ISA-Katalogs (Control → Teilanforderungen → Reifegrad/Belege/offene Punkte/Status „bestätigt|unbestätigt").
|
||||
|
||||
**Aufwand:** M (Schema-/Typ-Definitionen + Migration `tasks`-Erweiterung). **DoD:** Typen/Interfaces + Task-Migration gemergt, damit beide Lanes darauf bauen.
|
||||
|
||||
---
|
||||
|
||||
## 2. Lane A — Dev A: „Flow, Governance & Bewertung"
|
||||
|
||||
| Epic | Branch | Hängt ab von | Aufwand | 🧩 SME |
|
||||
|---|---|---|---|:--:|
|
||||
| **A1 Wizard-Shell & Navigation** | `dev/a1-wizard-shell` | Foundation | M–L | – |
|
||||
| **A2 Scoping + AL2/AL3 zentral (Adminportal) + Scope-Filter** | `dev/a2-scoping-admin-al` | A1 | M | 🧩 C1 |
|
||||
| **A3 Validierungs-Workflow generalisieren** | `dev/a3-validation-workflow` | Foundation, B1 | M | – |
|
||||
| **A4 ISMS-Rollen & Funktionstrennung (Schritt 3)** | `dev/a4-isms-rollen` | A1, A3 | M | 🧩 C7 |
|
||||
| **A5 Asset-Anbindung Wizard (Schritt 5, Reuse)** | `dev/a5-assets-step` | A1 | S | – |
|
||||
| **A6 Risiko-Katalog & Anbindung (Schritt 6)** | `dev/a6-risiko-katalog` | A1, B2 | M–L | 🧩 C4 |
|
||||
| **A7 Control-Assessment & Reifegrad/Gap (Schritt 7, SoA)** | `dev/a7-control-assessment` | A2, B1, B2, B5 | L | 🧩 C5, C6 |
|
||||
| **A8 Gap-Konsolidierung (Schritt 8)** | `dev/a8-gap-konsolidierung` | A6, A7, B1 | M | 🧩 C8 |
|
||||
|
||||
**A1 — Wizard-Shell & Navigation.** Neuer Bereich `src/app/(app)/onboarding/**` + `src/server/actions/onboarding.ts` (in `check-module-guards.ts` registrieren; neues Modul `onboarding` in `src/lib/modules.ts`). Multi-Step-State-Machine mit Fortschritt, **Gates** (Schritt „validiert" bevor weiter), **Wiederaufnahme**, und einem **Step-Registry**, in das Lane B ihre Schritt-Komponenten einklinkt (klare Datei-Trennung je Schritt). Persistenter Wizard-Fortschritt je Mandant. *Akzeptanz:* Flow ist resumierbar; Gates blockieren korrekt; Schritte sind als eigenständige Module registrierbar.
|
||||
|
||||
**A2 — Scoping + AL2/AL3 zentral im Adminportal.** (Explizite Anforderung.) Der **AL2/AL3-Schalter wird zentral im Superadmin-/Adminportal** gesetzt (`src/app/(platform)/admin/**` + `src/server/actions/admin.ts`/`platform.ts`) als Teil der Mandanten-Kern-Config — **einzige Quelle der Wahrheit**. Schritt 1 (Scoping) liest ihn **read-only** (nur Superadmin ändert), plus Prüfziele/Standorte/Geltungsbereich/Ausschlüsse → **Scope-Objekt**. Scope filtert nachgelagert Control-/Template-/Risiko-Sets (an vorhandene Coverage-Filter-Logik nach Assessment-Level andocken). *Akzeptanz:* AL nur im Adminportal änderbar; Änderung propagiert in Coverage/Zusatzanforderungen; nicht relevante Controls/Templates ausgeblendet. **🧩 C1** (AL2/AL3-Kennzeichnung + Prüfziel-Zuordnung je Control).
|
||||
|
||||
**A3 — Validierungs-Workflow generalisieren.** Den bestehenden Vier-Augen-Freigabe-/Task-Mechanismus (`policy_approval`) zu einem **generischen Objekt-Review** über alle Typen ausbauen (Modul/Richtlinie/Risiko/Control-Bewertung): Status-Feld (Foundation #2), Reviewer-Zuweisung inkl. **externer Berater**, Kommentare, „unbestätigt zählt nicht" in Auswertungen. Wiederverwendet `src/server/actions/tasks.ts` + `submitForApproval`. *Akzeptanz:* jedes Objekt trägt Review-Status; nur „validiert" zählt als bestätigt; externer Validierer-Rolle testbar.
|
||||
|
||||
**A4 — ISMS-Rollen & Funktionstrennung (Schritt 3).** ISMS-Rollenmodell (GF/ISB/DSB/IT) auf Basis vorhandener RBAC/RACI; **Funktionstrennungs-Prüfung** (z. B. ISB ≠ IT); Rollen-Platzhalter in Dokumente (ISB-Bestellung aus Vorlage). Konflikt → Hinweis/Aufgabe (A3/B1). *Akzeptanz:* Funktionstrennungs-Konflikt wird erkannt und als Aufgabe ausgewiesen. **🧩 C7**.
|
||||
|
||||
**A5 — Asset-Anbindung Wizard (Schritt 5).** Dünne Wizard-Schicht auf das bestehende Assets/BIA-Modul (C/I/A, Schutzbedarf, Eigentümer, Abhängigkeiten sind vorhanden). Trigger „Inventar unvollständig / kein Eigentümer" → Aufgabe (B1). *Akzeptanz:* Wizard nutzt Bestands-Assets; Trigger erzeugt Aufgabe.
|
||||
|
||||
**A6 — Risiko-Katalog & Anbindung (Schritt 6).** Bewertungs-/Register-Kern existiert (5×5, Behandlung, Control-Verknüpfung). Neu: **kuratierter Standard-/VDA-Risiko-Katalog** (Auswahl + eigene Ergänzung), Verknüpfung Asset/Control, Maßnahme→Aufgabe (B1). *Akzeptanz:* VDA-geforderte Risiken auswählbar; inakzeptables Risiko hat Behandlung; Maßnahmen erzeugen Aufgaben. **🧩 C4** (Kataloginhalt + Standardmaßnahmen).
|
||||
|
||||
**A7 — Control-Assessment & Reifegrad/Gap (Schritt 7, SoA).** Größter Block: baut die bislang fehlende **SoA-/Control-Oberfläche**. Je Control: Beleg-Verknüpfung (Dok/Risiko/Asset), **Reifegrad-Selbsteinschätzung** mit regelbasiertem Vorschlag (aus Belegen) **+ Pflichtbestätigung** (Muster: Lieferanten-Reifegrad-Freigabe), Markierung offener Teilanforderungen; unter Ziel → Aufgabe. Nutzt Coverage-Daten + Foundation-Export-Schema. *Akzeptanz:* jede relevante Teilanforderung adressiert; Reifegradvorschlag nachvollziehbar an Belege gekoppelt. **🧩 C5** (Reifegrad-Logik), **🧩 C6** (Umsetzungshinweis-Content, via B5).
|
||||
|
||||
**A8 — Gap-Konsolidierung (Schritt 8).** Aggregation/Dedup/Priorisierung (Muss/AL3 = hoch) aus Schritt 6+7 zu einer konsolidierten Gap-/Maßnahmenliste, abgeglichen mit Aufgaben (B1). *Akzeptanz:* keine Dopplungen; jeder offene Punkt hat Priorität + ggf. Aufgabe. **🧩 C8** (Priorisierungslogik/Quick-Wins).
|
||||
|
||||
---
|
||||
|
||||
## 3. Lane B — Dev B: „Engines, Inhalte & Ausgabe"
|
||||
|
||||
| Epic | Branch | Hängt ab von | Aufwand | 🧩 SME |
|
||||
|---|---|---|---|:--:|
|
||||
| **B1 Aufgaben-Modul erweitern** | `dev/b1-tasks-erweiterung` | Foundation | M | – |
|
||||
| **B2 Regel-/Mapping-Layer** | `dev/b2-regel-engine` | Foundation | L | 🧩 C2 |
|
||||
| **B3 Fragebogen/Fakten (Schritt 2)** | `dev/b3-fragebogen` | A1, B2 | M | 🧩 C2 |
|
||||
| **B4 Richtlinien: Import-bei-Aktivierung + manueller Upload + Control-Mapping (Schritt 4 + Menü)** | `dev/b4-richtlinien-import-upload` | Foundation | M–L | 🧩 C3 |
|
||||
| **B5 Umsetzungshinweise (Content-Modell + Inline-Panel)** | `dev/b5-umsetzungshinweise` | A1 | S (Code) | 🧩 C6 |
|
||||
| **B6 Versionierung/Propagation** | `dev/b6-versionierung` | B4 | M–L | – |
|
||||
| **B7 Assessment-Readiness & Export (Schritt 9)** | `dev/b7-readiness-export` | A7, A8 | L | 🧩 C9 |
|
||||
|
||||
**B1 — Aufgaben-Modul erweitern.** Das generische `Task`-Modell (heute `policy_approval`) um die Foundation-Felder erweitern; **Auto-Generierung** aus Triggern (Schritt 3/4/6/7/8, Zurückweisung) als **Vorschlag mit Bestätigung**; Ressourcenfelder editierbar; Verknüpfungen Control/Risiko/Dok/Asset; Anzeige/Filter im bestehenden Modul „Aufgaben" (`src/app/(app)/tasks/`). *Akzeptanz:* Trigger erzeugt Aufgabenvorschlag mit korrekten Verknüpfungen/Ressourcen; Bestätigung übernimmt.
|
||||
|
||||
**B2 — Regel-/Mapping-Layer.** Umsetzung der DSL (Foundation #3) als testbare Engine `src/lib/rules/**`: Antwort/Scope/Flag → Klausel-Ein/Ausblendung (Handlebars-Flags erweitern), betroffene Controls/Assets/Risiken, Aufgaben-Trigger. Isoliert + unit-getestet. *Akzeptanz:* Regelauswertung deterministisch, mit Testfällen belegt; Änderung einer Antwort propagiert sichtbar. **🧩 C2** (Antwort→Wirkung-Mapping).
|
||||
|
||||
**B3 — Fragebogen/Fakten (Schritt 2).** Dynamischer, **bedingter Fragebogen**; Antworten als **wiederverwendbare Faktenobjekte** (an vorhandene zentrale Variablen/Stammdaten andocken, ohne die Sperre der zentralen Variablen zu verletzen). Bedingte Sichtbarkeit über B2. *Akzeptanz:* Antworten wiederverwendbar; Änderung propagiert in abhängige Objekte/Platzhalter. **🧩 C2** (Fragenkatalog).
|
||||
|
||||
**B4 — Richtlinien: Import-bei-Aktivierung + manueller Upload + Control-Mapping.** (Explizite Anforderung.) Zwei Wege:
|
||||
- **(a) Vorlagen-Import bei Modul-Aktivierung:** Wird das **Richtlinien-Modul im Superadmin/Adminportal aktiviert**, wird das Vorlagenpaket **mandantenweit importiert** — die vorhandene **nicht-destruktive** Logik (`prisma/import-policies.ts`, Diff/Upsert/`archivedAt`) als **serverseitig auslösbare Aktion/Job** kapseln (statt nur CLI/Seed). Zusätzlich Button „Vorlagen importieren/aktualisieren" (Admin bzw. `/policies`). Idempotent, Änderungsreport.
|
||||
- **(b) Manueller Upload eigener Richtlinien direkt im Menü `/policies`:** Einstiegspunkt + Metadaten-/Block-Modell + **Control-Zuordnung** jetzt bauen; **Datei-Persistenz über einen Storage-Adapter-Interface stubben** (echtes Storage-Backend = Folge-Epic **S1**, außerhalb dieses Batches). Upload erfasst Datei-Referenz/Platzhalter + Control-Mapping in die Nachweislage. *Akzeptanz:* Modul-Aktivierung importiert Vorlagen nicht-destruktiv; unter `/policies` existiert „Eigene Richtlinie hochladen" mit Control-Zuordnung; Storage-Adapter ist gekapselt und später ohne UI-Änderung verdrahtbar. **🧩 C3** (regelfähige Vorlagen-Auszeichnung).
|
||||
|
||||
**B5 — Umsetzungshinweise (Content-Modell + Inline-Panel).** Strukturiertes Hinweis-Modell (org/tech/Nachweise/Vorlagen-Verweis/**Ressourcenindikation**), Scope-/Antwort-Filter (B2), kontextsensitives Inline-Panel an Teilanforderungen/Risiken/Templates. Code klein — **Inhalt ist der Aufwand**. *Akzeptanz:* passende Hinweise werden nach Scope/Antworten gefiltert eingeblendet; führen bei Maßnahme zu Aufgabe (B1). **🧩 C6**.
|
||||
|
||||
**B6 — Versionierung/Propagation.** Versionierung von Katalog/Templates/Risiko-Katalog + **Instanz-Referenz auf genutzte Version** + **Diff & gesteuerte Übernahme** bei Updates (löst zugleich den heute noch offenen Richtlinien-Diff und flankiert den nicht-destruktiven Re-Import). *Akzeptanz:* laufende Kundeninstanz bekommt bei Update einen Diff und übernimmt kontrolliert; nichts wird still überschrieben.
|
||||
|
||||
**B7 — Assessment-Readiness & Export (Schritt 9).** Reifegrad-Dashboard je Kapitel/gesamt, vorausgefüllte **VDA-ISA-Katalogsicht**, Maßnahmenplan; „bestätigt vs. unbestätigt" nach Validierungsstatus (A3); **Export** (koppelt an den offenen DOCX/PDF-Export). *Akzeptanz:* Kennzahlen stimmen mit Einzelbewertungen; Export vollständig/nachvollziehbar. **🧩 C9** (Auswertungs-/Interpretationstexte, Export-Layout).
|
||||
|
||||
---
|
||||
|
||||
## 4. Sequenz / Meilensteine (2 Lanes im Takt)
|
||||
|
||||
| Takt | Dev A (Lane A) | Dev B (Lane B) | Gate |
|
||||
|---|---|---|---|
|
||||
| **M0** | Foundation-Contracts (gemeinsam) | Foundation-Contracts (gemeinsam) | Contracts + `tasks`-Migration auf `dev` |
|
||||
| **M1** | A1 Wizard-Shell | B1 Tasks-Erweiterung · B2 Regel-Engine (Kern) | Shell + Task-API stehen |
|
||||
| **M2** | A2 Scoping/Admin-AL | B4 Richtlinien-Import/Upload · B3 Fragebogen | AL zentral · Import läuft |
|
||||
| **M3** | A3 Validierung · A4 Rollen | B5 Umsetzungshinweise | Review generisch |
|
||||
| **M4** | A5 Assets · A6 Risiko-Katalog | B6 Versionierung | Katalog/Risiko nutzbar |
|
||||
| **M5** | A7 Control-Assessment (SoA) | (Puffer/Review A7) · Start B7 | Kern-Bewertung steht |
|
||||
| **M6** | A8 Gap-Konsolidierung | B7 Readiness & Export | North-Star: Readiness-Export |
|
||||
|
||||
**Kürzester Pfad zur Assessment-Readiness:** M0→M1→M2→…→M6. Governance (A3/B1/B5/B6) läuft bewusst mit, nicht am Ende.
|
||||
|
||||
---
|
||||
|
||||
## 5. Explizite Anforderungen (Kurz-Referenz)
|
||||
- **AL2/AL3 zentral im Adminportal:** → **A2** (einzige Quelle im Superadmin/Admin; Scoping liest read-only; treibt Coverage/AL3-Zusatzanforderungen).
|
||||
- **Richtlinien-Vorlagen-Import bei Modul-Aktivierung + manueller Upload im Menü:** → **B4** (Import nicht-destruktiv on-enable; manueller Upload jetzt als UI/Modell/Control-Mapping, Datei-Speicher via Storage-Adapter später = Folge-Epic **S1**).
|
||||
|
||||
## 6. Außerhalb dieses Batches (Folge-Epics)
|
||||
- **S1 Storage-Backend** (Coolify-Volume/MinIO) — schaltet echten Datei-Upload (B4b, Netzplan REG-NET, Nachweis-Upload) scharf.
|
||||
- **Paket 4** (SMTP/Einladung), **NIS2-Modul**, **Admin Phase 2** (Impersonation/Plan-Limits) — unverändert im Backlog.
|
||||
|
||||
---
|
||||
|
||||
## 7. Nächster Schritt
|
||||
Foundation-Contracts (Abschnitt 1) gemeinsam finalisieren und mergen → dann Lanes starten. Fachliche Zulieferung C1–C9 parallel anstoßen (siehe `Berater-Anweisung-Fachcontent.md`), sonst werden C2/C3/C4/C5/C6 zum kritischen Pfad für A2/A6/A7 und B2/B3/B4/B5.
|
||||
@@ -0,0 +1,174 @@
|
||||
# Onboarding-Wizard — Story-Backlog (umsetzungsreif, mit Fachcontent C1–C9)
|
||||
|
||||
Basis: `Wizard-Entwickler-Backlog.md` (2 Lanes) + Fachcontent `Fachcontent_Wizard_C1-C9` + Dev-Stand `dev` (2026-07-24).
|
||||
Jede Story: **ID · Titel · (Lane/Branch) · User Story · Akzeptanzkriterien · Technik/Dateien · Fachcontent · Abhängigkeit**.
|
||||
|
||||
**Konventionen (für alle Stories):** DoD wie im Backlog (§0: `tsc`+`lint`+`build`/Guard-Check, `TENANT_MODELS`+RLS, Migration+RLS-DO-Block, `_verify.py`→OK bei Seed-Änderung, Browser-Verifikation). Story-Größe: S/M/L.
|
||||
**Fachcontent-Referenzen:** C1 = Scoping/AL-Tabelle (412 Anf.), C2 = Fragenkatalog+Wirkung, C3 = Vorlagen-Annotation, C4 = Risikokatalog (39 Risiken), C5 = Reifegrad R0–R3, C6 = Umsetzungshinweise (~397 Blöcke), C7 = Rollen/FT-01…06, C8 = Priorisierung/Dedup, C9 = Auswertung/Export.
|
||||
|
||||
---
|
||||
|
||||
## F — Foundation-Contracts (`dev/foundation-contracts`, gemeinsam, zuerst mergen)
|
||||
|
||||
### F1 — Aufgaben-Objekt-Schema erweitern (M)
|
||||
**Als** Entwickler **möchte ich** das bestehende `Task`/`TaskComment`-Modell um Wizard-Felder erweitern, **damit** alle Schritte Aufgaben einheitlich erzeugen.
|
||||
- **AK:** `Task` besitzt `type` (`document_create|evidence_provide|technical|organizational|validation`), `owner`, `dueDate`, `priority`, `status`, `resources` (JSON: tool/budget/personnel/time), `origin` (Schritt), polymorphe Verknüpfung `control|risk|document|asset`. Bestehender Typ `policy_approval` bleibt lauffähig.
|
||||
- **Technik:** `prisma/schema.prisma` (`Task`), Migration `tasks_wizard_fields`, `TENANT_MODELS`+RLS, `src/server/actions/tasks.ts` erweitern (in `check-module-guards.ts` registriert).
|
||||
- **Fachcontent:** C2 §8 (Task-Trigger), C8 (Priorität/Dedup als Feldsemantik).
|
||||
|
||||
### F2 — Einheitlicher Objekt-Validierungsstatus + externe-Validierer-Rolle (M)
|
||||
**Als** ISB/Berater **möchte ich** jedes bewertbare Objekt gleich validieren.
|
||||
- **AK:** wiederverwendbares Status-Feld `offen|in_bearbeitung|zur_validierung|validiert|zurueckgewiesen(+Kommentar)`; Rolle `external_validator` in RBAC; „unbestätigt zählt nicht" ist als Query-Helfer verfügbar.
|
||||
- **Technik:** Mixin/Enum in `schema.prisma`; RBAC-Recht; baut auf `submitForApproval`/`tasks.ts`.
|
||||
- **Fachcontent:** C5 (Validierungsstatus je Beleg), C9 (bestätigt/unbestätigt).
|
||||
|
||||
### F3 — Regel-/Mapping-DSL-Vertrag (M)
|
||||
**Als** Entwickler **möchte ich** einen testbaren Regel-Vertrag, **damit** Antworten/Scope/Flags Wirkungen auslösen.
|
||||
- **AK:** JSON-Schema `Bedingung(Antwort|Scope|Flag) → Wirkung(Klausel|Control|Risiko|Asset|Aufgabe)`; Referenz-Testfälle aus C2 §5 (Q-FEAT-01…10) grün.
|
||||
- **Technik:** `src/lib/rules/dsl.ts` (Typen) + Unit-Test-Harness. Noch keine UI.
|
||||
- **Fachcontent:** C2 (Wirkungsmatrix), C1 (Scope-Bedingung-Spalte).
|
||||
|
||||
### F4 — Wizard-Variablen/Flags erweitern (`variables.schema.json`) (S)
|
||||
**Als** Content-Owner **möchte ich** neue Flags/Variablen registriert haben, **damit** `_verify.py` sie kennt.
|
||||
- **AK:** `FLAG_PROTOTYPE_PROTECTION`, `FLAG_ISB_EXTERNAL`, `FLAG_ISB_INTERNAL` + fehlende `ROLE_*`/`TECH_*` aus C2 ergänzt; `python3 _verify.py` → **OK**.
|
||||
- **Technik:** `seed/isms-vorlagenpaket-v2/variables.schema.json`.
|
||||
- **Fachcontent:** C0 (offene Punkte 2), C2 §3–6, C7 §3. **Abh.:** vor B2/B3/B4/A4.
|
||||
|
||||
---
|
||||
|
||||
## Lane A — Dev A
|
||||
|
||||
### A1 — Wizard-Shell & Navigation (`dev/a1-wizard-shell`)
|
||||
**A1-1 Step-Registry & State-Machine (L).** Multi-Step-Flow mit Fortschritt, Gates, Wiederaufnahme; Schritte als registrierbare Module.
|
||||
- **AK:** Fortschritt je Mandant persistent; ein Gate blockiert „weiter", bis das Vorgänger-Objekt `validiert` ist (F2); Steps sind per Registry einklinkbar (Lane B liefert Step-Inhalte).
|
||||
- **Technik:** `src/app/(app)/onboarding/**`, `src/server/actions/onboarding.ts`, neues Modul `onboarding` in `src/lib/modules.ts`; Migration `onboarding_progress`.
|
||||
**A1-2 Fortschritts-/Status-Dashboard-Kachel (S).** Kachel „Onboarding-Fortschritt" analog vorhandener Dashboard-Kachel.
|
||||
|
||||
### A2 — Scoping + AL2/AL3 zentral im Adminportal (`dev/a2-scoping-admin-al`)
|
||||
**A2-1 AL2/AL3 zentral im Admin/Superadmin (M).** *(Explizite Anforderung.)*
|
||||
- **AK:** Der Assessment-Level (AL2/AL3) wird **ausschließlich** im Admin-/Superadmin-Portal je Mandant gesetzt (einzige Quelle); im Scoping read-only; treibt bestehende Coverage-Filter + `FLAG_HIGH/VERY_HIGH_PROTECTION`.
|
||||
- **Technik:** `src/app/(platform)/admin/**`, `src/server/actions/admin.ts`/`platform.ts`; Mandanten-`/settings` verliert die Änderungs-Kompetenz (nur Anzeige).
|
||||
**A2-2 Scope-Objekt + Filter-Engine (M).**
|
||||
- **AK:** Scoping erfasst Prüfziele (IS/Prototyp/Datenschutz), Standorte, Geltungsbereich, Ausschlüsse → Scope-Objekt; Filter blendet Anforderungen nach **AL + Flag + Prüfziel** exakt gemäß C1 aus (z. B. `HOCH` nur bei `FLAG_HIGH_PROTECTION`; 8.x nur bei Prototyp).
|
||||
- **Technik:** Scope-Modell + `src/lib/scope-filter.ts`; Import der C1-Tabelle als Datenquelle je Anforderung.
|
||||
- **Fachcontent:** **C1** (AL2/AL3 + Prüfziel + Scope-Bedingung je Anforderung, 412 Zeilen). **Abh.:** F3, A1.
|
||||
|
||||
### A3 — Validierungs-Workflow generalisieren (`dev/a3-validation-workflow`)
|
||||
**A3-1 Generisches Objekt-Review (M).**
|
||||
- **AK:** Richtlinie/Risiko/Control-Bewertung/Modul tragen Review-Status (F2); Reviewer-Zuweisung inkl. `external_validator`; Kommentare; Auswertung zählt nur `validiert`.
|
||||
- **Technik:** Ausbau `src/server/actions/tasks.ts` + `submitForApproval`; generische Review-Komponente.
|
||||
- **Fachcontent:** C9 §1 (bestätigt/unbestätigt). **Abh.:** F1, F2.
|
||||
|
||||
### A4 — ISMS-Rollen & Funktionstrennung (`dev/a4-isms-rollen`)
|
||||
**A4-1 Rollenmodell + Platzhalter (M).**
|
||||
- **AK:** Rollen `ROLE_MANAGEMENT/ISB/IT_LEAD/HR_LEAD/DPO` erfassbar (aus C2 Abschnitt B), befüllen Vorlagen-Platzhalter; ISB-Bestellung aus Vorlage generierbar.
|
||||
- **Technik:** Rollen-Modell; Anbindung zentrale Variablen (`src/lib/policy-variables.ts`).
|
||||
**A4-2 Funktionstrennungs-Prüfung FT-01…06 (M).**
|
||||
- **AK:** Regeln **FT-01…FT-06** aus C7 implementiert; Konflikt/Lücke → Hinweis + Aufgabe (F1); Option „Trennung herstellen" **oder** „kompensierende Kontrolle dokumentieren".
|
||||
- **Fachcontent:** **C7** (Rollen, FT-Regeln, `VA-00_ISB-Bestellung.md`, Flags `FLAG_ISB_EXTERNAL/INTERNAL`). **Abh.:** F4, A3.
|
||||
|
||||
### A5 — Asset-Anbindung Wizard (`dev/a5-assets-step`)
|
||||
**A5-1 Asset-Schritt auf Bestandsmodul (S).**
|
||||
- **AK:** Schritt 5 nutzt vorhandenes Assets/BIA (C/I/A, Schutzbedarf, Eigentümer); Trigger „unvollständig/kein Eigentümer" → Aufgabe (F1). Keine Doppel-Datenhaltung.
|
||||
|
||||
### A6 — Risiko-Katalog & Anbindung (`dev/a6-risiko-katalog`)
|
||||
**A6-1 Risiko-Katalog-Datenmodell + Import (M).**
|
||||
- **AK:** 39 Katalog-Risiken (11 Kategorien) importiert mit ID `R-<KAT>-<nr>`, Controls, Asset-Typen, Standardmaßnahmen, Default `E/S`; erweiterbar; „nicht anwendbar"-Begründung möglich.
|
||||
- **Technik:** Risiko-Katalog-Seed + Auswahl-UI im vorhandenen Risikomodul; 5×5 wie C4.
|
||||
**A6-2 Maßnahme → Aufgabe + Restrisiko (M).**
|
||||
- **AK:** ausgewähltes Risiko → Bewertung (5×5) → Behandlung → Standardmaßnahme erzeugt Aufgabe (F1), verknüpft Risiko+Control; Restrisiko > Akzeptanz erfordert dokumentierte Akzeptanz (VA-09).
|
||||
- **Fachcontent:** **C4** (Katalog + Bewertungslogik + Standardmaßnahmen). **Abh.:** F1, B2.
|
||||
|
||||
### A7 — Control-Assessment & Reifegrad/Gap (`dev/a7-control-assessment`, SoA)
|
||||
**A7-1 Control-/SoA-Oberfläche (L).**
|
||||
- **AK:** je relevantem Control: Belege verknüpfen (Dok/Risiko/Asset), Teilanforderungen sichtbar (aus C1/`mapping.json`), offene Teilanforderungen markiert; Inline-Umsetzungshinweise (B5/C6).
|
||||
**A7-2 Reifegrad-Engine R0–R3 + Pflichtbestätigung (L).**
|
||||
- **AK:** Reifegrad-Vorschlag exakt nach **C5**-Regeln (R0/R1a-c/R2/R3, Sonderfälle, Aktualitätsregel ≤12 Mon., Deckelung bei Widerspruch); Vorschlag ist **an Belege gekoppelt und nachvollziehbar**; Bearbeiter-Bestätigung Pflicht; Zielreifegrad nach C5 §3 (AL2→2, AL3→3, HOCH/SEHR HOCH→3).
|
||||
- **AK:** Reifegrad < Ziel / offene Teilanforderung → Aufgabe (F1).
|
||||
- **Technik:** `src/app/(app)/soa/**` (bislang Platzhalter) + `src/server/actions/soa.ts`; Reifegrad-Berechnung `src/lib/maturity.ts` (unit-getestet gegen C5-Beispiele).
|
||||
- **Fachcontent:** **C5** (Reifegradlogik), **C6** (Umsetzungshinweise). **Abh.:** A2, B1, B2, B5.
|
||||
|
||||
### A8 — Gap-Konsolidierung (`dev/a8-gap-konsolidierung`)
|
||||
**A8-1 Aggregation + Dedup + Priorisierung (M).**
|
||||
- **AK:** offene Punkte aus Schritt 6/7 zusammengeführt; **Dedup-Schlüssel** (Control+Teilanforderung / verknüpfte Aufgabe) nach C8 §2; Priorität **Hoch/Mittel/Niedrig** nach C8 §1 mit Zusatzsortierung (betroffene Controls, Risikohöhe, Aufwand); keine Dopplungen; jeder Punkt hat Priorität + ggf. Aufgabe.
|
||||
**A8-2 Quick-Win-Kennzeichnung (S).**
|
||||
- **AK:** Quick-Win-Kriterien aus C8 §3; im Maßnahmenplan hervorgehoben („erst Quick-Wins").
|
||||
- **Fachcontent:** **C8**. **Abh.:** A6, A7, B1.
|
||||
|
||||
---
|
||||
|
||||
## Lane B — Dev B
|
||||
|
||||
### B1 — Aufgaben-Modul erweitern (`dev/b1-tasks-erweiterung`)
|
||||
**B1-1 Auto-Generierung mit Bestätigung (M).**
|
||||
- **AK:** Trigger aus Schritt 3/4/6/7/8 + Zurückweisung erzeugen **Aufgabenvorschlag** (Typ/Verknüpfung/Ressourcen aus F1); Bearbeiter bestätigt/verwirft; Anzeige/Filter im Modul „Aufgaben" (`src/app/(app)/tasks/`).
|
||||
- **Fachcontent:** C2 §8 (konkrete Trigger). **Abh.:** F1.
|
||||
|
||||
### B2 — Regel-/Mapping-Engine (`dev/b2-regel-engine`)
|
||||
**B2-1 Engine-Kern + Klausel-Flags (L).**
|
||||
- **AK:** DSL (F3) ausgewertet: Antwort/Scope/Flag → Klausel ein/aus (Handlebars-Flags), Control-Relevanz, Risiko-/Asset-Bezug, Aufgabe; deterministisch, unit-getestet gegen **C2** Q-FEAT-01…10.
|
||||
- **Technik:** `src/lib/rules/**`; koppelt an vorhandene `{{#if FLAG}}`-Renderer + Lieferanten-Anforderungs-Engine.
|
||||
**B2-2 Propagation bei Antwortänderung (M).**
|
||||
- **AK:** Änderung einer Antwort propagiert sichtbar in abhängige Objekte/Platzhalter/Controls.
|
||||
- **Fachcontent:** **C2** (Wirkungsmatrix), C1 (Scope-Bedingungen). **Abh.:** F3, F4.
|
||||
|
||||
### B3 — Fragebogen/Fakten (`dev/b3-fragebogen`)
|
||||
**B3-1 Dynamischer, bedingter Fragebogen (M).**
|
||||
- **AK:** Abschnitte A–F aus C2 mit Antworttypen + Anzeige-Bedingungen; Antworten als wiederverwendbare Faktenobjekte; Baseline-Fragen (E) als vorbelegte Defaults aus `Technische-Sicherheits-Baseline.md` (nur bestätigen).
|
||||
- **AK:** zentrale Variablen bleiben serverseitig gesperrt (nur `/settings`), Fragebogen respektiert das.
|
||||
- **Technik:** `src/app/(app)/onboarding/steps/context/**` (im A1-Registry); Faktenmodell + Migration.
|
||||
- **Fachcontent:** **C2** (Fragen A–F, Baseline-Defaults). **Abh.:** A1, B2, F4.
|
||||
|
||||
### B4 — Richtlinien: Import-bei-Aktivierung + manueller Upload + Control-Mapping (`dev/b4-richtlinien-import-upload`)
|
||||
**B4-1 Vorlagen-Import bei Modul-Aktivierung (M).** *(Explizite Anforderung.)*
|
||||
- **AK:** Aktiviert der Superadmin das Richtlinien-Modul, wird das Paket mandantenweit **nicht-destruktiv** importiert (bestehende Logik `prisma/import-policies.ts` als Server-Action/Job gekapselt); Button „Vorlagen importieren/aktualisieren" in Admin und `/policies`; idempotent, Änderungsreport.
|
||||
**B4-2 Manueller Upload eigener Richtlinien im Menü (M).** *(Explizite Anforderung; Storage später.)*
|
||||
- **AK:** unter `/policies` „Eigene Richtlinie hochladen" mit **Pflicht-Control-Zuordnung** (Multi-Select Control-Katalog, optional Anforderungs-IDs, siehe C3 §4); Metadaten/Block-Modell angelegt; Datei-Persistenz über gestubbtes **Storage-Adapter-Interface** (echtes Backend = Folge-Epic S1); Zuordnung fließt als `<!-- REQ -->`-Äquivalent in die Nachweislage (Schritt 7).
|
||||
**B4-3 Proto/DS-Vorlagen P01/D01 + mapping.json (M).**
|
||||
- **AK:** neue Vorlagen `P01_Prototypenschutz.md` (+ `VA-20`) und `D01_Datenschutz.md` nach C3-Konvention angelegt; `mapping.json`-Einträge im gleichen Schema (8.x/9.x); `FLAG_PROTOTYPE_PROTECTION` genutzt; `_verify.py` (um neue Anker erweitert) → **OK**.
|
||||
- **Fachcontent:** **C3** (Annotationskonvention + P01/D01), C1/C6 (Dekomposition 8.x/9.x). **Abh.:** F4.
|
||||
|
||||
### B5 — Umsetzungshinweise (`dev/b5-umsetzungshinweise`)
|
||||
**B5-1 Hinweis-Datenmodell + Import (S Code).**
|
||||
- **AK:** Hinweis-Objekt je Teilanforderung mit Feldern **organisatorisch/technisch/Nachweise/Vorlage/Ressourcen/AL-Filter**; Import der ~397 C6-Blöcke; Baseline-Referenzen (`BL-*`) statt harter Werte.
|
||||
**B5-2 Kontextsensitives Inline-Panel (S).**
|
||||
- **AK:** Panel an Teilanforderung/Risiko/Template; gefiltert nach Scope/Antworten (B2) und AL; Ressourcen-Hinweis mit Beschaffungsbedarf → Aufgabe (F1).
|
||||
- **Fachcontent:** **C6** (Hinweise), C0 offener Punkt 3 (Baseline-Codes vor Verdrahtung gegen `Technische-Sicherheits-Baseline.md` normalisieren). **Abh.:** A1.
|
||||
|
||||
### B6 — Versionierung/Propagation (`dev/b6-versionierung`)
|
||||
**B6-1 Versionierung Katalog/Templates/Risiko + Instanz-Referenz (M).**
|
||||
- **AK:** Kundeninstanz referenziert genutzte Template-/Katalog-Version; Änderungen erzeugen Diff.
|
||||
**B6-2 Gesteuerte Übernahme (Diff) (M).**
|
||||
- **AK:** bei Update erhält die Instanz einen Diff mit kontrollierter Übernahme; nichts wird still überschrieben (ergänzt nicht-destruktiven Re-Import + löst offenen Richtlinien-Diff). **Abh.:** B4.
|
||||
|
||||
### B7 — Assessment-Readiness & Export (`dev/b7-readiness-export`)
|
||||
**B7-1 Reifegrad-Dashboard + Interpretationstexte (M).**
|
||||
- **AK:** Aggregation je Kapitel/gesamt (Ø, „unbestätigt zählt nicht"); Textbänder nach C9 §1; Kennzahlen (Anteil bestätigt, offene Punkte je Priorität, Abdeckung je Prüfziel); dynamische „nächste Schritte" (C9 §2).
|
||||
**B7-2 VDA-ISA-Katalog-Export (L).**
|
||||
- **AK:** Export-Layout exakt nach **C9 §3** (Felder Control-ID/Frage/Reifegrad/Status/Umsetzungsbeschreibung MUSS→SOLL→HOCH→SEHR HOCH/Belege/offene Punkte); Reihenfolge IS→Proto→DS; „unbestätigt" markiert; **XLSX** (Katalog+Kennzahlen) + DOCX/PDF-Management-Summary (koppelt an bestehenden Export); Zusatzartefakte (Maßnahmenplan, Nachweisregister) nach C9 §4.
|
||||
- **Fachcontent:** **C9**. **Abh.:** A7, A8.
|
||||
|
||||
---
|
||||
|
||||
## Content-Integration & offene Fachpunkte (aus C0)
|
||||
|
||||
| ID | Story | Owner | Abh. |
|
||||
|---|---|---|---|
|
||||
| **X1** | Neue `FLAG_*`/Variablen in `variables.schema.json` (siehe F4) | B (mit SME) | vor B2/B3/B4/A4 |
|
||||
| **X2** | P01/D01 + `VA-20` Vorlagen + `mapping.json`-Einträge (B4-3) | B (mit SME) | C3 |
|
||||
| **X3** | Baseline-`BL-*`-Codes aus C6 gegen `Technische-Sicherheits-Baseline.md` normalisieren | B5 (mit SME) | vor B5-Verdrahtung |
|
||||
| **X4** | ISB-Freigabe aller neuen/angepassten Fachtexte (VA/Richtlinien/P01/D01) | ISB (fachlich, kein Code) | vor Produktivsetzung |
|
||||
|
||||
---
|
||||
|
||||
## Sprint-Vorschlag (2 Lanes)
|
||||
|
||||
- **Sprint 0:** F1–F4 (gemeinsam) → mergen.
|
||||
- **Sprint 1:** A1 · B1 + B2-1.
|
||||
- **Sprint 2:** A2 (+C1) · B4 (+C3) + B3 (+C2).
|
||||
- **Sprint 3:** A3 · A4 (+C7) · B5 (+C6).
|
||||
- **Sprint 4:** A5 · A6 (+C4) · B6.
|
||||
- **Sprint 5:** A7 (+C5/C6).
|
||||
- **Sprint 6:** A8 (+C8) · B7 (+C9).
|
||||
|
||||
> „Definition of Ready" je Story: zugehöriges C-Paket eingespielt und (wo Seed) `_verify.py` → **OK**. Fehlt der Fachcontent, bleibt die Story blockiert (kritischer Pfad: C2 → C1/C3 → C5/C6).
|
||||
@@ -0,0 +1,35 @@
|
||||
# Fachcontent-Zulieferung C1–C9 — Übersicht
|
||||
|
||||
Fachliche Zulieferung (SME/Berater) für den Onboarding-Wizard, gemäß `BeraterAnweisungFachcontent.md` und `WizardEntwicklerBacklog.md`. Alle Pakete sind ID-konsistent zum bestehenden Vorlagenpaket `isms-vorlagenpaket-v2` (`mapping.json`, `variables.schema.json`, Baseline `BL-*`). Prüfziele: Informationssicherheit (Paketbasis), Prototypenschutz (8.x) und Datenschutz (9.x) als Erweiterung.
|
||||
|
||||
## Lieferpakete
|
||||
|
||||
| WP | Datei | Schaltet frei (Backlog) | Inhalt |
|
||||
|---|---|---|---|
|
||||
| **C1** | `C1_Scoping-AL-Pruefziel.md` | A2 | AL2/AL3-Kennzeichnung + Prüfziel + Scope-Bedingung je Anforderung — **412 Anforderungen** (316 IS + 72 Proto + 24 DS) |
|
||||
| **C2** | `C2_Fragenkatalog-Wirkung.md` | B2, B3 | Fragenkatalog (A–F) + Antwort→Wirkung (Variable/Flag/Control/Risiko/Aufgabe), gekoppelt an `variables.schema.json` |
|
||||
| **C3** | `C3_Vorlagen-Annotation.md` | B4 | Annotationskonvention (REQ/IMPL-Anker, `{{#if FLAG}}`, Baseline-Variablen), Ist-Bestätigung (`_verify.py → OK`), Erweiterung P01/D01 |
|
||||
| **C4** | `C4_Risikokatalog.md` | A6 | Standard-/VDA-Risiko-Katalog (**39 Risiken, 11 Kategorien**) mit Controls, Assets, Standardmaßnahmen, Default-5×5-Einschätzung |
|
||||
| **C5** | `C5_Reifegradlogik.md` | A7 | Generische Beleg→Reifegrad-Regel + control-spezifische Tabelle (alle 45 IS-Controls + Proto/DS-Gruppen), Zielreifegrad, Offene-Punkt-Kriterium |
|
||||
| **C6** | `C6_Umsetzungshinweise.md` | B5, A7 | Umsetzungshinweise je Teilanforderung (**~397 Blöcke über 79 Controls**): org/tech, Nachweise, Vorlage, Ressourcen, AL-Filter |
|
||||
| **C7** | `C7_Rollen-Funktionstrennung.md` | A4 | Soll-Rollenmodell, Funktionstrennungs-Regeln (FT-01…06), ISB-Bestellungs-Vorlage im Paket-Stil |
|
||||
| **C8** | `C8_Priorisierung-Gap.md` | A8 | Prioritätsregeln (Hoch/Mittel/Niedrig), Dedup-Kriterien, Quick-Win-Definition |
|
||||
| **C9** | `C9_Auswertung-Export.md` | B7 | Reifegrad-Interpretationstexte, nächste Schritte, VDA-ISA-Export-Layout (bestätigt/unbestätigt) |
|
||||
|
||||
## Konsistenz-Anker
|
||||
|
||||
- **Anforderungs-IDs** = `mapping.json`-IDs (z. B. `4.1.2-H1`); Proto/DS neu im gleichen Schema (`8.1.1-M1`, `9.1.1-M1`).
|
||||
- **Flags/Variablen** = `variables.schema.json` (Single Source of Truth). Neue Flags (`FLAG_PROTOTYPE_PROTECTION`, `FLAG_ISB_EXTERNAL/INTERNAL`) sind in C3/C7 vermerkt und dort zuerst zu ergänzen.
|
||||
- **Technische Werte** = Baseline `BL-*` (C6 referenziert, nie hart kodiert).
|
||||
- **Vorlagenpaket** unverändert; `python3 seed/isms-vorlagenpaket-v2/_verify.py` → **OK**.
|
||||
|
||||
## Offene Punkte / Abhängigkeiten für die Umsetzung
|
||||
|
||||
1. **Proto/DS-Vorlagen** (`P01`, `D01`) und zugehörige `mapping.json`-Einträge sind noch anzulegen (C3 Abschnitt 3) — die Anforderungsdekomposition + Hinweise (C1/C5/C6) liegen bereits vor.
|
||||
2. **Neue `FLAG_*`** vor Nutzung in `variables.schema.json` ergänzen, damit `_verify.py` sie kennt.
|
||||
3. **Baseline-IDs in C6**: Agenten haben teils sprechende `BL-*`-Codes ergänzt, die über den dokumentierten Satz (BL-IAM/CRY/OPS/NET/EP/PHY/HR/SUP/DEL/GOV/PROJ) hinausgehen — vor Verdrahtung gegen `Technische-Sicherheits-Baseline.md` normalisieren.
|
||||
4. **ISB-Freigabe** der neuen/angepassten Fachtexte ist der abschließende fachliche Schritt (steht im Backlog offen auf `dev`).
|
||||
|
||||
## Reihenfolge (kritischer Pfad)
|
||||
|
||||
C2 → C1/C3 (schalten B2/B3 und A2/B4 frei) → C4/C5/C6 (A6/A7/B5) → C7/C8/C9. Entspricht der Meilenstein-Sequenz M0–M6 des Backlogs.
|
||||
@@ -0,0 +1,444 @@
|
||||
# C1 — Scoping-Grundlage: AL2/AL3-Kennzeichnung + Prüfziel-Zuordnung je Anforderung
|
||||
|
||||
> **Schaltet frei:** A2 (Scoping / Admin-AL / Scope-Filter). **Grundlage:** `mapping.json` (Informationssicherheit, 316 Anforderungen) + Prototypenschutz/Datenschutz-Dekomposition (Erweiterung).
|
||||
|
||||
## Methodik (Zuordnungslogik)
|
||||
|
||||
Der Assessment-Level (AL) wird **zentral im Adminportal** gesetzt (Backlog A2) und ist read-only im Scoping. Die Zuordnung folgt der VDA-ISA-/TISAX-Systematik:
|
||||
|
||||
- **MUSS / SOLL** → Bestandteil von **AL2 und AL3** (Grundabsicherung; SOLL über `FLAG_INCLUDE_SHOULD` für Ziel-Reifegrad 3).
|
||||
- **HOCH** (Zusatz hoher Schutzbedarf) → relevant bei **hohem Schutzbedarf** (typisch AL3), Flag `FLAG_HIGH_PROTECTION`.
|
||||
- **SEHR HOCH** (Zusatz sehr hoher Schutzbedarf) → relevant bei **sehr hohem Schutzbedarf** (AL3), Flag `FLAG_VERY_HIGH_PROTECTION`.
|
||||
- **Prüfziel** steuert, ob ein ganzes Kapitel überhaupt im Scope ist (Informationssicherheit / Prototypenschutz / Datenschutz).
|
||||
- **Scope-Bedingung** = das Feature-Flag bzw. die Bedingung aus `mapping.json` (`condition`); ist keine gesetzt, gilt „immer im Scope" (sobald das Prüfziel aktiv ist).
|
||||
|
||||
Der Scope-Filter (A2) blendet je nach AL + Flags + Prüfziel die nicht relevanten Anforderungen aus. Spalte „Scope-Bedingung" ist maschinenlesbar an die `FLAG_*` aus `variables.schema.json` gekoppelt.
|
||||
|
||||
## Prüfziel Informationssicherheit (316 Anforderungen)
|
||||
|
||||
| Control | Anforderungs-ID | Typ | AL2 | AL3 | Prüfziel | Scope-Bedingung (Flag) |
|
||||
|---|---|---|:--:|:--:|---|---|
|
||||
| 1.1.1 | 1.1.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.1.1 | 1.1.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.1.1 | 1.1.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.1.1 | 1.1.1-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.1.1 | 1.1.1-M5 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.1.1 | 1.1.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.1.1 | 1.1.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.1.1 | 1.1.1-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.1.1 | 1.1.1-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.2.1 | 1.2.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.1 | 1.2.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.1 | 1.2.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.1 | 1.2.1-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.1 | 1.2.1-M5 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.1 | 1.2.1-M6 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.2 | 1.2.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.2 | 1.2.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.2 | 1.2.2-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.2 | 1.2.2-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.2 | 1.2.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.2.2 | 1.2.2-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.2.2 | 1.2.2-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.2.3 | 1.2.3-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.2.3 | 1.2.3-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.2.3 | 1.2.3-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.2.3 | 1.2.3-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.2.3 | 1.2.3-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.3.1 | 1.3.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.1 | 1.3.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.1 | 1.3.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.2 | 1.3.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.2 | 1.3.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.2 | 1.3.2-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.2 | 1.3.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.3 | 1.3.3-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.3 | 1.3.3-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.3 | 1.3.3-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.3 | 1.3.3-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.3 | 1.3.3-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.3 | 1.3.3-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.4 | 1.3.4-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.4 | 1.3.4-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.3.4 | 1.3.4-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.4 | 1.3.4-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.4 | 1.3.4-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.4 | 1.3.4-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.4 | 1.3.4-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.3.4 | 1.3.4-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 1.4.1 | 1.4.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.4.1 | 1.4.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.4.1 | 1.4.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.4.1 | 1.4.1-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.4.1 | 1.4.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.4.1 | 1.4.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.4.1 | 1.4.1-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.4.1 | 1.4.1-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.5.1 | 1.5.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.5.1 | 1.5.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.5.1 | 1.5.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.5.1 | 1.5.1-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.5.1 | 1.5.1-M5 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.5.1 | 1.5.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.5.2 | 1.5.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.5.2 | 1.5.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.5.2 | 1.5.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.1 | 1.6.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.1 | 1.6.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.1 | 1.6.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.1 | 1.6.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.1 | 1.6.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.1 | 1.6.1-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.1 | 1.6.1-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.1 | 1.6.1-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.1 | 1.6.1-S6 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.1 | 1.6.1-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 1.6.2 | 1.6.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.2 | 1.6.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.2 | 1.6.2-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.2 | 1.6.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.2 | 1.6.2-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.2 | 1.6.2-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.2 | 1.6.2-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.2 | 1.6.2-H2 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.2 | 1.6.2-H3 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.2 | 1.6.2-H4 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.2 | 1.6.2-H5 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.2 | 1.6.2-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 1.6.3 | 1.6.3-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.3 | 1.6.3-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.3 | 1.6.3-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 1.6.3 | 1.6.3-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.3 | 1.6.3-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.3 | 1.6.3-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.3 | 1.6.3-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.3 | 1.6.3-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.3 | 1.6.3-S6 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 1.6.3 | 1.6.3-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.3 | 1.6.3-H2 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.3 | 1.6.3-H3 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.3 | 1.6.3-H4 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.3 | 1.6.3-H5 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 1.6.3 | 1.6.3-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 2.1.1 | 2.1.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 2.1.1 | 2.1.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 2.1.1 | 2.1.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 2.1.1 | 2.1.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.1 | 2.1.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.2 | 2.1.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 2.1.2 | 2.1.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 2.1.2 | 2.1.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.2 | 2.1.2-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.2 | 2.1.2-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.3 | 2.1.3-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 2.1.3 | 2.1.3-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.3 | 2.1.3-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.3 | 2.1.3-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.3 | 2.1.3-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.3 | 2.1.3-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.3 | 2.1.3-S6 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.4 | 2.1.4-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 2.1.4 | 2.1.4-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.4 | 2.1.4-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 2.1.4 | 2.1.4-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 3.1.1 | 3.1.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 3.1.1 | 3.1.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 3.1.1 | 3.1.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 3.1.1 | 3.1.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 3.1.1 | 3.1.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 3.1.1 | 3.1.1-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 3.1.1 | 3.1.1-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 3.1.1 | 3.1.1-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 3.1.1 | 3.1.1-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 3.1.4 | 3.1.4-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 3.1.4 | 3.1.4-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 3.1.4 | 3.1.4-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 4.1.1 | 4.1.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.1 | 4.1.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.1 | 4.1.1-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 4.1.2 | 4.1.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.2 | 4.1.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.2 | 4.1.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.2 | 4.1.2-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.2 | 4.1.2-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.2 | 4.1.2-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 4.1.2 | 4.1.2-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 4.1.3 | 4.1.3-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.3 | 4.1.3-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.3 | 4.1.3-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.3 | 4.1.3-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.3 | 4.1.3-M5 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.3 | 4.1.3-M6 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.3 | 4.1.3-M7 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.1.3 | 4.1.3-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S10 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S6 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S7 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S8 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.1.3 | 4.1.3-S9 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.2.1 | 4.2.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.2.1 | 4.2.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 4.2.1 | 4.2.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.2.1 | 4.2.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.2.1 | 4.2.1-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.2.1 | 4.2.1-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.2.1 | 4.2.1-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 4.2.1 | 4.2.1-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 4.2.1 | 4.2.1-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 4.2.1 | 4.2.1-V2 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.1.1 | 5.1.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.1.1 | 5.1.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.1.1 | 5.1.1-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.1.2 | 5.1.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.1.2 | 5.1.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.1.2 | 5.1.2-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.1.2 | 5.1.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.1.2 | 5.1.2-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.1.2 | 5.1.2-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.1.2 | 5.1.2-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.1.2 | 5.1.2-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.2.1 | 5.2.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.1 | 5.2.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.1 | 5.2.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.1 | 5.2.1-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.1 | 5.2.1-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.1 | 5.2.1-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.2 | 5.2.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.2 | 5.2.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.2 | 5.2.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.3 | 5.2.3-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.3 | 5.2.3-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.3 | 5.2.3-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.3 | 5.2.3-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.3 | 5.2.3-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.3 | 5.2.3-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.3 | 5.2.3-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.3 | 5.2.3-S6 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.3 | 5.2.3-S7 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.3 | 5.2.3-S8 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.4 | 5.2.4-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.4 | 5.2.4-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.4 | 5.2.4-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.4 | 5.2.4-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.4 | 5.2.4-M5 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.4 | 5.2.4-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.4 | 5.2.4-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.4 | 5.2.4-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.4 | 5.2.4-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.4 | 5.2.4-H2 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.4 | 5.2.4-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.2.5 | 5.2.5-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.5 | 5.2.5-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.5 | 5.2.5-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.5 | 5.2.5-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.5 | 5.2.5-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.5 | 5.2.5-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.6 | 5.2.6-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.6 | 5.2.6-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.6 | 5.2.6-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.6 | 5.2.6-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.6 | 5.2.6-M5 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.6 | 5.2.6-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.6 | 5.2.6-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.6 | 5.2.6-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.6 | 5.2.6-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.6 | 5.2.6-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.2.7 | 5.2.7-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.7 | 5.2.7-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.7 | 5.2.7-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.7 | 5.2.7-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.7 | 5.2.7-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.8 | 5.2.8-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.8 | 5.2.8-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.8 | 5.2.8-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.8 | 5.2.8-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.8 | 5.2.8-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-H2 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-H3 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-H4 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-H5 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-H6 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-H7 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-V2 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.2.8 | 5.2.8-V3 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.2.9 | 5.2.9-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.9 | 5.2.9-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.2.9 | 5.2.9-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.2.9 | 5.2.9-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.9 | 5.2.9-H2 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.2.9 | 5.2.9-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.2.9 | 5.2.9-V2 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.2.9 | 5.2.9-V3 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.3.1 | 5.3.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.1 | 5.3.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.1 | 5.3.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.1 | 5.3.1-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.1 | 5.3.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.1 | 5.3.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.1 | 5.3.1-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.1 | 5.3.1-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.1 | 5.3.1-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.1 | 5.3.1-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 5.3.2 | 5.3.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.2 | 5.3.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.2 | 5.3.2-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.2 | 5.3.2-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.2 | 5.3.2-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 5.3.3 | 5.3.3-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.4 | 5.3.4-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.4 | 5.3.4-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 5.3.4-KI | 5.3.4-KI-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.4-KI | 5.3.4-KI-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.4-KI | 5.3.4-KI-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 5.3.4-KI | 5.3.4-KI-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.1 | 6.1.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.1 | 6.1.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.1 | 6.1.1-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.1 | 6.1.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.1 | 6.1.1-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.1 | 6.1.1-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 6.1.1 | 6.1.1-H2 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 6.1.1 | 6.1.1-H3 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 6.1.1 | 6.1.1-V1 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 6.1.1 | 6.1.1-V2 | SEHR HOCH | – | Ja | Informationssicherheit | `FLAG_VERY_HIGH_PROTECTION` |
|
||||
| 6.1.2 | 6.1.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.2 | 6.1.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.2 | 6.1.2-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.2 | 6.1.2-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.2 | 6.1.2-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.2 | 6.1.2-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.2 | 6.1.2-S3 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.2 | 6.1.2-S4 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.2 | 6.1.2-S5 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.3 | 6.1.3-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.3 | 6.1.3-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.3 | 6.1.3-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.3 | 6.1.3-M4 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.3 | 6.1.3-M5 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 6.1.3 | 6.1.3-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.3 | 6.1.3-S2 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 6.1.3 | 6.1.3-H1 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 6.1.3 | 6.1.3-H2 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 6.1.3 | 6.1.3-H3 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 6.1.3 | 6.1.3-H4 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 6.1.3 | 6.1.3-H5 | HOCH | – | Ja | Informationssicherheit | `FLAG_HIGH_PROTECTION` |
|
||||
| 7.1.1 | 7.1.1-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 7.1.1 | 7.1.1-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 7.1.1 | 7.1.1-S1 | SOLL | Ja | Ja | Informationssicherheit | `FLAG_INCLUDE_SHOULD` |
|
||||
| 7.1.2 | 7.1.2-M1 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 7.1.2 | 7.1.2-M2 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
| 7.1.2 | 7.1.2-M3 | MUSS | Ja | Ja | Informationssicherheit | immer im Scope |
|
||||
|
||||
## Prüfziel Prototypenschutz (72 Anforderungen) — Erweiterung
|
||||
|
||||
| Control | Anforderungs-ID | Typ | AL2 | AL3 | Prüfziel | Scope-Bedingung (Flag) |
|
||||
|---|---|---|:--:|:--:|---|---|
|
||||
| 8.1.1 | 8.1.1-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.1 | 8.1.1-S1 | SOLL | Ja | Ja | Prototypenschutz | `FLAG_INCLUDE_SHOULD` |
|
||||
| 8.1.2 | 8.1.2-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.2 | 8.1.2-S1 | SOLL | Ja | Ja | Prototypenschutz | `FLAG_INCLUDE_SHOULD` |
|
||||
| 8.1.3 | 8.1.3-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.3 | 8.1.3-S1 | SOLL | Ja | Ja | Prototypenschutz | `FLAG_INCLUDE_SHOULD` |
|
||||
| 8.1.3 | 8.1.3-S2 | SOLL | Ja | Ja | Prototypenschutz | `FLAG_INCLUDE_SHOULD` |
|
||||
| 8.1.4 | 8.1.4-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.4 | 8.1.4-S1 | SOLL | Ja | Ja | Prototypenschutz | `FLAG_INCLUDE_SHOULD` |
|
||||
| 8.1.4 | 8.1.4-S2 | SOLL | Ja | Ja | Prototypenschutz | `FLAG_INCLUDE_SHOULD` |
|
||||
| 8.1.4 | 8.1.4-H1 | HOCH | – | Ja | Prototypenschutz | `FLAG_HIGH_PROTECTION` |
|
||||
| 8.1.5 | 8.1.5-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.5 | 8.1.5-H1 | HOCH | – | Ja | Prototypenschutz | `FLAG_HIGH_PROTECTION` |
|
||||
| 8.1.6 | 8.1.6-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.6 | 8.1.6-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.6 | 8.1.6-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.7 | 8.1.7-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.7 | 8.1.7-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.7 | 8.1.7-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.7 | 8.1.7-M4 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.8 | 8.1.8-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.1.8 | 8.1.8-H1 | HOCH | – | Ja | Prototypenschutz | `FLAG_HIGH_PROTECTION` |
|
||||
| 8.2.1 | 8.2.1-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.1 | 8.2.1-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.1 | 8.2.1-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.1 | 8.2.1-M4 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.2 | 8.2.2-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.2 | 8.2.2-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.2 | 8.2.2-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.2 | 8.2.2-M4 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.2 | 8.2.2-M5 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.2 | 8.2.2-M6 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.3 | 8.2.3-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.3 | 8.2.3-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.3 | 8.2.3-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.3 | 8.2.3-M4 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.3 | 8.2.3-M5 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.3 | 8.2.3-M6 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.3 | 8.2.3-M7 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.4 | 8.2.4-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.4 | 8.2.4-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.4 | 8.2.4-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.5 | 8.2.5-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.5 | 8.2.5-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.5 | 8.2.5-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.6 | 8.2.6-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.6 | 8.2.6-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.6 | 8.2.6-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.6 | 8.2.6-M4 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.6 | 8.2.6-M5 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.7 | 8.2.7-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.2.7 | 8.2.7-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.3.1 | 8.3.1-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.3.1 | 8.3.1-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.3.1 | 8.3.1-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.3.1 | 8.3.1-M4 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.3.2 | 8.3.2-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.4.1 | 8.4.1-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.4.1 | 8.4.1-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.4.1 | 8.4.1-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.4.2 | 8.4.2-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.4.2 | 8.4.2-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.4.3 | 8.4.3-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.4.3 | 8.4.3-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.4.3 | 8.4.3-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.5.1 | 8.5.1-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.5.1 | 8.5.1-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.5.1 | 8.5.1-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.5.2 | 8.5.2-M1 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.5.2 | 8.5.2-M2 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.5.2 | 8.5.2-M3 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
| 8.5.2 | 8.5.2-M4 | MUSS | Ja | Ja | Prototypenschutz | Prüfziel Prototypenschutz aktiv |
|
||||
|
||||
> Hinweis Scope Prototypenschutz: Prüfziel bezieht sich in der aktuellen Konfiguration auf **Prototypenteile/-komponenten**; Controls 8.4.x (Test-/Erprobung) und 8.5.x (Ausstellungen/Film) sind per Scope-Regel `n.a.` und werden ausgeblendet.
|
||||
|
||||
## Prüfziel Datenschutz (24 Anforderungen) — Erweiterung
|
||||
|
||||
| Control | Anforderungs-ID | Typ | AL2 | AL3 | Prüfziel | Scope-Bedingung (Flag) |
|
||||
|---|---|---|:--:|:--:|---|---|
|
||||
| 9.1.1 | 9.1.1-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.2.1 | 9.2.1-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.2.1 | 9.2.1-M2 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.2.1 | 9.2.1-M3 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.2.1 | 9.2.1-M4 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.2.1 | 9.2.1-M5 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.2.1 | 9.2.1-M6 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.3.1 | 9.3.1-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.4.1 | 9.4.1-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.4.1 | 9.4.1-M2 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.5.1 | 9.5.1-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.5.2 | 9.5.2-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.5.2 | 9.5.2-M2 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.5.3 | 9.5.3-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.5.3 | 9.5.3-M2 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.5.3 | 9.5.3-M3 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.6.1 | 9.6.1-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.6.2 | 9.6.2-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.6.2 | 9.6.2-M2 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.6.2 | 9.6.2-M3 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.7.1 | 9.7.1-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.7.2 | 9.7.2-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.8.1 | 9.8.1-M1 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
| 9.8.1 | 9.8.1-M2 | MUSS | Ja | Ja | Datenschutz | Prüfziel Datenschutz aktiv (`FLAG_PERSONAL_DATA`) |
|
||||
@@ -0,0 +1,110 @@
|
||||
# C2 — Fragenkatalog + Antwort→Wirkung-Mapping
|
||||
|
||||
> **Schaltet frei:** B2 (Regel-/Mapping-Engine) und B3 (Fragebogen, Schritt 2). **Kritischer Pfad.**
|
||||
> **Grundlage:** `variables.schema.json` (Single Source of Truth der Wizard-Variablen und `FLAG_*`), `mapping.json` (`condition`-Flags je Anforderung), `Technische-Sicherheits-Baseline.md` (`BL-*`-Parameter).
|
||||
|
||||
## 1. Prinzip
|
||||
|
||||
Jede Frage erzeugt eine **Wirkung** auf genau vier Kanäle (DSL-Vertrag aus dem Backlog, Foundation #3):
|
||||
|
||||
1. **Variable/Platzhalter** — füllt einen `{{NAME}}`-Wert (z. B. `ORG_NAME`, `MFA_SCOPE`).
|
||||
2. **Feature-Flag** — setzt ein `FLAG_*` true/false, das `{{#if FLAG_X}}`-Blöcke in Vorlagen und die Control-Relevanz steuert.
|
||||
3. **Control/Risiko-Bezug** — schaltet Controls in den Scope und schlägt Katalog-Risiken (C4) vor.
|
||||
4. **Aufgabe** — erzeugt bei bestimmten Antworten einen Aufgabenvorschlag (Aufgaben-Modul).
|
||||
|
||||
Antworttypen: `text`, `single-select`, `multi-select`, `boolean`, `number/duration`. Baseline-Parameter (Abschnitt E) sind **vorbelegte Defaults** aus der Baseline; die Frage dient nur der Bestätigung/Anpassung, nicht der Ersteingabe.
|
||||
|
||||
Anzeige-Bedingungen referenzieren zuvor gesetzte Flags (bedingter Fragebogen).
|
||||
|
||||
---
|
||||
|
||||
## 2. Abschnitt A — Organisation & Geltungsbereich
|
||||
|
||||
| Frage-ID | Frage | Antworttyp | Anzeige-Bedingung | Wirkung |
|
||||
|---|---|---|---|---|
|
||||
| Q-ORG-01 | Vollständiger Name der Organisation? | text | immer | Variable `ORG_NAME` |
|
||||
| Q-ORG-02 | Kurzname/Abkürzung? | text | immer | Variable `ORG_SHORT` |
|
||||
| Q-ORG-03 | Geltungsbereich – Kurzlabel? | text | immer | Variable `ISMS_SCOPE` |
|
||||
| Q-ORG-04 | Geltungsbereich – Beschreibung (Standorte, Bereiche, Systeme, Ausschlüsse)? | text (lang) | immer | Variable `ISMS_SCOPE_DESCRIPTION`; speist Scope-Objekt (Schritt 1) |
|
||||
| Q-ORG-05 | Verarbeitet die Organisation personenbezogene Daten? | boolean | immer | Flag `FLAG_PERSONAL_DATA`; schaltet Prüfziel Datenschutz (9.x) + Controls 7.1.2 · Risiken R-DSGVO-* |
|
||||
| Q-ORG-06 | Werden Prototypen/schutzbedürftige Entwicklungsobjekte verarbeitet? | boolean | immer | schaltet Prüfziel Prototypenschutz (8.x); bei „nein" 8.x ausgeblendet |
|
||||
|
||||
## 3. Abschnitt B — Rollen (→ Schritt 3, Paket C7)
|
||||
|
||||
| Frage-ID | Frage | Antworttyp | Anzeige-Bedingung | Wirkung |
|
||||
|---|---|---|---|---|
|
||||
| Q-ROLE-01 | Oberste Leitung (Name/Funktion)? | text | immer | Variable `ROLE_MANAGEMENT` |
|
||||
| Q-ROLE-02 | Informationssicherheitsbeauftragte(r)/CISO? intern/extern? | text + single-select | immer | Variable `ROLE_ISB`; Funktionstrennungsprüfung (C7); bei fehlend → Aufgabe „ISB bestellen" |
|
||||
| Q-ROLE-03 | IT-Leitung / IT-Verantwortung (intern/extern)? | text | immer | Variable `ROLE_IT_LEAD`; Input Funktionstrennung ISB≠IT (C7) |
|
||||
| Q-ROLE-04 | Personalleitung? | text | immer | Variable `ROLE_HR_LEAD` |
|
||||
| Q-ROLE-05 | Datenschutzbeauftragte(r)? | text | `FLAG_PERSONAL_DATA` | Variable `ROLE_DPO` |
|
||||
|
||||
## 4. Abschnitt C — Governance & Betriebsrahmen
|
||||
|
||||
| Frage-ID | Frage | Antworttyp | Anzeige-Bedingung | Wirkung |
|
||||
|---|---|---|---|---|
|
||||
| Q-GOV-01 | Name des eingesetzten ISMS-Tools? | text | immer | Variable `TOOL_NAME` |
|
||||
| Q-GOV-02 | Ticket-/Workflow-System (Dokumentationsort)? | text | immer | Variable `TOOL_TICKET` (BL-IAM-07, BL-OPS-02/09) |
|
||||
| Q-GOV-03 | Verzeichnis-/IAM-System? | text | immer | Variable `TOOL_IAM` (BL-IAM-06/07) |
|
||||
| Q-GOV-04 | Revisions-/Prüfzyklus? | single-select (jährlich/…) | immer | Variable `REVIEW_CYCLE` (BL-HR-01, BL-GOV-01) |
|
||||
| Q-GOV-05 | Ziel-Reifegrad – SOLL-Anforderungen einbeziehen? | boolean (Default ja) | immer | Flag `FLAG_INCLUDE_SHOULD`; blendet alle `[SOLL]`-Blöcke ein/aus |
|
||||
|
||||
## 5. Abschnitt D — Feature-Fragen (steuern `FLAG_*`, Klauseln, Controls, Risiken)
|
||||
|
||||
Diese Fragen sind der Kern der Regel-Engine: jede Antwort blendet Vorlagenklauseln ein/aus, schaltet Controls in den Scope und schlägt Risiken vor.
|
||||
|
||||
| Frage-ID | Frage | Antworttyp | Anzeige-Bedingung | Wirkung (Flag · Klausel/Control · Risiko/Aufgabe) |
|
||||
|---|---|---|---|---|
|
||||
| Q-FEAT-01 | Schutzbedarf im Scope – höchste Stufe? (normal / hoch / sehr hoch) | single-select | immer | `FLAG_HIGH_PROTECTION` (hoch|sehr hoch), `FLAG_VERY_HIGH_PROTECTION` (sehr hoch), abgeleitet `FLAG_ELEVATED_PROTECTION`; blendet `[HOCH]`/`[SEHR HOCH]`-Anforderungen + `-elev`-Umsetzungstexte ein |
|
||||
| Q-FEAT-02 | Werden Cloud-Dienste genutzt? | boolean | immer | `FLAG_CLOUD_USED`; R12-Klauseln + Controls 5.3.2/5.3.4/6.1.3; Risiken R-CLOUD-* |
|
||||
| Q-FEAT-03 | Werden KI-/GenAI-Dienste genutzt? | boolean | immer | `FLAG_AI_USED`; R12-KI-Klauseln + Control 5.3.4-KI · VA-11; Risiko R-AI-* |
|
||||
| Q-FEAT-04 | Produktions-/OT-Umgebung vorhanden? | boolean | immer | `FLAG_OT_USED`; BL-NET-01 OT-Segmentierung; Risiken R-OT-* |
|
||||
| Q-FEAT-05 | Eigene Software-Entwicklung? | boolean | immer | `FLAG_DEV_INHOUSE`; R11-Klauseln + Controls 5.3.1 · VA-16; Risiko R-DEV-* |
|
||||
| Q-FEAT-06 | Mobiles Arbeiten / Homeoffice zugelassen? | boolean | immer | `FLAG_MOBILE_WORK`; R06-Klauseln + Control 2.1.4 |
|
||||
| Q-FEAT-07 | Mobile Endgeräte / Datenträger im Einsatz? | boolean | immer | `FLAG_MOBILE_DEVICES`; R06/BL-EP-*; Control 3.1.4; Risiko R-PHY-mobile |
|
||||
| Q-FEAT-08 | Eigene PKI / Zertifikatsverwaltung? | boolean | immer | `FLAG_CRYPTO_PKI`; BL-CRY-05 PKI-Klausel; Control 5.1.1 |
|
||||
| Q-FEAT-09 | Externe IT-Dienstleister genutzt? | boolean | immer | `FLAG_EXTERNAL_IT`; R13-Klauseln + Controls 6.1.1/6.1.3 · VA-10; Risiko R-SUP-*; bei „ja" → Aufgabe „Dienstleister-Selbstauskunft einholen" |
|
||||
| Q-FEAT-10 | Zugriff auf Kundensysteme (z. B. OEM)? | boolean | immer | `FLAG_CUSTOMER_SYSTEMS`; Klauseln „Konten in Kundensystemen" in R08/R13 (Controls 4.1.3/4.2.1/6.1.x) |
|
||||
|
||||
## 6. Abschnitt E — Technische Baseline (Defaults bestätigen/anpassen)
|
||||
|
||||
Vorbelegt aus `Technische-Sicherheits-Baseline.md`. Je Frage wird der Default angezeigt; Änderung schreibt die zugehörige Variable. Anzeige gruppiert; nur relevante bei gesetztem Flag.
|
||||
|
||||
| Frage-ID | Frage (Parameter) | Variable / Baseline-ID | Anzeige-Bedingung |
|
||||
|---|---|---|---|
|
||||
| Q-BL-01 | Passwort-Mindestlänge / Komplexität / Rotation | `PW_MIN_LENGTH`,`PW_COMPLEXITY`,`PW_ROTATION` (BL-IAM-01) | immer |
|
||||
| Q-BL-02 | MFA-Geltungsbereich | `MFA_SCOPE` (BL-IAM-02) | immer |
|
||||
| Q-BL-03 | Sitzungs-Timeout | `SESSION_TIMEOUT` (BL-IAM-03) | immer |
|
||||
| Q-BL-04 | Kontosperrung | `ACCOUNT_LOCKOUT` (BL-IAM-04) | immer |
|
||||
| Q-BL-05 | Rezertifizierungs-Frequenz | `RECERT_FREQ` (BL-IAM-05) | immer |
|
||||
| Q-BL-06 | Mindest-TLS / zulässige Algorithmen | `TLS_MIN`,`CRYPTO_ALGO` (BL-CRY-01/02) | immer |
|
||||
| Q-BL-07 | Patch-SLAs (kritisch/hoch/standard) | `PATCH_SLA_CRIT/HIGH/STD` (BL-OPS-01) | immer |
|
||||
| Q-BL-08 | Schwachstellenscan-Frequenz | `VULN_SCAN_FREQ` (BL-OPS-02) | immer |
|
||||
| Q-BL-09 | Malware-Update-Frequenz | `MALWARE_UPDATE` (BL-OPS-03) | immer |
|
||||
| Q-BL-10 | Log-Aufbewahrung | `LOG_RETENTION` (BL-OPS-04) | immer |
|
||||
| Q-BL-11 | Backup-Schema / Aufbewahrung / Testfrequenz | `BACKUP_SCHEME/RETENTION/TEST_FREQ` (BL-OPS-05/06) | immer |
|
||||
| Q-BL-12 | Penetrationstest-Frequenz | `PENTEST_FREQ` (BL-OPS-08) | `FLAG_ELEVATED_PROTECTION` |
|
||||
| Q-BL-13 | Eingesetzte Lösungen: MFA/Malware/Backup/SIEM/MDM/VPN | `TECH_MFA/MALWARE/BACKUP/SIEM/MDM/VPN` | jeweils bei zugehörigem Flag |
|
||||
| Q-BL-14 | Krypto-Standardvorgabe | `TECH_CRYPTO` (BL-CRY-02) | immer |
|
||||
|
||||
## 7. Abschnitt F — Dokument-Metadaten
|
||||
|
||||
| Frage-ID | Frage | Variable |
|
||||
|---|---|---|
|
||||
| Q-DOC-01 | Dokument-Version (Default 1.0) | `DOC_VERSION` |
|
||||
| Q-DOC-02 | Dokument-Datum | `DOC_DATE` |
|
||||
| Q-DOC-03 | Dokument-Status (Entwurf/In Freigabe/Freigegeben) | `DOC_STATUS` |
|
||||
|
||||
---
|
||||
|
||||
## 8. Aufgaben-Trigger aus Antworten (Auszug)
|
||||
|
||||
| Auslösende Antwort | Aufgabe (Typ) |
|
||||
|---|---|
|
||||
| Q-ROLE-02 „ISB nicht benannt" | `organizational` – ISB bestellen (verknüpft Control 1.2.2) |
|
||||
| Q-ROLE-02/03 ISB = IT-Verantwortung | `organizational` – Funktionstrennung herstellen/kompensieren (C7) |
|
||||
| Q-FEAT-09 „externe IT-Dienstleister = ja" | `evidence_provide` – Selbstauskunft/TISAX-Nachweis einholen (Control 6.1.1) |
|
||||
| Q-FEAT-02/03 Cloud/KI = ja, ohne Freigabeverfahren | `document_create` – Cloud-/KI-Freigabeverfahren aktivieren (VA-11) |
|
||||
| Q-BL-11 „kein Wiederherstellungstest" | `technical` – Restore-Test etablieren (BL-OPS-06, Control 5.2.9) |
|
||||
|
||||
> Hinweis: Die vollständige Antwort→Wirkung-Matrix wird maschinenlesbar als Regelobjekte (B2-DSL) hinterlegt; diese Tabelle ist die fachliche Spezifikation dafür. Neue `FLAG_*` bitte zuerst in `variables.schema.json` ergänzen (Single Source of Truth), dann Frage + Wirkung hier.
|
||||
@@ -0,0 +1,49 @@
|
||||
# C3 — Regelfähige Vorlagen-Auszeichnung (Annotationskonvention + Verify + Erweiterung)
|
||||
|
||||
> **Schaltet frei:** B4 (Richtlinien – Import + Upload + Control-Mapping). **Grundlage:** `isms-vorlagenpaket-v2/` (34 Vorlagen, `mapping.json`, `variables.schema.json`, `_verify.py`).
|
||||
|
||||
## 1. Ist-Zustand (Informationssicherheit) — vollständig annotiert
|
||||
|
||||
Das Vorlagenpaket ist für die **Informationssicherheit** bereits regelfähig ausgezeichnet und konsistent:
|
||||
|
||||
- **34 Vorlagen** – Leitlinie `L00`, Richtlinien `R01–R14`, Verfahren `VA-01 … VA-19`, plus `Technische-Sicherheits-Baseline.md`, `Nachweisregister_zentral.md`, `ISA-Mapping-Matrix.md`.
|
||||
- **316 Anforderungen** in `mapping.json` (312 ISA + 4 kundenspezifisch KI), je mit stabiler ID, `type`, `level`, `policy`, `condition`-Flag, `req_anchor`/`impl_anchor`, `verfahren`.
|
||||
- **`python3 _verify.py` → OK** (Render ohne offene Platzhalter für `FLAG_INCLUDE_SHOULD` an/aus, keine verwaisten Anker, keine Handlebars-Reste). **Dieser Lauf ist die Abnahmebedingung jeder Änderung.**
|
||||
|
||||
Für Informationssicherheit ist C3 damit als „bestätigt/konsistent" zu betrachten; die SME-Aufgabe ist Pflege + die Erweiterung um Prototypenschutz/Datenschutz (Abschnitt 3).
|
||||
|
||||
## 2. Annotationskonvention (verbindlich für alle Vorlagen)
|
||||
|
||||
| Konstrukt | Bedeutung | Beispiel |
|
||||
|---|---|---|
|
||||
| `{{VARIABLE}}` | Variable aus `variables.schema.json` | `{{ORG_NAME}}`, `{{MFA_SCOPE}}` |
|
||||
| `{{#if FLAG_X}} … {{/if}}` | Bedingter Block (Feature-Flag/Reifegrad/Schutzbedarf) | `{{#if FLAG_HIGH_PROTECTION}} … {{/if}}` |
|
||||
| `[MUSS]`/`[SOLL]`/`[HOCH]`/`[SEHR HOCH]` | Sichtbare Kennzeichnung der Anforderungsstufe | `- **[SOLL]** …` |
|
||||
| `<!-- REQ <id> -->` | Hidden-Anker vor einer Einzelanforderung | `<!-- REQ 4.1.2-H1 -->` |
|
||||
| `<!-- IMPL <control> -->` | Hidden-Anker vor dem Umsetzungstext (Control-gebündelt) | `<!-- IMPL 4.1.2 -->` |
|
||||
| `<!-- IMPL <control>-elev -->` | Umsetzungsvariante für erhöhten Schutzbedarf | `<!-- IMPL 4.1.2-elev -->` |
|
||||
| `{{LINK:ZIEL}}` | Laufzeit-Link (Dokument/Nachweisregister) | `{{LINK:R08#4.1.2}}` |
|
||||
| Verfahrensanker `<!-- FULFILLS <ids> | POLICY <Rxx> -->` | VA erfüllt Anforderungen | in `VA-*` |
|
||||
|
||||
**Regeln für eine regelfähige Auszeichnung**
|
||||
|
||||
1. Jede Einzelanforderung erhält genau einen `<!-- REQ <id> -->`-Anker, dessen ID exakt der `mapping.json`-`id` entspricht.
|
||||
2. `[SOLL]` immer in `{{#if FLAG_INCLUDE_SHOULD}}`, `[HOCH]` in `{{#if FLAG_HIGH_PROTECTION}}`, `[SEHR HOCH]` in `{{#if FLAG_VERY_HIGH_PROTECTION}}`. Der `condition`-Wert in `mapping.json` und der `{{#if}}` im Dokument müssen übereinstimmen.
|
||||
3. Feature-abhängige Klauseln (Cloud/KI/OT/Dev/Mobil/PKI/Extern/Kundensysteme) in den passenden `{{#if FLAG_*}}`-Block.
|
||||
4. Konkrete Zahlenwerte nie hart schreiben, sondern über Baseline-Variable (`{{PW_MIN_LENGTH}}` …) referenzieren.
|
||||
5. `<!-- … -->`-Anker im Dokument belassen (im Lesemodus unsichtbar); nur der PDF-/Druckexport entfernt sie.
|
||||
6. Nach jeder Änderung `python3 _verify.py` → **OK**.
|
||||
|
||||
## 3. Erweiterung: Prototypenschutz (P01) + Datenschutz (D01)
|
||||
|
||||
Das Paket ist „VDA ISA 2027 (Information Security)". Für die Prüfziele **Prototypenschutz (8.x)** und **Datenschutz (9.x)** sind Vorlagen + `mapping.json`-Einträge neu anzulegen — nach identischer Konvention. Vorschlag:
|
||||
|
||||
- **Neue Vorlage `P01_Prototypenschutz.md`** (Richtlinie Prototypenschutz) + Verfahren `VA-20_Prototypen-Zutritt-und-Transport`. Deckt 8.1.x (physische Sicherheit/Perimeter/Zonen/Zutritt/Einbruch/Besucher/Mandantentrennung), 8.2.x (Geheimhaltung/Unterauftragnehmer/Schulung/Klassifizierung/Bildaufzeichnung), 8.3.x (Transport/Lagerung). 8.4.x/8.5.x nur bei erweitertem Prüfziel.
|
||||
- **Neue Vorlage `D01_Datenschutz.md`** (Richtlinie Datenschutz) — kann `R14 Compliance & Datenschutz` erweitern/aufteilen; Verfahren `VA-18 Datenschutz-und-Compliance-Pflege` ist vorhanden. Deckt 9.1.x–9.8.x.
|
||||
- Je neuer Anforderung ein `mapping.json`-Eintrag im gleichen Schema (`id`,`policy`=P01/D01,`control`,`level`,`type`,`is_isa`=true,`req_anchor`,`impl_anchor`,`condition`,`requirement`,`verfahren`). Anforderungs-IDs siehe C1/C6-Dekomposition (`8.1.1-M1` …, `9.1.1-M1` …).
|
||||
- Neue `FLAG_*` bei Bedarf zuerst in `variables.schema.json` (z. B. `FLAG_PROTOTYPE_PROTECTION`), damit `_verify.py` sie kennt; Prototypenschutz-Klauseln in `{{#if FLAG_PROTOTYPE_PROTECTION}}`.
|
||||
- `_verify.py` um die neuen Verzeichnisse/Anker erweitern, dann → **OK**.
|
||||
|
||||
## 4. Control-Zuordnung beim manuellen Upload (B4b)
|
||||
|
||||
Für hochgeladene **eigene** Richtlinien (kein Template): Pflichtfeld „belegt Controls" (Multi-Select aus dem Control-Katalog). Optional je Control die abgedeckten Anforderungs-IDs. Diese Zuordnung fließt wie ein `<!-- REQ -->`-Anker in die Nachweislage (Schritt 7) — ohne Tailoring, aber mit voller Reifegrad-/Gap-Wirkung. Ein späterer Gap-Check (Dokumentinhalt ↔ Anforderungstext) ist als Option vorgesehen (offener Entscheidungspunkt).
|
||||
@@ -0,0 +1,169 @@
|
||||
# C4 — Standard-Risikokatalog (VDA ISA / TISAX)
|
||||
|
||||
**Paket:** C4 — Kuratierter Risiko-Katalog für den Onboarding-Wizard
|
||||
**Modul:** Risikomanagement
|
||||
**Referenzen:** R03 Risikomanagement · VA-09 Risikomanagement-Verfahren · VDA ISA (IS 1.x–7.x, Prototypenschutz 8.x, Datenschutz 9.x) · Baseline-Parameter BL-*
|
||||
|
||||
---
|
||||
|
||||
## 1. Nutzung im Wizard-Schritt „Risikomanagement"
|
||||
|
||||
Dieser Katalog wird dem Kunden im Onboarding-Wizard als kuratierte Vorauswahl typischer Informationssicherheits- und TISAX-Risiken angeboten. Der Ablauf:
|
||||
|
||||
1. **Auswahl** — Der Kunde markiert die für seinen Scope zutreffenden Risiken. Nicht zutreffende Risiken (z. B. Prototypenschutz ohne physische Musterteile, Entwicklung ohne eigene Softwareentwicklung) werden abgewählt oder als „nicht anwendbar" begründet.
|
||||
2. **Ergänzung** — Der Kunde ergänzt eigene, organisationsspezifische Risiken.
|
||||
3. **Bewertung** — Jedes ausgewählte Risiko wird nach der 5×5-Matrix bewertet (Eintrittswahrscheinlichkeit × Schadenshöhe). Die im Katalog hinterlegte **Default-Einschätzung** ist ein Startwert und vom Kunden anzupassen.
|
||||
4. **Maßnahmenableitung** — Aus dem bewerteten Risiko werden Maßnahmen abgeleitet (Standardmaßnahmen sind vorbelegt). Maßnahmen erzeugen im System **Aufgaben** mit Verantwortlichen und Fristen.
|
||||
5. **Restrisiko** — Nach Maßnahmenumsetzung erfolgt eine erneute Bewertung (Netto-/Restrisiko). Restrisiken oberhalb der Akzeptanzschwelle erfordern eine dokumentierte Risikoakzeptanz durch die Leitung (siehe VA-09).
|
||||
|
||||
### Bewertungslogik (5×5)
|
||||
|
||||
| Achse | Stufen | Kurzdefinition |
|
||||
|-------|--------|----------------|
|
||||
| **Eintrittswahrscheinlichkeit (E)** | 1 sehr gering · 2 gering · 3 mittel · 4 hoch · 5 sehr hoch | Erwartete Häufigkeit im Betrachtungszeitraum (i. d. R. 12 Monate) |
|
||||
| **Schadenshöhe (S)** | 1 vernachlässigbar · 2 gering · 3 spürbar · 4 hoch · 5 existenzbedrohend | Auswirkung auf Vertraulichkeit/Integrität/Verfügbarkeit, Vertrag, Reputation, Recht |
|
||||
|
||||
**Risikowert = E × S** (1–25). Klassifizierung gemäß VA-09:
|
||||
|
||||
- **1–4 gering** (grün) — beobachten, ggf. akzeptieren
|
||||
- **5–9 mittel** (gelb) — Maßnahmen empfohlen
|
||||
- **10–15 hoch** (orange) — Maßnahmen verbindlich, Termin gesetzt
|
||||
- **16–25 sehr hoch** (rot) — Sofortmaßnahmen, Eskalation an Leitung
|
||||
|
||||
Die Default-Einschätzung je Risiko ist als **E/S** angegeben (z. B. „E3/S4"). Sie geht von einem typischen KMU-Zuliefererbetrieb ohne bereits umgesetzte Maßnahmen aus (Brutto-/Ausgangsrisiko).
|
||||
|
||||
### ID-Schema
|
||||
|
||||
`R-<KATEGORIE>-<lfd. Nr.>` — Kategorien: ORG (Organisation/Governance), HR (Personal), PHY (Physisch), IAM (Identitäts-/Zugriffsmanagement), CRY (Kryptografie), OPS (Betrieb/IT), NET (Netzwerk), SUP (Lieferanten/Cloud), DEV (Entwicklung), PROTO (Prototypenschutz), DSGVO (Datenschutz).
|
||||
|
||||
---
|
||||
|
||||
## 2. Organisation / Governance
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-ORG-01 | Fehlende/veraltete IS-Leitlinie & Verantwortlichkeiten | Es existiert keine von der Leitung verabschiedete Informationssicherheitsleitlinie oder Rollen (ISB/CISO) sind nicht benannt, sodass Steuerung und Verbindlichkeit fehlen. | 1.1.1, 1.2.1, 1.3.1 | Richtlinien, Organisation | IS-Leitlinie nach R03 erstellen/aktualisieren, ISB benennen, jährliches Management-Review etablieren | E3/S4 — ohne Governance keine wirksame Steuerung; Schaden trifft gesamtes ISMS |
|
||||
| R-ORG-02 | Kein funktionierendes Risikomanagement | Risiken werden nicht systematisch erfasst, bewertet oder behandelt; TISAX-Anforderung an Risikoprozess ist nicht erfüllt. | 1.4.1 | Prozesse, Dokumentation | Risikomanagement-Verfahren VA-09 einführen, Risiko-Register führen, Reviews terminieren | E3/S4 — Kernanforderung TISAX; Assessment-Abweichung wahrscheinlich |
|
||||
| R-ORG-03 | Fehlendes Asset- und Informationsklassifizierungsschema | Werte (Informationen, Systeme) sind nicht inventarisiert oder klassifiziert, sodass Schutzbedarf und Maßnahmen nicht zielgerichtet zugeordnet werden können. | 1.3.2, 1.3.3, 5.2.x | Informationswerte, Inventar | Asset-Inventar aufbauen, Klassifizierungsschema (intern/vertraulich/streng vertraulich) einführen und kennzeichnen | E3/S3 — Grundlage vieler Controls; ohne Klassifizierung Fehlschutz |
|
||||
| R-ORG-04 | Unzureichende IS-Vorgabendokumentation / veraltete Verfahren | Verfahrensanweisungen und Richtlinien sind nicht vorhanden, veraltet oder werden nicht gelebt, was zu inkonsistentem Handeln führt. | 1.2.x, 1.5.1 | Dokumentation | Dokumentenlenkung nach R03 etablieren, Review-Zyklus (jährlich), Freigabe- und Versionskontrolle | E3/S3 — Nachweisführung im Assessment gefährdet |
|
||||
| R-ORG-05 | Fehlendes Vorfalls- / Incident-Management | Sicherheitsvorfälle werden nicht erkannt, gemeldet, dokumentiert oder ausgewertet, wodurch Schäden eskalieren und Lernen ausbleibt. | 1.6.1 | Prozesse | Incident-Response-Prozess einführen, Meldewege und Eskalation definieren, Vorfallregister führen | E3/S4 — verzögerte Reaktion vergrößert Schaden erheblich |
|
||||
| R-ORG-06 | Fehlendes Business Continuity / Notfallmanagement | Für Ausfälle kritischer Prozesse/IT existieren keine Notfall- und Wiederanlaufpläne, sodass Betriebsunterbrechungen unkontrolliert verlaufen. | 1.6.x, 7.x | Prozesse, IT-Systeme | BCM-Konzept und Wiederanlaufpläne erstellen, Notfallübungen jährlich, Bezug zu BL-OPS-05 (Backup) | E2/S4 — selten, aber hoher Schaden bei Eintritt |
|
||||
|
||||
---
|
||||
|
||||
## 3. Personal
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-HR-01 | Mangelndes Sicherheitsbewusstsein der Mitarbeitenden | Beschäftigte sind nicht regelmäßig geschult und fallen auf Phishing/Social Engineering herein oder handeln fahrlässig. | 2.1.2, 2.1.3 | Personal, Informationen | Awareness-Programm und jährliche Schulungen einführen, Phishing-Simulationen, Schulungsnachweise dokumentieren | E4/S3 — Mensch häufigster Angriffsvektor |
|
||||
| R-HR-02 | Fehlende Vertraulichkeits-/Geheimhaltungsvereinbarungen | Mit Mitarbeitenden, Zeitarbeit oder Externen sind keine NDAs abgeschlossen, sodass der Schutz vertraulicher Informationen rechtlich nicht abgesichert ist. | 2.1.1 | Verträge, Personal | NDA/Verpflichtung auf Vertraulichkeit in Onboarding-Prozess verankern, Bestand nachpflegen | E3/S3 — häufige Lücke bei Externen/Zeitarbeit |
|
||||
| R-HR-03 | Unsicheres On-/Offboarding (Berechtigungen bei Austritt) | Bei Eintritt, Wechsel oder Austritt werden Zugänge und Assets nicht zeitnah vergeben/entzogen, sodass verwaiste Konten und Datenmitnahme entstehen. | 2.1.x, 3.1.1 | Konten, Endgeräte | On-/Offboarding-Checkliste mit HR/IT, Fristen für Kontoentzug und Asset-Rückgabe, regelmäßiger Abgleich | E3/S3 — verwaiste Konten sind typischer Auditfund |
|
||||
| R-HR-04 | Innentäter / Datenmitnahme durch Mitarbeitende | Berechtigte Personen entwenden oder missbrauchen vorsätzlich Informationen (z. B. Konstruktionsdaten) zum eigenen Vorteil oder für Wettbewerber. | 2.1.x, 5.2.x, 3.1.x | Informationen, geistiges Eigentum | Need-to-know umsetzen, Protokollierung sensibler Zugriffe, DLP-Ansätze, arbeitsrechtliche Regelungen | E2/S4 — selten, aber sehr hoher Schaden für IP |
|
||||
|
||||
---
|
||||
|
||||
## 4. Physische Sicherheit
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-PHY-01 | Unberechtigter Zutritt zu Betriebs-/Sicherheitsbereichen | Fehlende Zutrittskontrolle ermöglicht Unbefugten Zugang zu Büros, Serverräumen oder Fertigung, mit Diebstahl- und Manipulationsrisiko. | 4.1.1, 4.1.2 | Gebäude, IT-Systeme | Zonenkonzept, Zutrittskontrollsystem/Schließplan, Besucherregelung mit Begleitung und Protokoll | E3/S3 — Grundschutzanforderung, oft lückenhaft |
|
||||
| R-PHY-02 | Unzureichender Schutz von Server-/Technikräumen | Serverräume sind nicht ausreichend gegen Zutritt, Brand, Wasser, Strom-/Klimaausfall geschützt, was zu Ausfall oder Datenverlust führt. | 4.1.x, 7.x | IT-Infrastruktur | Technikraum absichern (Zutritt, USV, Klima, Brand-/Wasserschutz), Umgebungsüberwachung | E2/S4 — geringe Häufigkeit, hoher Ausfallschaden |
|
||||
| R-PHY-03 | Diebstahl/Verlust von Datenträgern und Dokumenten | Papierunterlagen, USB-Medien oder Datenträger mit vertraulichen Informationen gehen verloren oder werden entwendet. | 4.1.x, 5.2.x | Datenträger, Dokumente | Clean-Desk-Policy, verschließbare Schränke, sichere Entsorgung (Schredder/zertifiziert), Medienverschlüsselung | E3/S3 — alltägliches Restrisiko |
|
||||
|
||||
---
|
||||
|
||||
## 5. Identitäts- und Zugriffsmanagement (IAM)
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-IAM-01 | Fehlberechtigungen / überzogene Zugriffsrechte | Zugriffsrechte folgen nicht dem Need-to-know- und Least-Privilege-Prinzip; Sammelrechte und Rechteakkumulation entstehen. | 3.1.1, 3.1.2, 3.1.3 | Konten, Anwendungen, Daten | Rollen-/Rechtekonzept (RBAC), regelmäßige Rezertifizierung der Berechtigungen, Trennung von Funktionen | E4/S3 — häufigster Auditfund im IAM |
|
||||
| R-IAM-02 | Schwache Authentisierung / fehlende MFA | Zugänge (insb. remote, Admin, Cloud) sind nur durch schwache Passwörter geschützt, wodurch Kontoübernahmen leicht möglich sind. | 3.1.4, 3.1.5 | Konten, Zugänge | Passwortrichtlinie (BL-IAM-*), MFA für Remote-/Admin-/Cloud-Zugänge verpflichtend, SSO | E4/S4 — Credential-Angriffe sehr häufig und wirksam |
|
||||
| R-IAM-03 | Ungesicherte / geteilte privilegierte Konten | Administrative und Sammelkonten werden geteilt genutzt und nicht überwacht, sodass Handlungen nicht zurechenbar sind. | 3.1.x | Admin-Konten | Privileged-Access-Management, personalisierte Admin-Konten, Protokollierung, getrennte Admin-Arbeitsplätze | E3/S4 — Missbrauch privilegierter Rechte hochwirksam |
|
||||
|
||||
---
|
||||
|
||||
## 6. Kryptografie
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-CRY-01 | Fehlende Verschlüsselung mobiler Geräte / Datenträger | Notebooks, Smartphones und Wechselmedien sind nicht verschlüsselt, sodass bei Verlust/Diebstahl Daten unmittelbar lesbar sind. | 5.1.1, 5.1.2 | Endgeräte, Datenträger | Full-Disk-Encryption (BitLocker/FileVault) verpflichtend, MDM-erzwungene Verschlüsselung, Medienrichtlinie | E3/S4 — Verlustfall führt sonst direkt zu Datenabfluss |
|
||||
| R-CRY-02 | Unsichere Datenübertragung (fehlende Transportverschlüsselung) | Vertrauliche Daten werden unverschlüsselt (E-Mail, FTP, HTTP) übertragen und können abgefangen werden. | 5.1.1 | Kommunikation, Daten | TLS erzwingen, sichere Austauschwege/Portale, E-Mail-Verschlüsselung für vertrauliche Inhalte | E3/S3 — Abfangrisiko bei Zulieferaustausch |
|
||||
| R-CRY-03 | Unzureichendes Schlüssel-/Zertifikatsmanagement | Kryptografische Schlüssel und Zertifikate werden nicht sicher verwaltet oder laufen unbemerkt ab, was zu Ausfällen oder Kompromittierung führt. | 5.1.x | Schlüssel, Zertifikate | Krypto-Richtlinie, zentrale Schlüssel-/Zertifikatsverwaltung, Ablaufüberwachung, sichere Aufbewahrung | E2/S3 — schleichender, aber wirkungsvoller Ausfall |
|
||||
|
||||
---
|
||||
|
||||
## 7. Betrieb / IT
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-OPS-01 | Fehlendes/mangelhaftes Patch- und Schwachstellenmanagement | Betriebssysteme und Anwendungen werden nicht zeitnah aktualisiert, sodass bekannte Schwachstellen ausnutzbar bleiben. | 5.2.4, 5.2.5 | IT-Systeme, Software | Patchmanagement-Prozess mit Fristen nach Kritikalität, Schwachstellenscans, Vulnerability-Tracking | E4/S4 — meistgenutztes Einfallstor, hohe Angriffsfläche |
|
||||
| R-OPS-02 | Schadsoftware / Ransomware-Befall | Malware gelangt über E-Mail, Wechselmedien oder Web ins Netz und verschlüsselt oder exfiltriert Daten. | 5.2.3 | IT-Systeme, Daten | Endpoint-Protection/EDR flächendeckend, E-Mail-/Web-Filter, Makro-Restriktionen, Awareness (R-HR-01) | E4/S5 — hohe Häufigkeit, potenziell existenzbedrohend |
|
||||
| R-OPS-03 | Backup-/Wiederanlauf-Versagen | Datensicherungen fehlen, sind unvollständig, nicht getestet oder mitverschlüsselbar, sodass eine Wiederherstellung im Ernstfall scheitert. | 7.x | Daten, IT-Systeme | Backup-Konzept nach BL-OPS-05 (3-2-1, Offline-/Immutable-Kopie), regelmäßige Restore-Tests, RTO/RPO definieren | E3/S5 — im Ransomware-Fall entscheidend für Überleben |
|
||||
| R-OPS-04 | Fehlende Protokollierung und Überwachung (Logging/Monitoring) | Sicherheitsrelevante Ereignisse werden nicht protokolliert oder ausgewertet, sodass Angriffe unentdeckt bleiben. | 5.2.6 | IT-Systeme, Logs | Zentrales Logging, Log-Auswertung/SIEM-Ansatz, Aufbewahrungsfristen, Alarmierung bei Auffälligkeiten | E3/S3 — verlängert Entdeckungszeit erheblich |
|
||||
| R-OPS-05 | Schatten-IT / nicht genehmigte Software & Dienste | Mitarbeitende nutzen nicht freigegebene Cloud-Dienste oder Software, wodurch Daten unkontrolliert abfließen und Schwachstellen entstehen. | 5.2.x, 6.1.x | Anwendungen, Daten | Freigabeprozess für Software/Dienste, Anwendungsinventar, technische Restriktionen, Awareness | E3/S3 — verbreitet, schwer sichtbar |
|
||||
| R-OPS-06 | Fehlkonfiguration / fehlendes Change-Management | Systeme werden ohne kontrollierte Änderungsprozesse betrieben, sodass Fehlkonfigurationen Sicherheitslücken und Ausfälle verursachen. | 5.2.1, 5.2.2 | IT-Systeme, Konfiguration | Härtungs-/Konfigurationsvorgaben (Baselines), Change-Management-Prozess, Test vor Produktivsetzung | E3/S3 — Fehlkonfiguration häufige Ausfall-/Angriffsursache |
|
||||
| R-OPS-07 | Verlust/Diebstahl mobiler Endgeräte | Notebooks, Smartphones oder Tablets gehen unterwegs verloren oder werden gestohlen und ermöglichen Zugriff auf Daten und Systeme. | 5.2.x, 5.1.1 | Endgeräte, Daten | MDM mit Remote-Wipe, Geräteverschlüsselung (R-CRY-01), Bildschirmsperre, Verlustmeldeprozess | E3/S3 — mobiles Arbeiten erhöht Häufigkeit |
|
||||
| R-OPS-08 | Fehlende sichere Entsorgung / Wiederverwendung von IT | Ausgemusterte Geräte und Datenträger werden ohne sichere Löschung entsorgt oder weitergegeben, sodass Restdaten abfließen. | 5.2.x, 4.1.x | Datenträger, Endgeräte | Prozess zur sicheren Löschung/Vernichtung, zertifizierte Entsorgung, Nachweisführung | E2/S3 — selten, aber unbemerkter Datenabfluss |
|
||||
|
||||
---
|
||||
|
||||
## 8. Netzwerk
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-NET-01 | Unsichere Netzsegmentierung / flaches Netz | Fehlende Trennung zwischen Office-, Produktions-/OT- und Gastnetzen ermöglicht laterale Ausbreitung von Angriffen. | 5.2.x | Netzwerk, IT-Systeme | Netzsegmentierung (VLAN/Zonen), Firewall-Regelwerk, Trennung OT/IT und Gast-WLAN | E3/S4 — begünstigt großflächige Kompromittierung |
|
||||
| R-NET-02 | Unsicherer Remote-/VPN-Zugang | Fernzugriffe sind nicht ausreichend abgesichert (kein MFA, offene Ports, veraltete VPN-Gateways) und werden angegriffen. | 5.2.x, 3.1.4 | Zugänge, Netzwerk | Gehärtetes VPN mit MFA, Zugriff nach Least-Privilege, Patching der Gateways, Zugriffprotokollierung | E3/S4 — Remote-Zugänge sind bevorzugtes Angriffsziel |
|
||||
| R-NET-03 | Unzureichender Perimeter-/Firewall-Schutz | Fehlende oder falsch konfigurierte Firewalls und exponierte Dienste erlauben direkte Angriffe aus dem Internet. | 5.2.x | Netzwerk, IT-Systeme | Firewall mit restriktivem Regelwerk, regelmäßige Regel-Reviews, Minimierung exponierter Dienste, externe Scans | E3/S4 — exponierte Dienste werden automatisiert angegriffen |
|
||||
|
||||
---
|
||||
|
||||
## 9. Lieferanten / Cloud
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-SUP-01 | Lieferanten/Dienstleister ohne IS-Nachweis | Externe Partner mit Zugriff auf Informationen/Systeme verfügen über kein nachgewiesenes IS-Niveau (z. B. TISAX/ISO 27001), was Risiken in die Lieferkette trägt. | 6.1.1, 6.1.2 | Verträge, Lieferanten | Lieferantenbewertung, IS-Anforderungen und Nachweise vertraglich fordern, TISAX-Label bei sensiblen Daten | E3/S4 — Kettenrisiko, TISAX-relevant für Weitergabe |
|
||||
| R-SUP-02 | Unzureichende vertragliche IS-Regelungen mit Dienstleistern | Verträge enthalten keine Vorgaben zu Vertraulichkeit, Rückgabe/Löschung, Audit- und Meldepflichten. | 6.1.x | Verträge | Standard-IS-Vertragsklauseln/Anlage, Regelungen zu Löschung, Subunternehmern, Meldung von Vorfällen | E3/S3 — Nachweislücke bei Audit |
|
||||
| R-SUP-03 | Abhängigkeit von Cloud-Diensten / Datenabfluss in die Cloud | Vertrauliche Daten liegen bei Cloud-Anbietern ohne ausreichende Kontrolle über Standort, Zugriff und Ausfallabsicherung. | 6.1.x, 9.x | Cloud-Dienste, Daten | Cloud-Nutzungsrichtlinie, Anbieterprüfung (Zertifikate, Standort), Verschlüsselung, AVV bei Personenbezug | E3/S4 — Kontrollverlust und Lock-in |
|
||||
| R-SUP-04 | Kompromittierung über die Software-Lieferkette | Manipulierte Updates, Bibliotheken oder Fernwartungszugänge von Dienstleistern führen zu Kompromittierungen. | 6.1.x, 5.2.x | Software, Zugänge | Bezugsquellen prüfen, Signaturen verifizieren, Fernwartungszugänge kontrollieren und protokollieren | E2/S4 — selten, aber weitreichende Wirkung |
|
||||
|
||||
---
|
||||
|
||||
## 10. Entwicklung
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-DEV-01 | Abfluss von Entwicklungs-/Konstruktionsdaten | Vertrauliche Entwicklungsdaten (CAD, Spezifikationen, Quellcode) gelangen unkontrolliert nach außen (Cloud, Mail, private Geräte). | 5.2.x, 8.x, 6.1.x | Entwicklungsdaten, IP | Klassifizierung und Zugriffsbeschränkung (Need-to-know), sichere Austauschwege, DLP, Repository-Absicherung | E3/S5 — Kernwert des Zulieferers, hoher IP-Schaden |
|
||||
| R-DEV-02 | Unsichere Software-Entwicklung (fehlender Secure SDLC) | Sicherheitsanforderungen werden in Entwicklung und Tests nicht berücksichtigt, sodass verwundbare Produkte/Software entstehen. | 5.2.x | Quellcode, Anwendungen | Secure-Coding-Vorgaben, Code-Reviews/SAST, Sicherheitstests, Trennung Entwicklungs-/Produktivumgebung | E3/S3 — je nach Entwicklungsanteil relevant |
|
||||
| R-DEV-03 | Testdaten mit Echt-/Produktivdaten | In Entwicklungs- und Testumgebungen werden ungeschützte Produktiv- oder Personendaten verwendet und exponiert. | 5.2.x, 9.x | Testdaten, Personendaten | Anonymisierung/Pseudonymisierung von Testdaten, Zugriffsbeschränkung Testumgebung, Löschkonzept | E3/S3 — verbreitete Praxis, auch datenschutzrelevant |
|
||||
|
||||
---
|
||||
|
||||
## 11. Prototypenschutz
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-PROTO-01 | Unberechtigter Zutritt zu Prototypen-/Musterbereichen | Unbefugte erlangen Zugang zu Bereichen mit Prototypen, Musterteilen oder Vorserien und können diese einsehen, fotografieren oder entwenden. | 8.1.x, 8.2.x | Prototypen, Räumlichkeiten | Sicherheitszonen mit Zutrittskontrolle, Begleitpflicht, Kamera-/Fotografierverbot, Besucherregelung | E3/S4 — TISAX-Prototypenschutz Kernrisiko |
|
||||
| R-PROTO-02 | Unzureichender Schutz bei Erprobung/Transport von Prototypen | Bei Fahrzeugerprobung, Foto/Film oder Transport werden Prototypen unzureichend getarnt/gesichert und Dritten zugänglich. | 8.3.x, 8.4.x | Prototypen, Fahrzeuge | Tarnung/Abdeckung, gesicherte Transporte, Regelungen für Erprobung und Foto/Film, Geheimhaltungszonen | E2/S4 — seltener, aber öffentlichkeitswirksamer Schaden |
|
||||
| R-PROTO-03 | Informationsabfluss zu geschützten Produkten/Projekten | Informationen zu geheimhaltungsbedürftigen Fahrzeugprojekten (Bilder, Daten, Termine) gelangen an Unbefugte oder in soziale Medien. | 8.1.x, 8.2.x | Projektinformationen | Verschärfte Klassifizierung/Kennzeichnung, Need-to-know, Schulung Prototypenschutz, Mobilgeräte-Restriktionen | E3/S4 — Reputations- und Vertragsschaden beim OEM |
|
||||
|
||||
---
|
||||
|
||||
## 12. Datenschutz
|
||||
|
||||
| Risiko-ID | Titel | Beschreibung | Betroffene Controls (VDA ISA) | Asset-Typen | Standardmaßnahme(n) | Default (E/S) |
|
||||
|-----------|-------|--------------|-------------------------------|-------------|---------------------|---------------|
|
||||
| R-DSGVO-01 | Datenschutzverstoß / meldepflichtige Datenpanne | Personenbezogene Daten werden unrechtmäßig offengelegt, verloren oder verarbeitet, was zu Meldepflicht (Art. 33/34), Bußgeld und Reputationsschaden führt. | 9.x | Personendaten | Datenschutz-Managementprozess, Datenpannen-Meldeprozess (72 h), technische/organisatorische Maßnahmen (TOM) | E3/S4 — hohe Bußgeld- und Meldepflichtrelevanz |
|
||||
| R-DSGVO-02 | Fehlende Auftragsverarbeitungsverträge (AVV) | Für Dienstleister, die personenbezogene Daten verarbeiten, fehlen AVV nach Art. 28 DSGVO, sodass Verarbeitung unrechtmäßig ist. | 9.x, 6.1.x | Verträge, Personendaten | AVV-Prozess etablieren, Bestand prüfen und nachholen, Dienstleister mit Personenbezug erfassen | E3/S3 — häufige Lücke, aufsichtsrelevant |
|
||||
| R-DSGVO-03 | Fehlendes Verarbeitungsverzeichnis / keine Rechtsgrundlagen | Verarbeitungstätigkeiten sind nicht dokumentiert (Art. 30) oder ohne Rechtsgrundlage, sodass Nachweispflichten verletzt werden. | 9.x | Dokumentation, Personendaten | Verzeichnis von Verarbeitungstätigkeiten führen, Rechtsgrundlagen prüfen, Löschkonzept/Fristen definieren | E3/S3 — Rechenschaftspflicht, Auditfund |
|
||||
| R-DSGVO-04 | Unzulässige Übermittlung in Drittländer | Personenbezogene Daten werden ohne geeignete Garantien in Drittländer (z. B. über Cloud-Dienste) übermittelt. | 9.x, 6.1.x | Personendaten, Cloud-Dienste | Datenflüsse prüfen, Standardvertragsklauseln/Transfer-Impact-Assessment, EU-Verarbeitung bevorzugen | E2/S4 — komplex, hohe aufsichtsrechtliche Relevanz |
|
||||
|
||||
---
|
||||
|
||||
## 13. Hinweise zur Pflege des Katalogs
|
||||
|
||||
- Der Katalog ist eine **Startvorlage**; jede Organisation passt Auswahl, Beschreibung, Controls-Zuordnung und Bewertung an ihren Scope an.
|
||||
- Controls-Angaben referenzieren die **Struktur** der VDA ISA (Kapitel 1–9). Die genauen Unter-Control-Nummern sind bei Nutzung gegen die aktuell gültige VDA-ISA-Version zu verifizieren.
|
||||
- Standardmaßnahmen verweisen, wo möglich, auf vorhandene Vorlagen/Verfahren (R03, VA-09) und Baseline-Parameter (z. B. **BL-OPS-05** Backup). Weitere BL-* sind bei Umsetzung zu ergänzen.
|
||||
- Jede aus einem Risiko abgeleitete Maßnahme sollte eine **Aufgabe** mit Verantwortlichem, Termin und Statusverfolgung erzeugen (VA-09).
|
||||
|
||||
_Ende Paket C4 — Standard-Risikokatalog._
|
||||
@@ -0,0 +1,199 @@
|
||||
# Paket C5 — Reifegrad-Logik je Control (Onboarding-Wizard, Schritt 7 „Control-Assessment")
|
||||
|
||||
**Zweck:** Regelbasierte, nachvollziehbare Herleitung eines **Reifegrad-Vorschlags (0–3)** je Control aus den im Wizard vorhandenen Belegen (verknüpfte Dokumente, Risiken, Assets) und deren Validierungsstatus. Der Vorschlag ist **nicht bindend** — die Bestätigung/Überschreibung durch den Bearbeiter ist Pflicht (Vier-Augen-Logik über die Rolle des ISB/Assessors).
|
||||
|
||||
**Grundlage:** VDA-ISA-Reifegradmodell 0–3
|
||||
- **0 — unvollständig:** Anforderung nicht oder nur zufällig erfüllt, keine belastbaren Belege.
|
||||
- **1 — durchgeführt/informell:** Ergebnis wird erreicht, aber ohne festgelegte, dokumentierte Vorgehensweise.
|
||||
- **2 — gesteuert/dokumentiert:** Vorgehen ist definiert, dokumentiert (Richtlinie **und** Verfahren) und mit Nachweisen belegt.
|
||||
- **3 — etabliert/integriert:** Vorgehen ist in die Organisation integriert und seine **Wirksamkeit wird über die Zeit nachgewiesen** (wiederkehrende Reviews/Protokolle/Tests).
|
||||
|
||||
---
|
||||
|
||||
## 1. Belegtypen und Validierungsstatus (Datenmodell-Bezug)
|
||||
|
||||
Der Wizard kennt je Control folgende verknüpfbare Belegklassen:
|
||||
|
||||
| Belegklasse | Herkunft im Fachcontent | Beispiel |
|
||||
|---|---|---|
|
||||
| **Zuständige Richtlinie (P)** | Feld `policy` (L00, R01–R14) | Leitlinie, Richtlinie |
|
||||
| **Zugehöriges Verfahren (V)** | Feld `verfahren` (VA-01 … VA-19) | Verfahrensanweisung / Prozess |
|
||||
| **Operativer Nachweis (N)** | control-spezifisch (Protokoll, Report, Register, Ticket, Testnachweis) | Review-Protokoll, Auditbericht |
|
||||
| **Asset-Verknüpfung (A)** | Asset-Inventar | zugeordnete Informationswerte/Systeme |
|
||||
| **Risiko-Verknüpfung (R)** | Risikoregister | zugeordnete Risiken + Risk Owner |
|
||||
|
||||
**Validierungsstatus je Beleg:** `fehlt` → `verknüpft (unvalidiert)` → `validiert` (durch Bearbeiter bestätigt, vorhanden, aktuell). Ein Beleg zählt für Reifegrad-Sprünge nach ≥2 nur, wenn er **`validiert`** ist.
|
||||
|
||||
**Aktualitätsregel (für N):** Ein operativer Nachweis gilt als „aktuell", wenn er innerhalb des für das Control definierten Review-Zyklus liegt (Standard: ≤ 12 Monate; anlassbezogene Verfahren: letzter relevanter Vorfall/Change abgedeckt). Veraltete Nachweise zählen wie `verknüpft (unvalidiert)`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Allgemeine Regeltabelle „Belegkonstellation → Reifegrad-Vorschlag" (generisch, für alle Controls)
|
||||
|
||||
| # | Belegkonstellation | Vorschlag | Begründung |
|
||||
|---|---|---|---|
|
||||
| R0 | Keine Belege verknüpft **oder** nur unvalidierte Fragmente ohne zuständige Richtlinie | **0** | Kein belastbarer Nachweis einer geregelten Vorgehensweise. |
|
||||
| R1a | Zuständige Richtlinie (P) verknüpft, aber **nicht validiert** | **1** | Regelungsabsicht erkennbar, aber nicht bestätigt/gelebt (informell). |
|
||||
| R1b | Richtlinie (P) validiert, **aber** ein für das Control **gefordertes Verfahren (V) fehlt** oder ist unvalidiert | **1** | Richtlinie allein steuert die operative Umsetzung noch nicht. |
|
||||
| R1c | Nur operativer Nachweis (N) vorhanden, **ohne** validierte Richtlinie | **1** | Tätigkeit wird durchgeführt, aber nicht dokumentiert gesteuert. |
|
||||
| R2 | Richtlinie (P) **validiert** **UND** alle geforderten Verfahren (V) **validiert** **UND** (falls einschlägig) Asset-/Risiko-Verknüpfung vorhanden | **2** | Vorgehen ist dokumentiert und gesteuert, Nachweise liegen strukturell vor. |
|
||||
| R3 | Zusätzlich zu R2: mindestens **ein operativer Wirksamkeitsnachweis (N) validiert und aktuell** (Review-/Audit-/Test-/Schulungs-/Rezertifizierungsprotokoll) | **3** | Wirksamkeit wird über die Zeit belegt, Vorgehen ist integriert. |
|
||||
|
||||
**Sonderfälle:**
|
||||
- Controls **ohne** zugeordnetes Verfahren im Fachcontent (`verfahren` = leer): Die operative Steuerung ist in der Richtlinie selbst verankert. Für Grad 2 tritt an die Stelle von (V) eine **validierte, dokumentierte Umsetzungsregelung/Konfiguration (N-basisch)**; Grad 3 erfordert weiterhin einen **wiederkehrenden Wirksamkeitsnachweis**.
|
||||
- Controls, die nur `SOLL` enthalten (z. B. 5.3.3): MUSS-Ebene ist definitionsgemäß erfüllt; Bewertung startet effektiv bei 1 und folgt ansonsten der Tabelle.
|
||||
- **Nachweis widerspricht Richtlinie / offene Findings im Nachweis:** Vorschlag wird um einen Grad gedeckelt (max. 1) und ein offener Punkt erzeugt.
|
||||
|
||||
---
|
||||
|
||||
## 3. Zielreifegrad-Regel
|
||||
|
||||
| Assessment-Scope (Kundenkonfiguration) | Standard-Zielreifegrad |
|
||||
|---|---|
|
||||
| **AL 3** / normaler Schutzbedarf (MUSS + SOLL im Scope) | **3** |
|
||||
| **AL 2** / reiner **MUSS-Scope** | **2** |
|
||||
| Control mit HOCH/SEHR-HOCH-Anforderungen im Scope (hoher/sehr hoher Schutzbedarf) | **3** (Grad 3 wird zur Pflicht, keine Absenkung) |
|
||||
|
||||
- Der Zielreifegrad wird **einmal je Assessment** aus dem Scope (AL2/AL3, Schutzbedarf-Flags `FLAG_INCLUDE_SHOULD`, `FLAG_HIGH_PROTECTION`, `FLAG_VERY_HIGH_PROTECTION`) abgeleitet und je Control angezeigt.
|
||||
- In der Control-Tabelle (Abschnitt 5) ist der **Standard-Zielreifegrad = 3** ausgewiesen; er sinkt automatisch auf **2**, sobald der Kunde im Onboarding einen reinen MUSS-/AL2-Scope wählt.
|
||||
|
||||
---
|
||||
|
||||
## 4. „Offener-Punkt"-Kriterium (Gap/Aufgabe entsteht, wenn …)
|
||||
|
||||
Ein **offener Punkt (Gap → Aufgabe)** wird automatisch erzeugt, wenn **eine** der folgenden Bedingungen zutrifft:
|
||||
|
||||
1. **Vorschlag < Zielreifegrad** (Reifegradlücke). → Aufgabe: „Belege/Umsetzung bis Zielgrad X anheben".
|
||||
2. **Pflichtbeleg fehlt:** zuständige Richtlinie (P) oder ein gefordertes Verfahren (V) ist `fehlt`/unvalidiert. → Aufgabe: Dokument erstellen/verknüpfen/validieren.
|
||||
3. **Operativer Nachweis fehlt oder ist veraltet**, obwohl Zielgrad 3. → Aufgabe: Review/Audit/Test durchführen und dokumentieren.
|
||||
4. **Asset-/Risiko-Verknüpfung fehlt** bei Controls, die auf Inventar/Risikoregister aufsetzen (z. B. 1.3.x, 1.4.1, 5.2.8). → Aufgabe: Verknüpfung herstellen.
|
||||
5. **Nachweis mit Findings/Widerspruch** (Deckelung nach Abschnitt 2). → Aufgabe: Abweichung beheben.
|
||||
6. **Bearbeiter überschreibt Vorschlag nach unten** oder markiert „nicht bestätigt". → Aufgabe mit Begründungspflicht.
|
||||
|
||||
Jeder offene Punkt trägt: Control-ID, fehlende Belegklasse, Ist-Grad, Zielgrad, empfohlene Maßnahme, Verantwortlichen (Default: ISB).
|
||||
|
||||
---
|
||||
|
||||
## 5. Control-spezifische Tabelle — IS-Controls (alle 45)
|
||||
|
||||
**Legende Richtlinien (`policy`):** L00 = Informationssicherheits-Leitlinie · R01 = ISMS-Organisation/Rollen · R02 = Umgang mit Informationswerten (Asset-Mgmt) · R03 = Risikomanagement & Wirksamkeitsprüfung · R04 = Incident-/Notfall-/Kontinuitätsmanagement · R05 = Personalsicherheit · R06 = Mobiles Arbeiten/Mobile Geräte · R07 = Physische Sicherheit/Zonenkonzept · R08 = Zugriffssteuerung (IAM) · R09 = Kryptografie/Kommunikationssicherheit · R10 = IT-Betriebssicherheit · R11 = Systementwicklung/Beschaffung · R12 = Cloud/externe IT-Dienste & KI · R13 = Lieferantenmanagement · R14 = Compliance/Recht & Datenschutz.
|
||||
|
||||
**Legende Verfahren (`verfahren`, abgeleitete Bezeichnungen):** VA-01 Ereignisbehandlung · VA-02 Notfall-/Kontinuitätsmgmt · VA-03 Benutzer-/Berechtigungsverwaltung · VA-04 Change-Management · VA-05 Backup & Wiederherstellung · VA-06 Schwachstellen-/Patch-/Audit-Mgmt · VA-07 Kryptografie/sichere Übertragung · VA-08 Asset-Inventarisierung & Klassifizierung · VA-09 Risikomanagement · VA-10 Lieferantensteuerung · VA-11 Cloud-/KI-Freigabe · VA-12 Schulung & Sensibilisierung · VA-13 Protokollierung/Monitoring · VA-14 Personalprozess · VA-15 Interne Audits/Compliance-Prüfung · VA-17 Zutrittsmanagement · VA-16 Sichere Entwicklung/Beschaffung · VA-18 Rechts-/Datenschutzkataster · VA-19 Projektklassifizierung.
|
||||
|
||||
Format: **Reifegrad-2-Bedingung** = Vorgehen dokumentiert & gesteuert · **Reifegrad-3-Bedingung** = zusätzlich validierter, aktueller Wirksamkeitsnachweis.
|
||||
|
||||
| Control | Erwartete Belege (Richtlinie / Verfahren / operativer Nachweis) | Reifegrad-2-Bedingung | Reifegrad-3-Bedingung | Ziel |
|
||||
|---|---|---|---|---|
|
||||
| **1.1.1** IS-Leitlinie | L00 / — / Managementfreigabe + Veröffentlichungsnachweis (Intranet), Änderungskommunikation | L00 validiert, Freigabe u. Bereitstellung dokumentiert | Wiederkehrender Leitlinien-Review (≤12 M.) + Nachweis Änderungskommunikation | 3 |
|
||||
| **1.2.1** ISMS/Geltungsbereich | R01 / — / Anwendbarkeitserklärung (SoA)/ISA-Katalog, Management-Review-Protokoll | R01 validiert, Scope + SoA dokumentiert | Regelmäßige Managementbewertung mit Wirksamkeitsaussage | 3 |
|
||||
| **1.2.2** Rollen & Verantwortlichkeiten | R01 / — / Rollen-/Verantwortungsmatrix, ISB-Ernennung, Qualifikationsnachweis | R01 validiert, Rollen zugewiesen u. dokumentiert | Periodische Überprüfung der Rollenbesetzung/Qualifikation | 3 |
|
||||
| **1.2.3** Projektklassifizierung | R01 / VA-19 / ausgefüllte Projektklassifizierung + Projekt-Risikobewertung | R01 + VA-19 validiert | Nachweis wiederholter Klassifizierung/Neubewertung über Projekte | 3 |
|
||||
| **1.3.1** Identifizierung Informationswerte | R02 / VA-08 / aktuelles Asset-/Informationswert-Inventar (**A**) | R02 + VA-08 validiert, Inventar (A) verknüpft | Nachweis regelmäßiger Inventarpflege/-abgleich | 3 |
|
||||
| **1.3.2** Klassifizierung Informationswerte | R02 / VA-08 / Klassifizierungsschema + klassifizierte Assets (**A**) | R02 + VA-08 validiert, Schema angewandt | Regelmäßige Überprüfung/Neubewertung der Klassifizierung | 3 |
|
||||
| **1.3.3** Externe IT-Dienste | R02 / — / Freigabe-/Bestandsliste externer Dienste, Freigabeverfahren | R02 validiert + dokumentierte Freigabeliste u. -regelung | Regelmäßige Prüfung, dass nur freigegebene Dienste genutzt werden | 3 |
|
||||
| **1.3.4** Software-Freigabe | R02 / — / Softwarefreigabeliste/Whitelist, Versions-/Patchstand | R02 validiert + dokumentierte Freigabeliste | Regelmäßige Überprüfung der Softwarefreigaben | 3 |
|
||||
| **1.4.1** Risikomanagement | R03 / VA-09 / Risikoregister mit Risk Ownern (**R**), Maßnahmenplan | R03 + VA-09 validiert, Risikoregister (R) verknüpft | Regelmäßige/anlassbezogene Neubewertung + Maßnahmen-Tracking | 3 |
|
||||
| **1.5.1** Compliance-/Richtlinienprüfung | R03 / VA-15 / Prüfplan + Prüfaufzeichnungen/Ergebnisse | R03 + VA-15 validiert, Prüfplan vorhanden | Durchgeführte Prüfungen dokumentiert + Korrekturmaßnahmen verfolgt | 3 |
|
||||
| **1.5.2** Unabhängige Überprüfung | R03 / VA-15 / Bericht unabhängiger/kompetenter Stelle, Managementbericht | R03 + VA-15 validiert | Durchgeführte unabhängige Prüfung + Maßnahmenverfolgung nachgewiesen | 3 |
|
||||
| **1.6.1** Meldung Sicherheitsereignisse | R04 / VA-01 / dokumentierte Meldewege/-kanäle, Meldeformular/Ticketsystem | R04 + VA-01 validiert, Meldewege bekannt | Nachweis genutzter Meldewege (Tickets) + ggf. Test der Meldung | 3 |
|
||||
| **1.6.2** Behandlung Sicherheitsereignisse | R04 / VA-01 / Incident-Log/Tickethistorie mit Lessons Learned | R04 + VA-01 validiert | Bearbeitete Vorfälle + Lessons-Learned-Rückfluss nachgewiesen | 3 |
|
||||
| **1.6.3** Krisen-/Notfallmanagement | R04 / VA-02 / Krisen-/Notfallplan, Krisenstab, Übungs-/Testprotokoll | R04 + VA-02 validiert, Plan u. Rollen dokumentiert | Durchgeführte Krisenübung/Test + Aktualisierung der Planung | 3 |
|
||||
| **2.1.1** Personalprüfung (Eignung/Identität) | R05 / VA-14 / Einstellungsprozess, dokumentierte Identitätsprüfung | R05 + VA-14 validiert | Nachweis gelebter Prüfung über Einstellungen (Stichprobe) | 3 |
|
||||
| **2.1.2** Verpflichtungen (NDA/Richtlinien) | R05 / VA-14 / unterzeichnete Vertraulichkeits-/Richtlinienverpflichtungen | R05 + VA-14 validiert, Verpflichtungen vorhanden | Nachweis flächendeckender, aktueller Verpflichtungen | 3 |
|
||||
| **2.1.3** Schulung & Sensibilisierung | R05 / VA-12 / Schulungskonzept + Teilnahmenachweise | R05 + VA-12 validiert, Konzept genehmigt | Regelmäßig durchgeführte Schulungen + Teilnahmedokumentation | 3 |
|
||||
| **2.1.4** Mobiles Arbeiten | R06 / — / kommunizierte Regelung, Sensibilisierungsnachweis | R06 validiert + dokumentierte Anforderungen | Nachweis Sensibilisierung + Überprüfung der Umsetzung | 3 |
|
||||
| **3.1.1** Sicherheitszonenkonzept | R07 / VA-17 / Zonenkonzept + Umsetzungsnachweis, Zutritts-/Besucherverfahren | R07 + VA-17 validiert, Zonenkonzept umgesetzt | Regelmäßige Überprüfung von Zonen/Zutritt/Besuchermgmt | 3 |
|
||||
| **3.1.4** Mobile Geräte/Datenträger | R06 / — / Regelung + Geräteregistrierung/MDM-Nachweis | R06 validiert + dokumentierte Anforderungen/Registrierung | Nachweis Umsetzung (MDM/Verschlüsselung) + Überprüfung | 3 |
|
||||
| **4.1.1** Identifikationsmittel (Lebenszyklus) | R08 / VA-03 / Ausgabe-/Rückgabe-/Sperrprozess, Nachweis kontrollierte Erstellung | R08 + VA-03 validiert | Nachweis gelebter Sperr-/Rückgabeprozesse (z. B. Verlustfall) | 3 |
|
||||
| **4.1.2** Benutzerauthentifizierung | R08 / — / Authentifizierungskonzept, techn. Umsetzung (Passwortpolicy/MFA) | R08 validiert + dokumentiertes Auth-Konzept | Nachweis wirksamer Umsetzung (MFA-/Policy-Report) + Review | 3 |
|
||||
| **4.1.3** Verwaltung Benutzerkonten | R08 / VA-03 / Kontenverwaltungsprozess, Konten-Rezertifizierung | R08 + VA-03 validiert | Regelmäßige Konten-Überprüfung/Rezertifizierung nachgewiesen | 3 |
|
||||
| **4.2.1** Verwaltung Zugriffsrechte | R08 / VA-03 / Berechtigungskonzept, Rechte-Review/Rezertifizierung | R08 + VA-03 validiert | Regelmäßige Rechte-Rezertifizierung nachgewiesen | 3 |
|
||||
| **5.1.1** Kryptografie | R09 / VA-07 / Kryptokonzept, Nachweis eingesetzter Verfahren | R09 + VA-07 validiert, Konzept umgesetzt | Regelmäßige Überprüfung der Krypto-Verfahren/Stand der Technik | 3 |
|
||||
| **5.1.2** Netzdienste/sichere Übertragung | R09 / VA-07 / Netzdienst-Inventar, Verschlüsselungsnachweis | R09 + VA-07 validiert, Dienste dokumentiert | Nachweis wirksamer (Transport-)Verschlüsselung + Überprüfung | 3 |
|
||||
| **5.2.1** Change-Management | R10 / VA-04 / Change-Prozess, Change-Tickets/CAB-Protokolle | R10 + VA-04 validiert | Nachweis gelebter Changes inkl. IS-Bewertung + Verifikation | 3 |
|
||||
| **5.2.2** Trennung Entw./Test/Prod | R10 / — / Risikobewertung + Segmentierungsnachweis | R10 validiert + dokumentierte Segmentierung | Überprüfung der Trennung/Segmentierung im Betrieb | 3 |
|
||||
| **5.2.3** Schutz vor Schadsoftware | R10 / — / AV-Konzept, AV-Konsole/Status-Report | R10 validiert + dokumentierte Schutzmaßnahmen | Aktueller AV-Statusreport + regelmäßige Überprüfung | 3 |
|
||||
| **5.2.4** Protokollierung/Logging | R10 / VA-13 / Logging-Konzept, Log-Review-Nachweis | R10 + VA-13 validiert | Nachweis regelmäßiger Log-Auswertung/Eskalation | 3 |
|
||||
| **5.2.5** Umgang mit Schwachstellen | R10 / VA-04, VA-06 / Schwachstellen-/Patchprozess, Scan-/Patchreports | R10 + VA-04 + VA-06 validiert | Aktuelle Scan-/Patchreports + Risikobehandlung nachgewiesen | 3 |
|
||||
| **5.2.6** Prüfung von IT-Systemen (Audit) | R10 / VA-06 / Prüfanforderungen, Audit-/Pentestberichte | R10 + VA-06 validiert | Durchgeführte System-/Dienstprüfungen + Maßnahmen nachgewiesen | 3 |
|
||||
| **5.2.7** Netzwerkmanagement | R10 / — / Netzkonzept/Segmentierung, Umsetzungsnachweis | R10 validiert + dokumentiertes Netzkonzept | Überprüfung von Netzmgmt/Segmentierung im Betrieb | 3 |
|
||||
| **5.2.8** Kontinuität IT-Dienste (BCM) | R04 / VA-02 / kritische Dienste identifiziert (**A**), Kontinuitätsplan, Testprotokoll | R04 + VA-02 validiert, kritische Dienste (A) erfasst | Durchgeführter Kontinuitäts-/Wiederherstellungstest nachgewiesen | 3 |
|
||||
| **5.2.9** Backup & Wiederherstellung | R10 / VA-05 / Backup-/Restore-Konzept, Restore-Testprotokoll | R10 + VA-05 validiert, Konzepte vorhanden | Durchgeführter Restore-Test (regelmäßig) nachgewiesen | 3 |
|
||||
| **5.3.1** Sichere Systementwicklung/Beschaffung | R11 / VA-16 / IS-Anforderungen, Abnahme-/Testnachweise | R11 + VA-16 validiert | Nachweis durchgeführter Abnahmetests/Security-Tests | 3 |
|
||||
| **5.3.2** Sicherheit Netzdienste | R11 / VA-16 / SLA/Absicherungsverfahren, Überwachungsnachweis | R11 + VA-16 validiert | Nachweis Überwachung/Qualitätssicherung der Netzdienste | 3 |
|
||||
| **5.3.3** Beendigung IT-Dienste (nur SOLL) | R11 / — / vertraglich geregelter Beendigungsprozess, Nachweis Rückgabe/Löschung | R11 validiert + dokumentierter Beendigungsprozess | Nachweis gelebter Beendigung (Datenrückgabe/-löschung) | 3 |
|
||||
| **5.3.4** Mandantentrennung (Cloud) | R12 / VA-11 / Trennungskonzept des Anbieters, Nachweis | R12 + VA-11 validiert | Regelmäßige Überprüfung/Anpassung des Trennungskonzepts | 3 |
|
||||
| **5.3.4-KI** KI-/GenAI-Nutzung | R12 / VA-11 / KI-Nutzungsregelung + Freigabeliste, vertragl. Trainings-Ausschluss | R12 + VA-11 validiert, Freigabeliste + Datenklassen | Human-in-the-Loop-/Dokumentationsnachweis + Überprüfung | 3 |
|
||||
| **6.1.1** Lieferantenmanagement | R13 / VA-10 / Lieferantenbewertung, Verträge + Nachweise/Zertifikate | R13 + VA-10 validiert, Bewertung + Verträge | Regelmäßige Überprüfung Nachweise/Vertragserfüllung (Monitoring) | 3 |
|
||||
| **6.1.2** Vertraulichkeitsvereinbarungen | R13 / VA-10 / NDA-Vorlagen + abgeschlossene NDAs, Gültigkeitsüberwachung | R13 + VA-10 validiert, Vorlagen + NDAs | Regelmäßige Überprüfung/Verlängerung + gelebte NDA-Nutzung | 3 |
|
||||
| **6.1.3** Geteilte Verantwortlichkeiten (Shared Resp.) | R13 / VA-10 / Verantwortungsmatrix, Nachweis Erfüllung durch Dienstleister | R13 + VA-10 validiert, Matrix dokumentiert | Nachweis, dass Dienstleister Verantwortung erfüllen (Prüfung) | 3 |
|
||||
| **7.1.1** Rechtliche/vertragliche Vorgaben | R14 / VA-18 / Rechts-/Compliance-Kataster, Aktualisierungsnachweis | R14 + VA-18 validiert, Kataster vorhanden | Regelmäßige Aktualisierung des Katasters + Umsetzungsnachweis | 3 |
|
||||
| **7.1.2** Datenschutz-relevante IS-Anforderungen | R14 / VA-18 / dokumentierte DS-Anforderungen, Umsetzungsnachweis im ISMS | R14 + VA-18 validiert, Anforderungen bestimmt | Nachweis Umsetzung/Überprüfung im ISMS-Kontext | 3 (MUSS-only¹) |
|
||||
|
||||
¹ 7.1.2 enthält nur MUSS-Anforderungen: In reinem AL2-/MUSS-Scope Zielreifegrad **2**; ansonsten 3.
|
||||
|
||||
---
|
||||
|
||||
## 6. Proto (8.x) und Datenschutz (9.x) — kompakte Gruppenlogik
|
||||
|
||||
Für Prototypenschutz und Datenschutz sind im Fachcontent **keine Verfahren (VA)** hinterlegt; die Anforderungen sind überwiegend **MUSS** und stark auftraggeber-/rechtsgetrieben. Die Reifegradlogik wird daher vereinfacht: Für Grad 2 tritt an die Stelle des Verfahrens die **dokumentierte, umgesetzte Regelung** (Konzept/Prozess/Vereinbarung); Grad 3 erfordert einen **wiederkehrenden Wirksamkeits-/Umsetzungsnachweis**.
|
||||
|
||||
**Generische Regel Proto/DS:**
|
||||
- **0** — keine Regelung/kein Konzept belegt.
|
||||
- **1** — Konzept/Vereinbarung vorhanden, aber unvalidiert oder nur informell umgesetzt.
|
||||
- **2** — Konzept/Prozess/Vereinbarung **validiert und umgesetzt** (physische Maßnahme, Vertrag, dokumentierter Prozess).
|
||||
- **3** — zusätzlich **validierter, aktueller Nachweis der gelebten Umsetzung** (Auditbericht, Alarmverfolgung, Schulungsnachweis, Besucherprotokoll, DSFA-Register, VVT-Pflege, Auftragskontrollen).
|
||||
|
||||
**Zielreifegrad Proto/DS:** überwiegend **2** (reine MUSS-Anforderungen); für Gruppen mit SOLL/HOCH-Anteil bzw. hohem Schutzbedarf **3**.
|
||||
|
||||
### 6.1 Prototypenschutz (8.x)
|
||||
|
||||
| Gruppe | Controls | Erwartete Belege (Richtlinie/Regelung / operativer Nachweis) | Grad-2-Bedingung | Grad-3-Bedingung | Ziel |
|
||||
|---|---|---|---|---|---|
|
||||
| **8.1 Physische Sicherheit** | 8.1.1–8.1.8 | Sicherheitskonzept Prototypenschutz (Außenhaut, Zutritt, Einblickschutz, EMA/Alarmverfolgung, Besuchermgmt, Mandantentrennung) / Umsetzungs- u. Alarmverfolgungsnachweise, Besucherprotokolle | Sicherheitskonzept validiert + Schutzmaßnahmen umgesetzt | Wiederkehrende Überprüfung der phys. Maßnahmen + Alarmverfolgung/Besuchermgmt nachgewiesen | 2–3² |
|
||||
| **8.2 Organisation/Vertrag/Personal** | 8.2.1–8.2.7 | NDAs (Firma + Personen), Zutrittsvergabeprozess, Schulungskonzept Prototypen, Bild-/Geräteregelungen / unterzeichnete NDAs, Schulungsnachweise, Zutrittslogs | Vereinbarungen/Prozesse validiert u. dokumentiert | Nachweis gelebter Umsetzung (Schulungen, Zutritts-Reviews, Nachweise Unterauftragnehmer) | 2 |
|
||||
| **8.3 Transport/Lagerung** | 8.3.1–8.3.2 | Prozess Einholung Auftraggebervorgaben, freigegebene Logistiker / Nachweis Einhaltung/Meldeprozess | Prozesse validiert u. implementiert | Nachweis gelebter Transport-/Lagerkontrollen u. Ereignismeldung | 2 |
|
||||
| **8.4 Tarnung/Erprobung** | 8.4.1–8.4.3 | Tarnungs-/Erprobungsregeln, Meldeprozess Beschädigungen / Nachweis Bekanntgabe u. Einhaltung | Regeln/Prozesse validiert u. bekannt | Nachweis gelebter Einhaltung + Meldungen bei Vorfällen | 2 |
|
||||
| **8.5 Ausstellungen/Foto-Film** | 8.5.1–8.5.2 | Prozess Auftraggebervorgaben, freigegebene Sicherheitskonzepte / Freigabenachweise, Verhaltensregeln | Prozesse + freigegebene Konzepte validiert | Nachweis gelebter Umsetzung je Veranstaltung/Shooting | 2 |
|
||||
|
||||
² 8.1.4/8.1.5/8.1.8 mit HOCH-Anteil (schutzbedürftige Fahrzeuge): Zielreifegrad 3.
|
||||
|
||||
### 6.2 Datenschutz (9.x)
|
||||
|
||||
| Gruppe | Controls | Erwartete Belege (Richtlinie/Regelung / operativer Nachweis) | Grad-2-Bedingung | Grad-3-Bedingung | Ziel |
|
||||
|---|---|---|---|---|---|
|
||||
| **9.1 Richtlinie DS** | 9.1.1 | DS-Richtlinie (freigegeben) / Aktualisierungs-/Freigabenachweis | DS-Richtlinie validiert u. freigegeben | Regelmäßige Aktualisierung/Review nachgewiesen | 2 |
|
||||
| **9.2 Verantwortlichkeiten DS** | 9.2.1 | DSB-Bestellung/DS-Funktion, Kontaktveröffentlichung, Ressourcen / Kontroll- u. Berichtsdokumentation | Bestellung/Funktion + Eingliederung validiert | Nachweis ausgeübter Kontrollpflichten + Managementbericht | 2 |
|
||||
| **9.3 Verarbeitungsverzeichnis** | 9.3.1 | VVT (Art. 30), Prozessbeschreibung/Zuständigkeiten / VVT-Pflegenachweis | VVT + Prozess validiert | Regelmäßige VVT-Pflege/Aktualität nachgewiesen | 2 |
|
||||
| **9.4 DSFA** | 9.4.1 | Kriterien/Liste DSFA-pflichtiger Verarbeitungen, DSFA-Verfahren / durchgeführte DSFA | DSFA-Verfahren + Zuständigkeiten validiert | Durchgeführte DSFA + Maßnahmen nachgewiesen | 2 |
|
||||
| **9.5 Datenübermittlung/AV** | 9.5.1–9.5.3 | AV-Verträge (Art. 28), Transferinstrumente, Drittland-Garantien / Nachweis Verträge/Prüfungen | Prozesse + Verträge validiert | Nachweis Überprüfung Einhaltung + Drittland-Erfassung (TIA) | 2 |
|
||||
| **9.6 Betroffenenrechte/Vorfälle** | 9.6.1–9.6.2 | Verfahren Betroffenenanfragen, DS-Vorfall-/Notfallplan, Schulung / Bearbeitungs-/Meldenachweise | Verfahren validiert u. dokumentiert | Nachweis fristgerechter Bearbeitung + Meldeprozesse gelebt | 2 |
|
||||
| **9.7 Personal DS** | 9.7.1–9.7.2 | Vertraulichkeitsverpflichtungen, DS-Schulungskonzept / Verpflichtungs- u. Schulungsnachweise | Verpflichtung + Schulungskonzept validiert | Regelmäßige DS-Schulungen + Verpflichtungen nachgewiesen | 2 |
|
||||
| **9.8 Weisungen AV** | 9.8.1 | Verfahren Weisungsumgang, Datentrennung nach Auftrag / Dokumentation Weisungen | Verfahren + Maßnahmen validiert | Nachweis dokumentierter/umgesetzter Weisungen + Trennung | 2 |
|
||||
|
||||
---
|
||||
|
||||
## 7. Umsetzungshinweis Wizard (Pseudologik)
|
||||
|
||||
```
|
||||
ziel = ableiteZiel(scope) // AL3 -> 3, AL2/MUSS -> 2, HOCH/V-HOCH -> 3
|
||||
p = statusRichtlinie(control.policy)
|
||||
v = min(statusAllerVerfahren(control.verfahren)) // leer -> „n/a" (durch N-basisch ersetzt)
|
||||
n = statusOperativerNachweis(control) // inkl. Aktualitätsprüfung
|
||||
a = statusAssetVerknuepfung(control) // nur falls einschlägig
|
||||
r = statusRisikoVerknuepfung(control) // nur falls einschlägig
|
||||
|
||||
if p != validiert: vorschlag = (p == verknuepft) ? 1 : 0
|
||||
elif verfahrenGefordert && v != validiert: vorschlag = 1
|
||||
elif einschlaegigA && a != verknuepft: vorschlag = 1
|
||||
else: vorschlag = 2
|
||||
if vorschlag == 2 && n == validiert_aktuell: vorschlag = 3
|
||||
if nachweisMitFindings: vorschlag = min(vorschlag, 1)
|
||||
|
||||
if vorschlag < ziel || pflichtbelegFehlt || (ziel==3 && n!=validiert_aktuell):
|
||||
erzeugeOffenenPunkt(control, ist=vorschlag, ziel, fehlendeBelege)
|
||||
|
||||
// Pflicht: Bearbeiter bestätigt oder überschreibt vorschlag (mit Begründung)
|
||||
```
|
||||
|
||||
**Kernprinzip:** Der Wizard schlägt vor, der Bearbeiter entscheidet. Jeder Vorschlag ist über die verknüpften, validierten Belege vollständig nachvollziehbar; jede Lücke zwischen Vorschlag und Zielreifegrad wird automatisch in einen offenen Punkt (Aufgabe) überführt.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
# C7 — ISMS-Soll-Rollenmodell + Funktionstrennung (+ Bestellungs-Vorlage)
|
||||
|
||||
> **Schaltet frei:** A4 (ISMS-Rollen & Funktionstrennung, Schritt 3). **Grundlage:** `variables.schema.json` (`ROLE_*`), Richtlinie `R01_ISMS-Organisation-und-Rollen`.
|
||||
|
||||
## 1. Soll-Rollenmodell
|
||||
|
||||
| Rolle | Variable | Kernverantwortung | Besetzung |
|
||||
|---|---|---|---|
|
||||
| Oberste Leitung | `ROLE_MANAGEMENT` | Gesamtverantwortung ISMS, Ressourcen, Freigabe von Leitlinie/Richtlinien, Managementbewertung | intern (GF) |
|
||||
| Informationssicherheitsbeauftragte(r) | `ROLE_ISB` | Aufbau/Pflege/Weiterentwicklung ISMS, Beratung der Leitung, Risikomanagement, Audits, Meldeweg; berichtet direkt an die Leitung | intern **oder** extern |
|
||||
| IT-Leitung / IT-Verantwortung | `ROLE_IT_LEAD` | Betrieb, technische Umsetzung der Maßnahmen | intern oder extern (Dienstleister) |
|
||||
| Personalleitung | `ROLE_HR_LEAD` | Personalsicherheit, On-/Offboarding, Awareness | intern |
|
||||
| Datenschutzbeauftragte(r) | `ROLE_DPO` | Datenschutz-Compliance (bei Verarbeitung personenbezogener Daten) | intern oder extern |
|
||||
|
||||
Bezug: Controls 1.2.1/1.2.2 (Organisation der IS), 2.1.x (Personal), 7.1.2 (Datenschutz). Rollen-Variablen befüllen Platzhalter in allen Vorlagen (Verantwortlich/Freigabe).
|
||||
|
||||
## 2. Funktionstrennungs-Regeln (Prüfung im Wizard)
|
||||
|
||||
| Regel-ID | Bedingung | Ergebnis | Begründung |
|
||||
|---|---|---|---|
|
||||
| FT-01 | `ROLE_ISB` = `ROLE_IT_LEAD` (dieselbe Person, beide intern) | **Konflikt** → Hinweis + Aufgabe | ISB muss die IT unabhängig überwachen können; Selbstkontrolle unzulässig |
|
||||
| FT-02 | `ROLE_ISB` intern **und** direkt der IT-Leitung unterstellt | **Konflikt (schwach)** → Hinweis | Weisungsunabhängigkeit/Berichtsweg an Leitung gefährdet |
|
||||
| FT-03 | `ROLE_ISB` = `ROLE_MANAGEMENT` | **Konflikt** → Hinweis + Aufgabe | Leitung kann eigene ISMS-Verantwortung nicht selbst überwachen |
|
||||
| FT-04 | `ROLE_ISB` nicht benannt | **Lücke** → Aufgabe „ISB bestellen" (Control 1.2.2) | ISB ist Muss-Anforderung |
|
||||
| FT-05 | `ROLE_DPO` fehlt trotz `FLAG_PERSONAL_DATA` | **Lücke** → Aufgabe „DSB benennen/prüfen" | Datenschutz-Organisation erforderlich |
|
||||
| FT-06 | Antragsteller = Genehmiger von Zugriffsrechten (aus IAM-Daten) | **Konflikt** → Hinweis | Vier-Augen bei Berechtigungsvergabe (Control 4.2.1) |
|
||||
|
||||
**Kompensierende Kontrollen** (wenn Trennung z. B. bei Kleinorganisation nicht möglich): externer ISB (GEFIM-Modell), Vier-Augen mit der Leitung, dokumentierte Ausnahmegenehmigung + verstärkte Protokollierung. Der Wizard bietet bei Konflikt „Trennung herstellen" **oder** „kompensierende Kontrolle dokumentieren" (→ Aufgabe bzw. Nachweis).
|
||||
|
||||
## 3. Bestellungs-/Ernennungs-Vorlage (Paket-Stil)
|
||||
|
||||
Neue Vorlage `VA-00_ISB-Bestellung.md` bzw. Textbaustein in `R01`, mit Platzhaltern und Ankern:
|
||||
|
||||
```markdown
|
||||
# Bestellung Informationssicherheitsbeauftragte(r)
|
||||
|
||||
| Feld | Wert |
|
||||
|------|------|
|
||||
| Organisation | {{ORG_NAME}} |
|
||||
| Bestellte Person / Funktion | {{ROLE_ISB}} |
|
||||
| Bestellt durch | {{ROLE_MANAGEMENT}} |
|
||||
| Besetzung | {{#if FLAG_ISB_EXTERNAL}}extern (Dienstleistervertrag){{/if}}{{#if FLAG_ISB_INTERNAL}}intern{{/if}} |
|
||||
| Version / Datum / Status | {{DOC_VERSION}} / {{DOC_DATE}} / {{DOC_STATUS}} |
|
||||
|
||||
<!-- REQ 1.2.2-M1 -->
|
||||
Die Organisation {{ORG_NAME}} bestellt {{ROLE_ISB}} mit Wirkung zum {{DOC_DATE}} zum/zur Informationssicherheitsbeauftragten.
|
||||
|
||||
## Aufgaben und Befugnisse
|
||||
- Aufbau, Pflege und Weiterentwicklung des ISMS gemäß VDA ISA.
|
||||
- Beratung der Leitung; jährliche Überprüfung von Richtlinien und Wirksamkeit.
|
||||
- Koordination von Risikomanagement, Schulungen, Audits, Maßnahmen.
|
||||
- Melde-/Eskalationsrecht direkt an {{ROLE_MANAGEMENT}}; Zugang zu relevanten Informationen/Systemen.
|
||||
|
||||
## Freigabe
|
||||
| Rolle | Name | Datum, Unterschrift |
|
||||
|-------|------|---------------------|
|
||||
| Leitung | {{ROLE_MANAGEMENT}} | |
|
||||
| ISB | {{ROLE_ISB}} | |
|
||||
```
|
||||
|
||||
Neue Flags bei Bedarf in `variables.schema.json`: `FLAG_ISB_EXTERNAL` / `FLAG_ISB_INTERNAL` (aus Q-ROLE-02). Nach Anlage `_verify.py` → **OK**.
|
||||
@@ -0,0 +1,37 @@
|
||||
# C8 — Priorisierungslogik Gap + Quick-Wins
|
||||
|
||||
> **Schaltet frei:** A8 (Gap-Konsolidierung, Schritt 8). **Grundlage:** Ergebnisse aus Schritt 6 (Risiko) und 7 (Control-Assessment), Aufgaben-Modul.
|
||||
|
||||
## 1. Prioritätsregeln (deterministisch)
|
||||
|
||||
Priorität eines offenen Punkts = höchste zutreffende Regel:
|
||||
|
||||
| Priorität | Bedingung |
|
||||
|---|---|
|
||||
| **Hoch** | Offene **MUSS**-Anforderung (Reifegrad < 2) · **oder** offene AL3-Zusatzanforderung (`HOCH`/`SEHR HOCH`) bei entsprechendem Schutzbedarf · **oder** Behandlungsmaßnahme zu einem Risiko oberhalb der Akzeptanzlinie · **oder** fehlende Muss-Rolle/Funktionstrennungs-Konflikt (C7 FT-01/03/04) |
|
||||
| **Mittel** | Offene **SOLL**-Anforderung · Reifegrad = 2 aber unter Zielreifegrad 3 · Nachweis vorhanden aber nicht validiert · Dokument im Entwurf/nur als Vorlage |
|
||||
| **Niedrig** | Redaktioneller/formaler Punkt · Optimierung ohne Reifegrad-Wirkung · Nachweis nur zu aktualisieren |
|
||||
|
||||
Zusatzgewichtung (Sortierung innerhalb gleicher Priorität): (1) Anzahl betroffener Controls, (2) Risikohöhe des verknüpften Risikos, (3) Aufwand aufsteigend (Quick-Wins zuerst).
|
||||
|
||||
## 2. Deduplizierung
|
||||
|
||||
Offene Punkte aus Schritt 6 und 7 werden zusammengeführt. Dedup-Schlüssel = (Control + Teilanforderungs-ID) bzw. (verknüpfte Maßnahme/Aufgabe). Regeln:
|
||||
|
||||
- Gleiche Teilanforderung aus mehreren Quellen → **ein** Punkt, höchste Priorität gewinnt, Quellen werden verknüpft.
|
||||
- Ein offener Punkt, für den bereits eine Aufgabe existiert → keine neue Aufgabe, bestehende verknüpfen.
|
||||
- Risiko-Maßnahme und Control-Gap, die dieselbe Maßnahme adressieren (z. B. „Patchmanagement einführen" für Risiko R-OPS-03 und Controls 5.2.3/5.2.5) → zusammenführen, alle Bezüge an die eine Aufgabe hängen.
|
||||
|
||||
## 3. Quick-Wins
|
||||
|
||||
Ein offener Punkt ist **Quick-Win**, wenn: geringer Aufwand (organisatorisch/redaktionell, kein Tool-/Budgetbedarf) **und** Reifegrad-Wirkung ≥ +1 auf mindestens ein Control **und** keine Abhängigkeit von anderer offener Maßnahme. Typische Quick-Wins: Freigabe/Validierung eines bereits erstellten Dokuments, Befüllen einer vorhandenen Vorlage (Konten-Review, Rezertifizierung), Rollen-/Funktionstrennungs-Dokumentation, Redaktionslücken schließen. Der Wizard hebt Quick-Wins im Maßnahmenplan gesondert hervor (Reihenfolge-Empfehlung „erst Quick-Wins, dann Hoch-Aufwand").
|
||||
|
||||
## 4. Beispiel-Priorisierung
|
||||
|
||||
| Offener Punkt | Regel | Priorität | Quick-Win? |
|
||||
|---|---|---|---|
|
||||
| Kein Patchmanagement (Controls 5.2.3/5.2.5, Risiko R-OPS-03) | MUSS < 2 + Risiko | Hoch | nein (Tool) |
|
||||
| Restore-Test nicht durchgeführt (5.2.9, BL-OPS-06) | MUSS-Nachweis fehlt | Hoch | ja (organisatorisch) |
|
||||
| ISB = IT-Verantwortung (FT-01) | Funktionstrennungs-Konflikt | Hoch | teils (extern/kompensieren) |
|
||||
| SOLL Berechtigungs-Review nur als Vorlage (4.2.1) | SOLL, nicht validiert | Mittel | ja |
|
||||
| Zonenbezeichnung inkonsistent (3.1.1) | redaktionell | Niedrig | ja |
|
||||
@@ -0,0 +1,49 @@
|
||||
# C9 — Auswertungs-/Interpretationstexte + Export-Layout
|
||||
|
||||
> **Schaltet frei:** B7 (Assessment-Readiness & Export, Schritt 9). **Grundlage:** validierte Control-Bewertungen (Schritt 7), Gap-/Maßnahmenliste (Schritt 8), Validierungsstatus (A3).
|
||||
|
||||
## 1. Reifegrad-Dashboard — Interpretationstexte
|
||||
|
||||
Aggregation je Kapitel und gesamt (Durchschnitt der Control-Reifegrade, „unbestätigt" zählt nicht als erfüllt). Textbänder nach Gesamtreifegrad:
|
||||
|
||||
| Reifegrad (Ø) | Band | Interpretationstext |
|
||||
|---|---|---|
|
||||
| < 1,5 | Aufbau | „Das ISMS befindet sich im Aufbau. Wesentliche Richtlinien/Verfahren sind noch zu erstellen oder freizugeben. Fokus: Muss-Anforderungen und Grundstruktur." |
|
||||
| 1,5 – < 2,5 | Etabliert im Aufbau | „Grundlegende Prozesse sind vorhanden und teils dokumentiert. Für Assessment-Reife fehlen v. a. Nachweise der gelebten Anwendung und Validierungen." |
|
||||
| 2,5 – < 3,0 | Assessment-nah | „Das ISMS ist überwiegend etabliert. Wenige offene Punkte und Nachweise trennen von der Assessment-Reife (AL-Ziel). Fokus: Hoch-Punkte schließen, Wirksamkeitsnachweise ergänzen." |
|
||||
| = 3,0 | Assessment-reif | „Die bewerteten Controls erfüllen den Zielreifegrad. Empfehlung: Stichprobenvalidierung und Aktualität der Nachweise vor dem Assessment sicherstellen." |
|
||||
|
||||
Zusätzliche Kennzahlen: Anteil bestätigter (validierter) Controls, Anzahl offener Punkte je Priorität, Abdeckung je Prüfziel, „höchstes erreichbares Ergebnis" = Zielreifegrad.
|
||||
|
||||
## 2. Empfohlene nächste Schritte (dynamisch)
|
||||
|
||||
Regelbasiert eingeblendet:
|
||||
|
||||
- Offene **Hoch**-Punkte vorhanden → „Vor dem Assessment zwingend: die N Hoch-Punkte im Maßnahmenplan abarbeiten (siehe Aufgaben)."
|
||||
- Unvalidierte Objekte vorhanden → „X Objekte warten auf Validierung durch ISB/Berater — bis dahin als ‚unbestätigt' gewertet."
|
||||
- Prüfziel Prototypenschutz aktiv & 8.x < Ziel → „Prototypenspezifische Nachweise ergänzen (physische Schutzmaßnahmen, Zutritt, Transport)."
|
||||
- Nachweis-Upload-Iteration noch offen → „Operative Nachweise (Screenshots/Protokolle) in der Folgeiteration hochladen."
|
||||
|
||||
## 3. VDA-ISA-Katalog-Export — Layout
|
||||
|
||||
**Struktur (je Prüfziel ein Tabellenblatt/Abschnitt, Reihenfolge Informationssicherheit → Prototypenschutz → Datenschutz):**
|
||||
|
||||
| Feld | Inhalt | Quelle |
|
||||
|---|---|---|
|
||||
| Control-ID | z. B. 4.1.2 | Katalog |
|
||||
| Kontrollfrage / Ziel | aus Katalog | Katalog |
|
||||
| Reifegrad | 0–3 (bestätigt) bzw. „na" | Schritt 7 |
|
||||
| Status | bestätigt / unbestätigt | A3-Validierung |
|
||||
| Umsetzungsbeschreibung | je Teilanforderung: **Anforderung (fett)** + Umsetzung (normal), Reihenfolge MUSS→SOLL→HOCH→SEHR HOCH | Schritt 7 + Vorlagen-IMPL |
|
||||
| Belege | verknüpfte Dokumente/Verfahren/Risiken/Assets | Schritt 4–7 |
|
||||
| Offene Punkte | je Control aus Gap-Liste | Schritt 8 |
|
||||
|
||||
**Darstellungsregeln:** Anforderungstext im Originalwortlaut, **fett**; Umsetzung normal darunter mit Quellenangabe (Dokument, Version/Stand, Kapitel) — konsistent zur bisherigen Ausarbeitung. „Unbestätigt" sichtbar markieren (z. B. Kennzeichnung/Farbe). Ergänzungshinweise/offene Punkte **nicht** im Katalog, sondern in der separaten Maßnahmen-/Schwachstellenliste.
|
||||
|
||||
**Exportformate:** XLSX (VDA-ISA-Katalogsicht + Ergebnisblatt mit Reifegrad-Kennzahlen), zusätzlich DOCX/PDF für Management-Zusammenfassung. Der Export koppelt an den bestehenden DOCX/PDF-Export der App.
|
||||
|
||||
## 4. Zusatzartefakte im Export
|
||||
|
||||
- **Maßnahmenplan** (aus C8): priorisierte offene Punkte + verknüpfte Aufgaben, Quick-Wins hervorgehoben.
|
||||
- **Nachweisregister** (aus `Nachweisregister_zentral.md`): je Anforderung der zugeordnete Nachweis/Status.
|
||||
- **Management-Zusammenfassung**: Stärken, Reifegrad-Überblick, Hoch-Punkte, empfohlene Schritte vor dem Assessment.
|
||||
@@ -0,0 +1,233 @@
|
||||
# Onboarding-Wizard ISMS – Detaillierter Fahrplan & Entwickler-Handlungsanweisung
|
||||
|
||||
**Produkt:** ISMS-Applikation – Onboarding-Wizard
|
||||
**Fokus der ersten Ausbaustufe:** TISAX / VDA ISA
|
||||
**Ziel (North Star):** Assessment-Readiness – am Ende des Wizards liegt ein vorausgefüllter VDA-ISA-Katalog inkl. Reifegrad-Ersteinschätzung und Maßnahmenplan vor.
|
||||
**Modus:** Kunde bearbeitet eigenständig; ISB oder externer Berater (falls gebucht) validiert an definierten Gates.
|
||||
**Tailoring:** Template- und regelbasiert; eigene Richtlinien optional hochladbar; die mitgelieferten Vorlagen sind optional.
|
||||
**Status:** Detailausarbeitung zur Verifizierung vor der technischen Umsetzung.
|
||||
|
||||
---
|
||||
|
||||
## 1. Lesehinweis & Konventionen
|
||||
|
||||
Dieses Dokument beschreibt je Wizard-Schritt: Zweck, Ein-/Ausgaben, Verarbeitungslogik, erzeugte Objekte, kontextsensitive Umsetzungshinweise, Aufgaben-Trigger, Validierung, benötigte Entwicklungs-Ressourcen und Akzeptanzkriterien. Es ist eine fachliche Handlungsanweisung, keine technische Spezifikation – Technologiewahl, konkrete Schemata und UI-Design folgen in der Umsetzung.
|
||||
|
||||
**Aufwands-/Ressourcengröße (T-Shirt):** S = klein, M = mittel, L = groß. Bezieht sich auf den Entwicklungsaufwand des jeweiligen Bausteins, nicht auf die Kundenlaufzeit.
|
||||
|
||||
**Rollen im Wizard**
|
||||
|
||||
| Rolle | Aufgabe |
|
||||
|---|---|
|
||||
| Bearbeiter (Kunde) | Durchläuft die Schritte, gibt Fakten ein, wählt/erstellt Dokumente, bewertet Controls und Risiken |
|
||||
| Validierer (ISB intern oder externer Berater) | Prüft und gibt Module/Objekte frei; ohne Freigabe fließt Inhalt als „unbestätigt" in die Auswertung |
|
||||
| Systemadministrator (Vorbedingung) | Richtet Mandant, Nutzer und Rollen ein – **außerhalb** des Wizards |
|
||||
|
||||
---
|
||||
|
||||
## 2. Querschnittsmechaniken (gelten in allen Schritten)
|
||||
|
||||
Diese vier Mechaniken sind kein eigener Schritt, sondern durchziehen den gesamten Wizard und sollten früh als wiederverwendbare Bausteine gebaut werden.
|
||||
|
||||
### 2.1 Validierungs-Workflow
|
||||
|
||||
Jedes bearbeitbare Objekt (Modul, Richtlinie, Risiko, Control-Bewertung) trägt einen Status: `offen → in Bearbeitung → zur Validierung → validiert` (bzw. `zurückgewiesen` mit Kommentar). Nur validierte Inhalte zählen in der Assessment-Readiness-Auswertung als „bestätigt". Der Validierer erhält je Objekt Kontext, Kommentar- und Freigabefunktion. Ist kein externer Berater gebucht, übernimmt der interne ISB die Validierung.
|
||||
**Ressourcen:** Backend (Statusmodell, Rechte) M · Frontend (Review-Ansicht, Kommentare) M.
|
||||
|
||||
### 2.2 Umsetzungshinweise („So setzen Sie diese Anforderung um")
|
||||
|
||||
An jeder VDA-ISA-Teilanforderung (und optional an Risiken/Templates) hängt redaktioneller Hinweis-Content, der bei der Bearbeitung kontextsensitiv eingeblendet wird. Ein Hinweis umfasst typischerweise: organisatorische Umsetzungsoption, technische Umsetzungsoption, typische Nachweise, geeignete Vorlage (Verweis) und eine **Ressourcenindikation** (Tool/Personal/Budget/Zeit). Die Einblendung wird über Scope und Antworten gefiltert (z. B. nur AL3-relevante Hinweise). Hinweise sind Wissensinhalt, keine trackbare Aufgabe – führt ein Hinweis zu einer umzusetzenden Maßnahme, entsteht daraus eine Aufgabe (siehe 2.3).
|
||||
**Ressourcen:** Fachredaktion/ISMS-SME (Content-Pflege) L · Backend (Hinweis-Datenmodell, Filter) S · Frontend (Inline-Panel) S.
|
||||
|
||||
### 2.3 Maßnahmen → Aufgaben-Modul
|
||||
|
||||
Ergibt sich bei der Bearbeitung eine umzusetzende Maßnahme (z. B. „Patchmanagement-Tool einführen", „Berechtigungs-Review etablieren", „Notfallübung durchführen"), wird daraus eine **Aufgabe im Aufgaben-Modul** erzeugt – automatisch vorgeschlagen und vom Bearbeiter bestätigt. Trigger-Punkte: Richtlinie „später erstellen" (Schritt 4), Risikobehandlung (Schritt 6), Control-Lücke/Reifegrad < Ziel (Schritt 7), Gap-Liste (Schritt 8), Zurückweisung durch Validierer.
|
||||
|
||||
**Aufgaben-Objekt (Felder):** Titel, Beschreibung, Typ (`Dokument erstellen` / `Nachweis liefern` / `technische Maßnahme` / `organisatorische Maßnahme`), Verantwortlicher, Fälligkeit, Priorität, Status, Verknüpfung (Control / Risiko / Dokument / Asset), **benötigte Ressourcen** (Tool, Budget, Personal, Zeit), Herkunft (auslösender Schritt). Die Ressourcenindikation stammt aus dem Umsetzungshinweis und ist editierbar.
|
||||
|
||||
*Beispiel:* Control 5.2.3/5.2.5 unzureichend → Hinweis „technische Umsetzung: zentrales Patchmanagement" → Aufgabe „Patchmanagement-Tool auswählen und einführen", Typ `technische Maßnahme`, verknüpft mit 5.2.3 und 5.2.5, Ressourcen: Tool-Lizenz + IT-Personal ca. X PT, Priorität Hoch.
|
||||
**Ressourcen:** Backend (Task-Generierung, Verknüpfungen, API zum Aufgaben-Modul) M · Frontend (Vorschlag/Bestätigung, Ressourcenfelder) M. Voraussetzung: Aufgaben-Modul der App existiert bzw. bietet eine Schnittstelle.
|
||||
|
||||
### 2.4 Audit-Trail & Versionierung
|
||||
|
||||
Jede Eingabe, Statusänderung und Freigabe wird protokolliert (wer/wann/was). Templates, Katalog und Risikokatalog sind versioniert; Kundendokumente referenzieren die genutzte Template-Version.
|
||||
**Ressourcen:** Backend (Event-Log, Versionierung) M.
|
||||
|
||||
---
|
||||
|
||||
## 3. Fachliche Bausteine / Datenobjekte (Fundament)
|
||||
|
||||
| Baustein | Inhalt | Ressourcen |
|
||||
|---|---|---|
|
||||
| Control-Katalog VDA ISA | Prüfziele, Assessment-Level, je Control die Muss-/Soll-/Zusatzanforderungen als einzeln adressierbare Teilanforderungen | SME (Datenpflege) M · Backend (Import/Modell) S |
|
||||
| Template-Bibliothek (optional) | Richtlinien-/VA-Vorlagen mit Platzhaltern, optionalen Bausteinen und Control-Verknüpfung | SME/Content L · Backend S |
|
||||
| Upload-Pfad eigene Dokumente | Upload + Zuordnung „welche Controls belegt dieses Dokument" | Backend S · Frontend S |
|
||||
| Fakten-/Fragemodell | Antwortobjekte zu Organisation, IT, Dienstleistern, Prozessen; wiederverwendbar | SME (Fragebogen) M · Backend M |
|
||||
| Risiko-Katalog | Standard- und VDA-geforderte Risiken, vordefiniert und erweiterbar; Verknüpfung zu Controls/Assets | SME L · Backend M |
|
||||
| Regel-/Mapping-Layer | Antwort → Platzhalter, Klausel-Ein/Ausblendung, betroffene Controls/Assets/Risiken | Backend (Regel-Engine) L |
|
||||
| Reifegrad-/Gap-Engine | Reifegrad-Ersteinschätzung + offene Punkte je Control | Backend M · SME (Logik) M |
|
||||
|
||||
---
|
||||
|
||||
## 4. Die Schritte im Detail
|
||||
|
||||
> Vorbedingung (außerhalb des Wizards): technisches Onboarding – Mandant, Nutzer, Rollen eingerichtet.
|
||||
|
||||
### Schritt 1 – Scoping
|
||||
|
||||
- **Zweck:** Prüfziele, Assessment-Level (AL2/AL3), Standorte und Geltungsbereich festlegen. Dies steuert, welche Controls, Templates und Risiken im weiteren Verlauf überhaupt relevant sind.
|
||||
- **Eingaben:** Prüfziele (Info-Sicherheit, Prototypenschutz, Datenschutz), Assessment-Level, Standort(e), organisatorischer/technischer Geltungsbereich, Ausschlüsse.
|
||||
- **Verarbeitung & Regeln:** Aktiviert/deaktiviert Control-Set und Template-Set; z. B. Prototypenschutz nur bei entsprechendem Prüfziel, AL3 schaltet Zusatzanforderungen „sehr hoher Schutzbedarf" frei.
|
||||
- **Erzeugte Objekte:** Scope-Objekt; gefiltertes Control-Set als Arbeitsgrundlage.
|
||||
- **Umsetzungshinweise:** Erläuterung der Prüfziele und Level (Entscheidungshilfe AL2 vs. AL3), typische Scope-Formulierungen.
|
||||
- **Aufgaben-Trigger:** i. d. R. keine.
|
||||
- **Validierung:** Scope wird durch ISB/Berater bestätigt (Fundament für alles Weitere).
|
||||
- **Ressourcen (Entwicklung):** Frontend (Scoping-UI) S · Backend (Scope-Filterlogik) M · SME (Scope-Regeln) S.
|
||||
- **Akzeptanzkriterien:** Geänderter Scope filtert nachgelagerte Schritte korrekt; nicht relevante Controls/Templates sind ausgeblendet.
|
||||
|
||||
### Schritt 2 – Kontextaufnahme (Gegebenheiten)
|
||||
|
||||
- **Zweck:** Die tatsächlichen Gegebenheiten der Organisation als Faktenbasis erheben, die Platzhalter befüllt und Regeln aktiviert.
|
||||
- **Eingaben:** Geführter Fragebogen – Unternehmensdaten, Organisationsstruktur, IT-Landschaft (Systeme, Cloud, Netzwerke), eingesetzte Dienstleister, relevante Prozesse, grundlegender Schutzbedarf.
|
||||
- **Verarbeitung & Regeln:** Antworten werden als wiederverwendbare Faktenobjekte gespeichert und mit Platzhaltern, Klauselregeln, Controls, Assets und Risiken verknüpft. Bedingte Fragen (nur anzeigen, wenn relevant).
|
||||
- **Erzeugte Objekte:** Faktenprofil der Organisation.
|
||||
- **Umsetzungshinweise:** Erläuterung, warum eine Angabe gebraucht wird und wie sie sich auf Dokumente/Bewertung auswirkt.
|
||||
- **Aufgaben-Trigger:** Fehlende Grundvoraussetzung erkennbar (z. B. „kein Inventar vorhanden") → optionale Aufgabe.
|
||||
- **Validierung:** Plausibilitätsprüfung durch ISB/Berater.
|
||||
- **Ressourcen (Entwicklung):** Frontend (dynamischer Fragebogen) M · Backend (Faktenmodell, bedingte Logik) M · SME (Fragenkatalog) M.
|
||||
- **Akzeptanzkriterien:** Antworten sind wiederverwendbar; eine Änderung propagiert sichtbar in abhängige Objekte.
|
||||
|
||||
### Schritt 3 – Rollen & Verantwortlichkeiten
|
||||
|
||||
- **Zweck:** ISMS-Rollen festlegen (Geschäftsführung, ISB/DSB, IT-Verantwortung), inkl. Funktionstrennung.
|
||||
- **Eingaben:** Personen/Funktionen je Rolle; intern/extern; Weisungs-/Berichtswege.
|
||||
- **Verarbeitung & Regeln:** Prüft auf Funktionstrennung (z. B. ISB ≠ IT-Verantwortung); befüllt Rollen-Platzhalter in Dokumenten (Bestellungen/Ernennungen).
|
||||
- **Erzeugte Objekte:** Rollenmodell; Dokumente wie ISB-Bestellung (aus Vorlage, optional).
|
||||
- **Umsetzungshinweise:** Anforderungen an ISB-Qualifikation, externe vs. interne Besetzung, typische Nachweise.
|
||||
- **Aufgaben-Trigger:** Fehlende ISB-Bestellung / fehlende Funktionstrennung → Aufgabe (organisatorische Maßnahme).
|
||||
- **Validierung:** Freigabe des Rollenmodells.
|
||||
- **Ressourcen (Entwicklung):** Frontend S · Backend (Rollenmodell, Regelprüfung) M · SME S.
|
||||
- **Akzeptanzkriterien:** Funktionstrennungs-Konflikt wird erkannt und als Hinweis/Aufgabe ausgewiesen.
|
||||
|
||||
### Schritt 4 – Richtlinien & Verfahrensanweisungen
|
||||
|
||||
- **Zweck:** Für jeden relevanten Themenbereich die belegenden Dokumente bereitstellen – flexibel in der Quelle.
|
||||
- **Eingaben:** Je Themenbereich Auswahl einer von drei Optionen:
|
||||
(a) mitgelieferte Vorlage tailoren (Platzhalter aus Fakten befüllt, nicht zutreffende Klauseln ausgeblendet),
|
||||
(b) eigene Richtlinie hochladen und den abgedeckten Controls zuordnen,
|
||||
(c) als offen markieren / später erstellen.
|
||||
- **Verarbeitung & Regeln:** (a) Template-Engine erzeugt kundenspezifisches Dokument aus Faktenprofil + Regeln; (b) Upload wird gespeichert und über Control-Mapping in die Nachweislage aufgenommen; (c) erzeugt Aufgabe.
|
||||
- **Erzeugte Objekte:** Dokumenten-Set (generiert oder hochgeladen) mit Control-Verknüpfung und Versionsbezug.
|
||||
- **Umsetzungshinweise:** Was die jeweilige Richtlinie mindestens enthalten muss (VDA-ISA-Bezug); Formulierungsbausteine.
|
||||
- **Aufgaben-Trigger:** Option (c) „später erstellen" → Aufgabe `Dokument erstellen`; hochgeladenes Dokument ohne vollständige Control-Abdeckung → Hinweis/Aufgabe.
|
||||
- **Validierung:** Freigabe je Dokument (Objekt-Ebene).
|
||||
- **Ressourcen (Entwicklung):** Backend (Template-Engine, Platzhalter/Regeln, Rendering) L · Frontend (Auswahl, Editor/Vorschau, Upload) L · SME/Content (Vorlagen mit Regeln auszeichnen) L.
|
||||
- **Akzeptanzkriterien:** Generiertes Dokument enthält keine unaufgelösten Platzhalter und keine nicht zutreffenden Klauseln; hochgeladenes Dokument ist Controls zugeordnet.
|
||||
|
||||
### Schritt 5 – Werte-/Assetinventar (Grundstock)
|
||||
|
||||
- **Zweck:** Die für Scope und Schutzbedarf nötigen Informationswerte/Assets erfassen.
|
||||
- **Eingaben:** Assets (Kategorie, Eigentümer, Schutzziele C/I/A, Schutzbedarf, Standort/Verknüpfung).
|
||||
- **Verarbeitung & Regeln:** Assets werden Risiken (Schritt 6) und Controls zugeordnet; Schutzbedarf steuert die AL3-Relevanz von Zusatzanforderungen.
|
||||
- **Erzeugte Objekte:** Assetinventar (Grundstock).
|
||||
- **Umsetzungshinweise:** Wie man Werte identifiziert und Schutzbedarf herleitet; Beispielkategorien.
|
||||
- **Aufgaben-Trigger:** Unvollständiges Inventar / fehlender Eigentümer → Aufgabe.
|
||||
- **Validierung:** Freigabe des Inventars.
|
||||
- **Ressourcen (Entwicklung):** Frontend (Inventar-CRUD, Import) M · Backend (Assetmodell, Verknüpfungen) M · SME S.
|
||||
- **Akzeptanzkriterien:** Jedes Asset hat Eigentümer und Schutzbedarf; Verknüpfung zu Risiken/Controls möglich.
|
||||
|
||||
### Schritt 6 – Risikomanagement
|
||||
|
||||
- **Zweck:** Risiken systematisch erfassen, bewerten und behandeln – auf Basis eines Katalogs mit Standard- und VDA-geforderten Risiken.
|
||||
- **Eingaben:** Auswahl aus Risiko-Katalog (Standard/VDA) + eigene Ergänzungen; Bewertung (Eintrittswahrscheinlichkeit/Schadensausmaß); Behandlungsentscheidung.
|
||||
- **Verarbeitung & Regeln:** Risiken werden mit Assets und Controls verknüpft; Bewertungsmethodik (Skalen, Akzeptanzlinie) wird angewendet; Behandlungsoptionen (reduzieren/übertragen/vermeiden/akzeptieren) mit Maßnahmenableitung.
|
||||
- **Erzeugte Objekte:** Risikoregister; Behandlungsmaßnahmen.
|
||||
- **Umsetzungshinweise:** Vorschlag typischer Maßnahmen je Risiko; Erläuterung der Bewertungsmethodik.
|
||||
- **Aufgaben-Trigger:** Jede Behandlungsmaßnahme, die Umsetzung erfordert → Aufgabe (technisch/organisatorisch), verknüpft mit Risiko und Control (z. B. Risiko „Schadsoftware" → Aufgabe „Endpoint-/Patchmanagement einführen").
|
||||
- **Validierung:** Freigabe des Risikoregisters bzw. je Risiko.
|
||||
- **Ressourcen (Entwicklung):** Backend (Risikomodell, Bewertungslogik, Katalog) L · Frontend (Register, Matrix, Bewertung) L · SME (Risiko-Katalog + Standardmaßnahmen) L.
|
||||
- **Akzeptanzkriterien:** VDA-geforderte Risiken sind auswählbar; jedes inakzeptable Risiko hat eine Behandlung; Maßnahmen erzeugen Aufgaben.
|
||||
|
||||
### Schritt 7 – Control-Zuordnung & Reifegrad
|
||||
|
||||
- **Zweck:** Je relevantem VDA-ISA-Control die Umsetzung bewerten und Reifegrad einschätzen.
|
||||
- **Eingaben:** Je Control: Verknüpfung der belegenden Dokumente/Risiken/Assets; geführte Reifegrad-Selbsteinschätzung; ggf. Kurzbeschreibung.
|
||||
- **Verarbeitung & Regeln:** Reifegrad-/Gap-Engine schlägt auf Basis vorhandener Belege einen Reifegrad vor; offene Teilanforderungen werden markiert.
|
||||
- **Erzeugte Objekte:** Control-Bewertung (Reifegrad, Belege, offene Punkte) – die Rohdaten des späteren VDA-ISA-Katalogs.
|
||||
- **Umsetzungshinweise:** Pro Teilanforderung „So setzen Sie das um" (organisatorisch/technisch, Nachweise, passende Vorlage, Ressourcenbedarf).
|
||||
- **Aufgaben-Trigger:** Reifegrad unter Ziel / offene Teilanforderung → Aufgabe (Dokument, Nachweis, technische oder organisatorische Maßnahme).
|
||||
- **Validierung:** Freigabe der Control-Bewertung durch ISB/Berater.
|
||||
- **Ressourcen (Entwicklung):** Backend (Scoring/Gap-Logik, Verknüpfungen) L · Frontend (Control-Ansicht, Belege, Reifegrad) L · SME (Reifegrad-Logik, Hinweis-Content) L.
|
||||
- **Akzeptanzkriterien:** Jede relevante Teilanforderung ist adressiert; Reifegradvorschlag ist nachvollziehbar an Belege gekoppelt.
|
||||
|
||||
### Schritt 8 – Gap- & Maßnahmenableitung
|
||||
|
||||
- **Zweck:** Offene Punkte aus Controls und Risikobehandlung zu einer priorisierten Maßnahmenliste zusammenführen.
|
||||
- **Eingaben:** Ergebnisse aus Schritt 6 und 7; bestehende Aufgaben.
|
||||
- **Verarbeitung & Regeln:** Deduplizierung, Priorisierung (Muss-/AL3-kritisch = hoch), Konsolidierung zu einer Gesamtsicht; Abgleich mit dem Aufgaben-Modul.
|
||||
- **Erzeugte Objekte:** Konsolidierte Maßnahmen-/Gap-Liste (verknüpft mit Aufgaben).
|
||||
- **Umsetzungshinweise:** Priorisierungslogik erläutert; Quick-Wins hervorgehoben.
|
||||
- **Aufgaben-Trigger:** Jeder offene Punkt ohne bestehende Aufgabe → Aufgabe.
|
||||
- **Validierung:** Freigabe der Maßnahmenliste.
|
||||
- **Ressourcen (Entwicklung):** Backend (Aggregation/Dedup/Priorisierung) M · Frontend (Listenansicht, Filter) M.
|
||||
- **Akzeptanzkriterien:** Keine Dopplungen; jeder offene Punkt hat Priorität und – wo Umsetzung nötig – eine Aufgabe.
|
||||
|
||||
### Schritt 9 – Assessment-Readiness-Auswertung
|
||||
|
||||
- **Zweck:** Das Gesamtergebnis darstellen: vorausgefüllter VDA-ISA-Katalog, Reifegrad-Dashboard, Maßnahmenplan.
|
||||
- **Eingaben:** Alle validierten Objekte.
|
||||
- **Verarbeitung & Regeln:** Aggregation der Reifegrade je Kapitel/gesamt; „bestätigt vs. unbestätigt" nach Validierungsstatus; Export.
|
||||
- **Erzeugte Objekte:** VDA-ISA-Katalog-Sicht/Export; Reifegrad-Dashboard; Maßnahmenplan.
|
||||
- **Umsetzungshinweise:** Interpretation der Auswertung; empfohlene nächste Schritte vor dem Assessment.
|
||||
- **Aufgaben-Trigger:** Aus offenen Hoch-Punkten ableitbar (bereits in Schritt 8 erzeugt).
|
||||
- **Validierung:** Gesamtfreigabe/Abschluss durch ISB/Berater.
|
||||
- **Ressourcen (Entwicklung):** Backend (Aggregation, Export) M · Frontend (Dashboard, Katalogansicht) L · SME (Auswertungslogik) M.
|
||||
- **Akzeptanzkriterien:** Kennzahlen stimmen mit den Einzelbewertungen überein; Export ist vollständig und nachvollziehbar.
|
||||
|
||||
---
|
||||
|
||||
## 5. Entwicklungs-Fahrplan (Meilensteine mit Ressourcen)
|
||||
|
||||
| Meilenstein | Inhalt | Schritte | Kern-Ressourcen | Größe |
|
||||
|---|---|---|---|---|
|
||||
| M1 Fundament | Datenmodell + Import Control-Katalog VDA ISA | – | Backend, SME | M |
|
||||
| M2 Frage-Engine | Scoping + Kontext + Rollen | 1–3 | Backend, Frontend, SME | L |
|
||||
| M3 Richtlinien-Modul | Template-Engine + Upload/Control-Mapping | 4 | Backend, Frontend, Content-SME | L |
|
||||
| M4 Asset- & Risiko-Modul | Assetinventar + Risiko-Katalog + Bewertung | 5–6 | Backend, Frontend, SME | L |
|
||||
| M5 Bewertungs-Engine | Control-Mapping, Reifegrad/Gap, Maßnahmen-Konsolidierung | 7–8 | Backend, SME, Frontend | L |
|
||||
| M6 Ergebnis/Output | Assessment-Readiness-Auswertung + Export | 9 | Backend, Frontend | M |
|
||||
| M7 Governance (querlaufend) | Validierungs-Workflow, Aufgaben-Integration, Audit-Trail, Versionierung, Umsetzungshinweise | alle | Backend, Frontend, SME | L |
|
||||
|
||||
**Kürzester Pfad zur Assessment-Readiness:** M1 → M2 → M3 → M4 → M5 → M6. M7 wird parallel eingezogen (Validierung, Aufgaben und Hinweise sollten nicht nachträglich „angeflanscht" werden). Nachweis-Upload ist bewusst spätere Iteration.
|
||||
|
||||
---
|
||||
|
||||
## 6. Ressourcen-Gesamtübersicht (Rollen im Entwicklungsprojekt)
|
||||
|
||||
| Rolle | Beitrag | Auslastung (grob) |
|
||||
|---|---|---|
|
||||
| ISMS/TISAX-SME (Fachredaktion) | Control-Katalog, Templates mit Regeln, Risiko-Katalog, Umsetzungshinweise, Reifegrad-/Bewertungslogik | hoch, durchgehend – der inhaltliche Flaschenhals |
|
||||
| Backend-Entwicklung | Datenmodell, Regel-/Mapping-Engine, Scoring, Task-Integration, API, Audit-Trail | hoch |
|
||||
| Frontend-Entwicklung | Wizard-Flow, dynamische Formulare, Editor/Vorschau, Dashboards | hoch |
|
||||
| Content-/Template-Engineering | Vorlagen mit Platzhaltern und Regel-Tags auszeichnen | mittel, in M3 konzentriert |
|
||||
| UX/Design | geführter Flow, Statusführung, Hinweis-Panels | mittel |
|
||||
| QA/Test | Regel-/Scoring-Korrektheit, Dokumentgenerierung, Freigabelogik | mittel–hoch |
|
||||
|
||||
**Wichtig:** Der größte, oft unterschätzte Aufwand liegt nicht in der Software, sondern im **Fachcontent** (Control-Daten, regelfähige Vorlagen, Risiko-Katalog, Umsetzungshinweise). Dieser sollte parallel und früh durch die Beratung erstellt werden, sonst wird er zum kritischen Pfad.
|
||||
|
||||
---
|
||||
|
||||
## 7. Offene Entscheidungspunkte (vor der technischen Spezifikation zu klären)
|
||||
|
||||
1. **Upload eigener Richtlinien:** nur Control-Zuordnung, oder zusätzlich ein automatischer Abgleich Dokumentinhalt ↔ Anforderungen (Gap-Check)?
|
||||
2. **Risiko-Bewertungsmethodik:** fest vorgegeben oder mandantenspezifisch konfigurierbar (Skalen, Akzeptanzlinie)?
|
||||
3. **Versionierung von Katalog/Templates/Risiken:** wie werden laufende Kundeninstanzen bei Updates nachgezogen (automatisch, mit Diff, manuell)?
|
||||
4. **Validierungsgranularität:** pro Modul, zusätzlich pro Einzelobjekt (einzelne Richtlinie/Risiko/Control)?
|
||||
5. **Aufgaben-Modul:** existiert bereits mit passender Schnittstelle, oder muss die Task-Erzeugung mitgeplant werden?
|
||||
6. **Reifegrad-Vorschlag:** rein regelbasiert aus Belegen, oder als Empfehlung mit Pflicht zur Bestätigung durch den Bearbeiter?
|
||||
|
||||
---
|
||||
|
||||
## 8. Nächster Schritt
|
||||
|
||||
Nach Verifizierung dieses Fahrplans: technische Feinspezifikation je Modul (Datenschemata, Regel-Syntax, API-Verträge, UI-Wireframes, Akzeptanztests) – vorgeschlagene Reihenfolge entlang der Meilensteine M1–M7.
|
||||
@@ -0,0 +1,9 @@
|
||||
# Hinweis: STAND-dev-branch.md liegt zentral
|
||||
|
||||
Die im Original-Übergabepaket enthaltene Kopie von `STAND-dev-branch.md` (Stand 2026-07-24)
|
||||
wurde **bewusst nicht** hier abgelegt, um keinen zweiten, veralteten Stand zu führen.
|
||||
|
||||
**Maßgeblich ist die zentrale Datei im Repo:** [`docs/STAND-dev-branch.md`](../../STAND-dev-branch.md)
|
||||
(wird nach jeder abgeschlossenen Arbeit gepflegt — Single Source of Truth).
|
||||
|
||||
Weitere Basis-Doku: `docs/HANDOVER-DEV.md`, `docs/HANDOVER-PM.md`, `docs/SPEC.md`.
|
||||
@@ -0,0 +1,20 @@
|
||||
# Onboarding-Wizard — Übergabepaket (Entwicklung)
|
||||
|
||||
Alles, was die beiden Entwickler und der Berater für die parallele Umsetzung brauchen.
|
||||
|
||||
## Reihenfolge / Einstieg
|
||||
1. **00_Entwicklerpakete/** — je ein fertiger Umsetzungs-Prompt:
|
||||
- `Paket-DevA-Wizard-Scoping.md` — Wizard-Shell, Scoping, **AL2/AL3 zentral im Adminportal**.
|
||||
- `Paket-DevB-Engines-Richtlinien.md` — Aufgaben/Regel-Engine, Fragebogen, **Richtlinien-Import bei Modul-Aktivierung + manueller Upload**.
|
||||
- Beide enthalten einen **identischen Contracts-Anhang** (Naht) + Datei-Hoheit → konfliktarm parallel. Vorab: 15-Min-Kickoff.
|
||||
2. **01_Planung/** — Kontext & Gesamtbild:
|
||||
- `Wizard-Stories.md` (kompletter Story-Backlog F/A/B), `Wizard-Entwickler-Backlog.md` (2-Lane-Plan),
|
||||
`Onboarding-Wizard-Machbarkeitsanalyse.md` (Ist-Abgleich), `Berater-Anweisung-Fachcontent.md`.
|
||||
3. **02_Fachcontent_C1-C9/** — Zuarbeit des Fachberaters (ID-konsistent zu `isms-vorlagenpaket-v2`). Start: `C0_README-...`.
|
||||
4. **03_Referenz/** — Berater-Fahrplan + Dev-Stand `dev`.
|
||||
|
||||
## Wichtig
|
||||
- Basis-Branch **`dev`**; Feature-Branches `dev/a*-…` bzw. `dev/b*-…`; PR-Ziel `dev`.
|
||||
- **Definition of Ready** je Story: zugehöriges C-Paket eingespielt, bei Seed-Änderung `python3 seed/isms-vorlagenpaket-v2/_verify.py` → **OK**.
|
||||
- Kritischer Pfad Fachcontent: C2 → C1/C3 → C5/C6.
|
||||
- Offene Fachpunkte (C0): neue `FLAG_*` in `variables.schema.json`, P01/D01+VA-20 anlegen, Baseline-`BL-*` normalisieren, ISB-Freigabe.
|
||||
Reference in New Issue
Block a user