refactor(developer-portal): split iace, docs, byoeh pages
Extract each page into colocated _components/ sections to bring page.tsx files from 1008/891/769 LOC down to 57/23/21 LOC, well within the 500-line hard cap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import { CodeBlock, InfoBox } from '@/components/DevPortalLayout'
|
||||
|
||||
export function EncryptionNamespaceSection() {
|
||||
return (
|
||||
<>
|
||||
<h2 id="verschluesselung">6. Ende-zu-Ende-Verschluesselung</h2>
|
||||
<p>
|
||||
Die Verschluesselung findet <strong>vollstaendig auf dem System des Kunden</strong> statt --
|
||||
der Cloud-Server bekommt nur verschluesselte Daten zu sehen.
|
||||
</p>
|
||||
|
||||
<h3>6.1 Der Verschluesselungsvorgang</h3>
|
||||
<CodeBlock language="text" filename="Client-seitige Verschluesselung (im SDK)">
|
||||
{`┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 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 │
|
||||
└─────────────────────────────────────────────────────────────────┘`}
|
||||
</CodeBlock>
|
||||
|
||||
<h3>6.2 Sicherheitsgarantien</h3>
|
||||
<div className="not-prose my-6 overflow-x-auto">
|
||||
<table className="min-w-full divide-y divide-gray-200 text-sm">
|
||||
<thead className="bg-gray-50">
|
||||
<tr>
|
||||
<th className="px-4 py-3 text-left font-medium text-gray-500">Angriffsszenario</th>
|
||||
<th className="px-4 py-3 text-left font-medium text-gray-500">Was der Angreifer sieht</th>
|
||||
<th className="px-4 py-3 text-left font-medium text-gray-500">Ergebnis</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200">
|
||||
<tr><td className="px-4 py-3 font-medium">Cloud-Server wird gehackt</td><td className="px-4 py-3">Verschluesselte Blobs + Hashes</td><td className="px-4 py-3 text-green-700 font-medium">Keine lesbaren Dokumente</td></tr>
|
||||
<tr><td className="px-4 py-3 font-medium">Datenbank wird geleakt</td><td className="px-4 py-3">encrypted_identity_map (verschluesselt)</td><td className="px-4 py-3 text-green-700 font-medium">Keine personenbezogenen Daten</td></tr>
|
||||
<tr><td className="px-4 py-3 font-medium">Netzwerkverkehr abgefangen</td><td className="px-4 py-3">Verschluesselte Daten (TLS + AES)</td><td className="px-4 py-3 text-green-700 font-medium">Doppelt verschluesselt</td></tr>
|
||||
<tr><td className="px-4 py-3 font-medium">Betreiber (Breakpilot) will mitlesen</td><td className="px-4 py-3">Verschluesselte Blobs, kein Schluessel</td><td className="px-4 py-3 text-green-700 font-medium">Operator Blindness</td></tr>
|
||||
<tr><td className="px-4 py-3 font-medium">Anderer Kunde versucht Zugriff</td><td className="px-4 py-3">Nichts (Tenant-Isolation)</td><td className="px-4 py-3 text-green-700 font-medium">Namespace blockiert</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 id="namespace">7. Namespace-Isolation: Jeder Kunde hat seinen eigenen Bereich</h2>
|
||||
<p>
|
||||
Ein <strong>Namespace</strong> ist ein vollstaendig abgeschotteter Bereich im System -- wie
|
||||
<strong> separate Tresorraeume in einer Bank</strong>. Jeder Kunde hat seinen eigenen Raum,
|
||||
und kein Schluessel passt in einen anderen.
|
||||
</p>
|
||||
|
||||
<CodeBlock language="text" filename="Tenant-Isolation in der Vektordatenbank (Qdrant)">
|
||||
{`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")
|
||||
]`}
|
||||
</CodeBlock>
|
||||
|
||||
<h3>7.2 Drei Ebenen der Isolation</h3>
|
||||
<div className="not-prose my-6 overflow-x-auto">
|
||||
<table className="min-w-full divide-y divide-gray-200 text-sm">
|
||||
<thead className="bg-gray-50">
|
||||
<tr>
|
||||
<th className="px-4 py-3 text-left font-medium text-gray-500">Ebene</th>
|
||||
<th className="px-4 py-3 text-left font-medium text-gray-500">System</th>
|
||||
<th className="px-4 py-3 text-left font-medium text-gray-500">Isolation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200">
|
||||
<tr><td className="px-4 py-3 font-medium">Dateisystem</td><td className="px-4 py-3">MinIO (S3-Storage)</td><td className="px-4 py-3">Eigener Bucket/Pfad pro Kunde</td></tr>
|
||||
<tr><td className="px-4 py-3 font-medium">Vektordatenbank</td><td className="px-4 py-3">Qdrant</td><td className="px-4 py-3">Pflichtfilter <code>tenant_id</code> bei jeder Suche</td></tr>
|
||||
<tr><td className="px-4 py-3 font-medium">Metadaten-DB</td><td className="px-4 py-3">PostgreSQL</td><td className="px-4 py-3">Jede Tabelle hat <code>tenant_id</code> als Pflichtfeld</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<InfoBox type="warning" title="Kein Training mit Kundendaten">
|
||||
Auf allen Vektoren in Qdrant ist das Flag <code>training_allowed: false</code> gesetzt.
|
||||
Kundeninhalte werden <strong>ausschliesslich fuer RAG-Suchen</strong> innerhalb des
|
||||
Kunden-Namespace verwendet.
|
||||
</InfoBox>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user