import { CodeBlock, InfoBox } from '@/components/DevPortalLayout'
export function EncryptionNamespaceSection() {
return (
<>
6. Ende-zu-Ende-Verschluesselung
Die Verschluesselung findet vollstaendig auf dem System des Kunden statt --
der Cloud-Server bekommt nur verschluesselte Daten zu sehen.
6.1 Der Verschluesselungsvorgang
{`┌─────────────────────────────────────────────────────────────────┐
│ System des Kunden (SDK) │
├─────────────────────────────────────────────────────────────────┤
│ 1. Kunde konfiguriert Passphrase im SDK │
│ → Passphrase bleibt hier -- wird NIE gesendet │
│ │
│ 2. Schluessel-Ableitung: │
│ PBKDF2-SHA256(Passphrase, zufaelliger Salt, 100.000 Runden) │
│ → Ergebnis: 256-Bit-Schluessel (32 Bytes) │
│ │
│ 3. Verschluesselung: │
│ AES-256-GCM(Schluessel, zufaelliger IV, Dokument) │
│ → GCM: Garantiert Integritaet (Manipulation erkennbar) │
│ │
│ 4. Schluessel-Hash: │
│ SHA-256(abgeleiteter Schluessel) → Hash fuer Verifikation │
│ → Vom Hash kann der Schluessel NICHT zurueckberechnet werden│
│ │
│ 5. Upload: Nur diese Daten gehen an den Cloud-Server: │
│ • Verschluesselter Blob • Salt • IV • Schluessel-Hash │
│ │
│ Was NICHT an den Server geht: │
│ ✗ Passphrase ✗ Abgeleiteter Schluessel ✗ Klartext │
└─────────────────────────────────────────────────────────────────┘`}
6.2 Sicherheitsgarantien
| Angriffsszenario |
Was der Angreifer sieht |
Ergebnis |
| Cloud-Server wird gehackt | Verschluesselte Blobs + Hashes | Keine lesbaren Dokumente |
| Datenbank wird geleakt | encrypted_identity_map (verschluesselt) | Keine personenbezogenen Daten |
| Netzwerkverkehr abgefangen | Verschluesselte Daten (TLS + AES) | Doppelt verschluesselt |
| Betreiber (Breakpilot) will mitlesen | Verschluesselte Blobs, kein Schluessel | Operator Blindness |
| Anderer Kunde versucht Zugriff | Nichts (Tenant-Isolation) | Namespace blockiert |
7. Namespace-Isolation: Jeder Kunde hat seinen eigenen Bereich
Ein Namespace ist ein vollstaendig abgeschotteter Bereich im System -- wie
separate Tresorraeume in einer Bank. Jeder Kunde hat seinen eigenen Raum,
und kein Schluessel passt in einen anderen.
{`Kunde A (tenant_id: "firma-alpha-001")
├── Dokument 1 (verschluesselt)
└── Referenz: Pruefkriterien 2025
Kunde B (tenant_id: "firma-beta-002")
└── Referenz: Compliance-Vorgaben 2025
Suchanfrage von Kunde A:
→ Suche NUR in tenant_id = "firma-alpha-001"
→ Kunde B's Daten sind UNSICHTBAR
Jede Qdrant-Query hat diesen Pflichtfilter:
must_conditions = [
FieldCondition(key="tenant_id", match="firma-alpha-001")
]`}
7.2 Drei Ebenen der Isolation
| Ebene |
System |
Isolation |
| Dateisystem | MinIO (S3-Storage) | Eigener Bucket/Pfad pro Kunde |
| Vektordatenbank | Qdrant | Pflichtfilter tenant_id bei jeder Suche |
| Metadaten-DB | PostgreSQL | Jede Tabelle hat tenant_id als Pflichtfeld |
Auf allen Vektoren in Qdrant ist das Flag training_allowed: false gesetzt.
Kundeninhalte werden ausschliesslich fuer RAG-Suchen innerhalb des
Kunden-Namespace verwendet.
>
)
}