9.3 KiB
1. Zusammenfassung
Claude benennt valide Architektur-Risiken. Für das Projekt werden daraus keine neuen Produktziele abgeleitet, sondern konkrete Korrekturen an Datenmodell, Security-Dokumentation, ADRs und Betriebsregeln.
Kernentscheidungen:
tenant_idwird der einzige technische Mandanten-Isolationsschlüssel.organisation_idwird nicht mehr für Tenant-Isolation verwendet.- Multi-Tenancy wird nicht „halb vorbereitet“, sondern technisch sauber in V1 angelegt.
- Secrets werden nicht im Domainmodell gespeichert, sondern nur referenziert.
- Audit-Hash-Chain wird nicht als manipulationssichere Security-Maßnahme verkauft.
- DLQ, Dokumente, Rollen und Reconciliation erhalten konkrete Regeln.
- Bounded Contexts werden als Modul-/Schema-Grenzen dokumentiert, keine Microservice-Aufspaltung.
2. Übernommene Punkte
Tenant-Isolation
Übernehmen.
Änderung:
tenant_idist Pflichtfeld auf allen mandantenbezogenen Tabellen.organisation_idwird aus der technischen Isolation entfernt.- Falls Organisation benötigt wird, dann nur fachlich, z. B. als
customer_organisation_id. - PostgreSQL Row-Level-Security wird vorgesehen.
- Tenant-Kontext wird pro Request/Job explizit gesetzt.
- Queries ohne Tenant-Kontext müssen fehlschlagen.
Konkrete Modellregel:
tenant_id UUID NOT NULL REFERENCES tenants(id)
Für mandantenbezogene Relationen:
FOREIGN KEY (tenant_id, customer_id)
REFERENCES customers(tenant_id, id)
Secrets-Management
Übernehmen.
Änderung:
- Keine API-Keys, Passwörter oder Tokens in Fachentitäten.
- Domainmodelle speichern nur
secret_ref. - Secret-Service wird als technischer Baustein dokumentiert.
- Encryption-at-rest wird verpflichtend für Secret-Storage.
- Zugriff auf Secrets nur über Service-Layer, nicht über direkte DB-Reads.
Beispiel:
registrar_accounts.secret_ref
statt:
registrar_accounts.api_key
registrar_accounts.password
Audit-Log
Teilweise übernehmen.
Änderung:
- Hash-Chain wird nicht als Schutz gegen DB-Admin-Manipulation beschrieben.
- Audit-Log bleibt append-only auf Anwendungsebene.
- Integritätsprüfung wird klar abgegrenzt.
- Optional: periodischer Export/Checkpoint in externes System.
ADR 0014 muss entsprechend korrigiert werden.
Dead Letter Queue
Übernehmen.
Änderung:
- DLQ erhält Retention-Regeln.
- PII in Fehlerpayloads wird vermieden oder redaktiert.
- Maximale Aufbewahrung wird festgelegt.
- Reprocessing und Löschung werden beschrieben.
Vorschlag:
DLQ default retention: 30 Tage
DLQ max retention: 90 Tage
PII payloads: nicht speichern oder redaktieren
Bounded Contexts
Übernehmen, aber pragmatisch.
Änderung:
- Keine sofortige Service-Aufteilung.
- Einführung klarer Modulgrenzen im Monolithen.
- Datenmodell wird nach fachlichen Bereichen gegliedert.
Kontexte:
- Identity & Access
- CRM
- Billing
- Provisioning
- Registry
- Support
- Documents
- Audit
Reconciliation
Teilweise übernehmen.
Änderung:
- Kein vollständiges Event-Sourcing für V1.
- Stattdessen Operation-/Job-Historie und Status-Snapshots.
- Reconciliation basiert auf:
- gewünschtem Zustand
- aktuellem externem Zustand
- letzter Operation
- Fehlerhistorie
Benötigte Tabellen/Modelle:
provisioning_operations
external_resource_snapshots
job_runs
job_attempts
Rollen und Scopes
Übernehmen.
Änderung:
- Rollen werden nicht nur benannt, sondern mit konkreten Berechtigungen dokumentiert.
- Zugriff auf Secrets, Rechnungen, Serverdaten und Kundendaten wird explizit geregelt.
Beispielrollen:
- Owner
- Admin
- Billing
- Support
- Provisioning Operator
- Read-only Auditor
Dokument-Storage
Übernehmen.
Änderung:
- Dokumente speichern keine Datei direkt im Datenmodell.
- Dokumente referenzieren Object Storage.
- Tenant-Isolation über Bucket/Prefix plus DB-Zugriffskontrolle.
- Löschung, Archivierung und Legal Hold werden dokumentiert.
Beispiel:
documents.object_key
documents.storage_provider
documents.checksum_sha256
documents.retention_until
documents.legal_hold
documents.deleted_at
3. Abgelehnte oder verschobene Punkte
Vollständiges Event-Sourcing
Verschoben.
Begründung:
- Für V1 nicht erforderlich.
- Reconciliation kann über Operation-Historie, Job-Historie und Snapshots umgesetzt werden.
Microservice-Aufteilung nach Bounded Contexts
Abgelehnt für V1.
Begründung:
- Zu hoher Betriebs- und Integrationsaufwand.
- Modulgrenzen im Monolithen reichen aktuell aus.
Audit-Hash-Chain als Manipulationsschutz
Abgelehnt.
Änderung:
- Hash-Chain darf maximal als Integritätsindikator beschrieben werden.
- Kein Sicherheitsversprechen gegen privilegierte DB-Manipulation.
Parallele Nutzung von organisation_id und tenant_id
Abgelehnt.
Änderung:
- Nur
tenant_idist technischer Scope. - Organisation ist, falls benötigt, ein CRM-/Kundenkonzept.
Single-Tenant V1 ohne Tenant-Schutz
Abgelehnt.
Änderung:
- V1 darf fachlich nur einen aktiven Tenant haben.
- Technisch wird Tenant-Isolation trotzdem sauber eingebaut.
4. Neue/geänderte Dateien
Geändert
docs/data-model-v0.2.md
Änderungen:
organisation_idaus technischer Mandanten-Isolation entfernen.tenant_idals verbindlichen Scope definieren.- Tenant-FK-Regeln ergänzen.
- Tabellen nach Bounded Contexts gruppieren.
- Secret-Felder durch
secret_refersetzen. - Dokumentmodell um Storage-Metadaten erweitern.
- Operation-/Job-Historie ergänzen.
docs/security.md
Änderungen:
- Tenant-Isolation konkretisieren.
- Secrets-Management konkretisieren.
- RBAC/Scopes verlinken.
- RLS und Tenant-Kontext als Pflichtmechanismus aufnehmen.
docs/adr/0014-audit-log.md
Änderungen:
- Hash-Chain nicht mehr als manipulationssicher beschreiben.
- Algorithmus konkretisieren, falls beibehalten.
- Optionalen externen Checkpoint/Export dokumentieren.
- Grenzen des Mechanismus explizit nennen.
docs/adr/0017-jobs-reconciliation-dlq.md
Änderungen:
- DLQ-Retention ergänzen.
- PII-Regeln ergänzen.
- Reprocessing-Regeln ergänzen.
- Reconciliation-Datenbasis ergänzen.
Neu
docs/architecture/tenant-isolation.md
Inhalt:
tenant_idals einziger technischer Mandantenschlüssel- Request-/Job-Tenant-Kontext
- Fail-closed-Verhalten
- RLS-Grundregeln
- Cross-Tenant-Zugriffe verboten
- Composite FK-Regeln
docs/architecture/bounded-contexts.md
Inhalt:
- Modulgrenzen
- erlaubte Abhängigkeiten
- Besitz von Tabellen/Entitäten
- keine direkten Fremdzugriffe zwischen Kontexten ohne definierte Schnittstelle
docs/security/secrets-management.md
Inhalt:
- Secret-Service-Konzept
secret_ref- keine Klartext-Secrets in DB
- Rotation
- Zugriffskontrolle
- Auditierung von Secret-Zugriffen
docs/security/rbac-matrix.md
Inhalt:
| Bereich | Owner | Admin | Billing | Support | Provisioning | Auditor |
|---|---|---|---|---|---|---|
| Kunden lesen | ja | ja | ja | ja | ja | ja |
| Kunden ändern | ja | ja | nein | eingeschränkt | nein | nein |
| Rechnungen lesen | ja | ja | ja | nein | nein | ja |
| Rechnungen ändern | ja | ja | ja | nein | nein | nein |
| Serverdaten lesen | ja | ja | nein | eingeschränkt | ja | ja |
| Server ändern | ja | ja | nein | nein | ja | nein |
| Secrets lesen | nein | nein | nein | nein | nein | nein |
| Secret nutzen | ja | ja | nein | nein | system | nein |
docs/storage/document-storage.md
Inhalt:
- Object-Storage-Strategie
- Tenant-Isolation per Prefix/Bucket
- Checksums
- Archivierung
- Löschanfragen
- Legal Hold
- Zugriffskontrolle
docs/operations/dlq-retention.md
Inhalt:
- DLQ-Retention
- PII-Regeln
- Reprocessing
- manuelle Freigabe
- endgültige Löschung
- Monitoring
docs/operations/reconciliation.md
Inhalt:
- gewünschter Zustand
- externer Ist-Zustand
- Operation-Historie
- Snapshot-Modell
- Konfliktbehandlung
- Retry-Strategie
db/policies/tenant_rls.sql
Inhalt:
- PostgreSQL RLS-Grundstruktur
- Policy pro mandantenbezogener Tabelle
- Nutzung von
current_setting('app.tenant_id') - Fail-closed bei fehlendem Tenant-Kontext
Beispiel:
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation_customers
ON customers
USING (
tenant_id = current_setting('app.tenant_id')::uuid
);
db/migrations/xxxx_add_tenant_scope.sql
Inhalt:
tenants-Tabelletenant_idauf mandantenbezogenen Tabellen- NOT NULL Constraints
- Composite Foreign Keys
- Indizes auf
(tenant_id, id)
5. Konkrete nächste Schritte
-
docs/data-model-v0.2.mdanpassen:tenant_idfestlegenorganisation_idaus Isolation entfernen- Secret-Felder durch
secret_refersetzen
-
docs/architecture/tenant-isolation.mdneu erstellen. -
db/migrations/xxxx_add_tenant_scope.sqlvorbereiten:tenantstenant_id- Constraints
- Indizes
-
db/policies/tenant_rls.sqlerstellen. -
docs/security/secrets-management.mderstellen. -
docs/security/rbac-matrix.mderstellen. -
ADR 0014 überarbeiten:
- keine falsche Sicherheitsbehauptung zur Hash-Chain
-
ADR 0017 überarbeiten:
- DLQ-Retention
- PII-Regeln
- Reconciliation-Datenbasis
-
docs/storage/document-storage.mderstellen. -
docs/architecture/bounded-contexts.mderstellen und Datenmodell danach gruppieren.