This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/developer-portal/app/development/byoeh/page.tsx
BreakPilot Dev a5243f7d51
Some checks failed
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
docs: Rewrite BYOEH page for business customers (SDK namespace)
Reframes the Developer Portal BYOEH page from teacher-specific exam
correction to a general SDK offering for business customers who need
to send sensitive data to the cloud for AI processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 00:51:48 +01:00

770 lines
44 KiB
TypeScript

import { DevPortalLayout, CodeBlock, InfoBox } from '@/components/DevPortalLayout'
export default function BYOEHDocsPage() {
return (
<DevPortalLayout
title="Namespace-Technologie fuer Geschaeftskunden"
description="Wie das SDK sensible Daten anonymisiert, verschluesselt und sicher in der Cloud verarbeiten laesst -- ohne dass der Betreiber Zugriff auf Klartext hat."
>
{/* ============================================================ */}
{/* 1. EINLEITUNG */}
{/* ============================================================ */}
<h2 id="einfuehrung">1. Was ist die Namespace-Technologie?</h2>
<p>
Unsere <strong>Namespace-Technologie</strong> (intern BYOEH -- Bring Your Own Expectation Horizon)
ist eine Privacy-First-Architektur, die es Geschaeftskunden ermoeglicht, <strong>sensible Daten
anonym und verschluesselt</strong> von KI-Services in der Cloud verarbeiten zu lassen -- ohne dass
personenbezogene Informationen jemals den Client verlassen.
</p>
<blockquote>
<em>&ldquo;Daten gehen pseudonymisiert und verschluesselt in die Cloud, werden dort
von KI verarbeitet, und kommen verarbeitet zurueck. Nur der Kunde kann die Ergebnisse
wieder den Originaldaten zuordnen -- denn nur sein System hat den Schluessel dafuer.&rdquo;</em>
</blockquote>
<p>
Das SDK loest ein grundlegendes Problem fuer Unternehmen: <strong>KI-gestuetzte
Datenverarbeitung ohne Datenschutzrisiko</strong>. Die Architektur basiert auf vier Bausteinen:
</p>
<ol>
<li>
<strong>Pseudonymisierung:</strong> Personenbezogene Daten werden durch zufaellige
Tokens ersetzt. Nur der Kunde kennt die Zuordnung.
</li>
<li>
<strong>Client-seitige Verschluesselung:</strong> Alle Daten werden <em>auf dem System
des Kunden</em> verschluesselt, bevor sie die Infrastruktur verlassen. Der Cloud-Server
sieht nur verschluesselte Blobs.
</li>
<li>
<strong>Namespace-Isolation:</strong> Jeder Kunde erhaelt einen eigenen, vollstaendig
abgeschotteten Namespace. Kein Kunde kann auf Daten eines anderen zugreifen.
</li>
<li>
<strong>KI-Verarbeitung in der Cloud:</strong> Die KI arbeitet mit den pseudonymisierten
Daten und den vom Kunden bereitgestellten Referenzdokumenten. Ergebnisse gehen zurueck
an den Kunden zur lokalen Entschluesselung und Re-Identifizierung.
</li>
</ol>
<InfoBox type="info" title="Kern-Designprinzip: Operator Blindness">
<strong>Breakpilot kann die Kundendaten nicht lesen.</strong> Der Server sieht nur
verschluesselte Blobs und einen Schluessel-Hash (nicht den Schluessel selbst). Die
Passphrase zum Entschluesseln existiert <em>ausschliesslich</em> auf dem System des Kunden
und wird niemals uebertragen. Selbst ein Angriff auf die Cloud-Infrastruktur wuerde keine
Klartextdaten preisgeben.
</InfoBox>
{/* ============================================================ */}
{/* 2. ANWENDUNGSFAELLE */}
{/* ============================================================ */}
<h2 id="anwendungsfaelle">2. Typische Anwendungsfaelle</h2>
<p>
Die Namespace-Technologie ist ueberall einsetzbar, wo sensible Daten von einer KI
verarbeitet werden sollen, ohne den Datenschutz zu gefaehrden:
</p>
<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">Branche</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Anwendungsfall</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Sensible Daten</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr>
<td className="px-4 py-3 font-medium">Bildung</td>
<td className="px-4 py-3">KI-gestuetzte Klausurkorrektur</td>
<td className="px-4 py-3">Schuelernamen, Noten, Leistungsdaten</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Gesundheitswesen</td>
<td className="px-4 py-3">Medizinische Befundanalyse</td>
<td className="px-4 py-3">Patientennamen, Diagnosen, Befunde</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Recht</td>
<td className="px-4 py-3">Vertragsanalyse, Due Diligence</td>
<td className="px-4 py-3">Mandantendaten, Vertragsinhalte</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Personalwesen</td>
<td className="px-4 py-3">Bewerbungsscreening, Zeugnisanalyse</td>
<td className="px-4 py-3">Bewerberdaten, Gehaltsinformationen</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Finanzwesen</td>
<td className="px-4 py-3">Dokumentenpruefung, Compliance-Checks</td>
<td className="px-4 py-3">Kontodaten, Transaktionen, Identitaeten</td>
</tr>
</tbody>
</table>
</div>
{/* ============================================================ */}
{/* 3. DER KOMPLETTE ABLAUF */}
{/* ============================================================ */}
<h2 id="ablauf">3. Der komplette Ablauf im Ueberblick</h2>
<p>
Der Prozess laesst sich in sieben Schritte unterteilen. Die gesamte
Pseudonymisierung und Verschluesselung geschieht auf dem System des Kunden,
bevor Daten in die Cloud gesendet werden:
</p>
<CodeBlock language="text" filename="Workflow: Vom Quelldokument zur KI-verarbeiteten Ausgabe">
{`SCHRITT 1: DOKUMENTE ERFASSEN & PSEUDONYMISIEREN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
SDK empfaengt Dokumente (PDF, Bild, Text)
→ Personenbezogene Daten werden erkannt (Header, Namen, IDs)
→ PII wird durch zufaellige Tokens ersetzt (doc_token, UUID4)
→ Zuordnung "Token → Originalname" wird lokal gesichert
SCHRITT 2: CLIENT-SEITIGE VERSCHLUESSELUNG
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Kunde konfiguriert eine Passphrase im SDK
→ SDK leitet daraus einen 256-Bit-Schluessel ab (PBKDF2, 100k Runden)
→ Dokumente werden mit AES-256-GCM verschluesselt
→ Nur der Hash des Schluessels wird an den Server gesendet
→ Passphrase und Schluessel verlassen NIEMALS das Kundensystem
SCHRITT 3: IDENTITAETS-MAP SICHERN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Die Zuordnung "Token → Originaldaten" wird verschluesselt gespeichert:
→ Nur mit der Passphrase des Kunden rekonstruierbar
→ Ohne Passphrase ist keine Re-Identifizierung moeglich
SCHRITT 4: UPLOAD IN DEN KUNDEN-NAMESPACE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Verschluesselte Dateien gehen in den isolierten Namespace:
→ Jeder Kunde hat eine eigene tenant_id
→ Daten werden in MinIO (Storage) + Qdrant (Vektoren) gespeichert
→ Server sieht: verschluesselter Blob + Schluessel-Hash + Salt
SCHRITT 5: KI-VERARBEITUNG IN DER CLOUD
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
KI verarbeitet die pseudonymisierten Daten:
→ RAG-System durchsucht Referenzdokumente des Kunden
→ KI generiert Ergebnisse basierend auf Kundenkontext
→ Ergebnisse sind an den Namespace gebunden
SCHRITT 6: ERGEBNISSE ZURUECK
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
KI-Ergebnisse gehen an das Kundensystem:
→ SDK entschluesselt die Ergebnisse mit der Passphrase
→ Kunde sieht aufbereitete Ergebnisse im Klartext
SCHRITT 7: RE-IDENTIFIZIERUNG & FINALISIERUNG
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Kunde ordnet Ergebnisse den Originaldaten zu:
→ Identitaets-Map wird entschluesselt
→ Tokens werden wieder den echten Datensaetzen zugeordnet
→ Fertige Ergebnisse stehen im Originalsystem bereit`}
</CodeBlock>
{/* ============================================================ */}
{/* 4. SDK-INTEGRATION */}
{/* ============================================================ */}
<h2 id="sdk-integration">4. SDK-Integration</h2>
<p>
Die Integration in bestehende Systeme erfolgt ueber unser SDK. Nachfolgend ein
vereinfachtes Beispiel, wie ein Kunde das SDK nutzt:
</p>
<CodeBlock language="typescript" filename="Beispiel: SDK-Integration (TypeScript)">
{`import { BreakpilotSDK, NamespaceClient } from '@breakpilot/compliance-sdk'
// 1. SDK initialisieren mit API-Key
const sdk = new BreakpilotSDK({
apiKey: process.env.BREAKPILOT_API_KEY,
endpoint: 'https://api.breakpilot.de'
})
// 2. Namespace-Client erstellen (pro Mandant/Abteilung)
const namespace = sdk.createNamespace({
tenantId: 'kunde-firma-abc',
passphrase: process.env.ENCRYPTION_PASSPHRASE // Bleibt lokal!
})
// 3. Dokument pseudonymisieren & verschluesselt hochladen
const result = await namespace.upload({
file: documentBuffer,
metadata: { type: 'vertrag', category: 'due-diligence' },
pseudonymize: true, // PII automatisch ersetzen
headerRedaction: true // Kopfbereich entfernen
})
// result.docToken = "a7f3c2d1-4e9b-4a5f-8c7d-..."
// 4. Referenzdokument hochladen (z.B. Pruefkriterien)
await namespace.uploadReference({
file: referenceBuffer,
title: 'Pruefkriterien Vertrag Typ A'
})
// 5. KI-Verarbeitung anstossen
const analysis = await namespace.analyze({
docToken: result.docToken,
prompt: 'Pruefe den Vertrag gegen die Referenzkriterien',
useRAG: true
})
// 6. Ergebnisse entschluesseln (passiert automatisch im SDK)
console.log(analysis.findings) // Klartext-Ergebnisse
console.log(analysis.score) // Bewertung
// 7. Re-Identifizierung (Token → Originalname)
const identityMap = await namespace.getIdentityMap()
const originalName = identityMap[result.docToken]`}
</CodeBlock>
<InfoBox type="success" title="Zero-Knowledge-Architektur">
Die Passphrase verlässt niemals das System des Kunden. Das SDK verschluesselt
und entschluesselt <strong>ausschliesslich lokal</strong>. Breakpilot hat zu keinem
Zeitpunkt Zugriff auf Klartextdaten oder den Verschluesselungsschluessel.
</InfoBox>
{/* ============================================================ */}
{/* 5. PSEUDONYMISIERUNG */}
{/* ============================================================ */}
<h2 id="pseudonymisierung">5. Pseudonymisierung: Wie personenbezogene Daten entfernt werden</h2>
<p>
Pseudonymisierung bedeutet: personenbezogene Daten werden durch <strong>zufaellige
Tokens</strong> ersetzt, sodass ohne Zusatzinformation kein Rueckschluss auf die Person
moeglich ist. Das SDK bietet zwei Mechanismen:
</p>
<h3>5.1 Der doc_token: Ein zufaelliger Identifikator</h3>
<p>
Jedes Dokument erhaelt einen <strong>doc_token</strong> -- einen 128-Bit-Zufallscode im
UUID4-Format (z.B. <code>a7f3c2d1-4e9b-4a5f-8c7d-6b2e1f0a9d3c</code>). Dieser Token:
</p>
<ul>
<li>Ist <strong>kryptographisch zufaellig</strong> -- es gibt keinen Zusammenhang zwischen
Token und Originaldatensatz</li>
<li>Kann <strong>nicht zurueckgerechnet</strong> werden -- auch mit Kenntnis des Algorithmus
ist kein Rueckschluss moeglich</li>
<li>Dient als <strong>eindeutiger Schluessel</strong>, um Ergebnisse spaeter dem
Originaldokument zuzuordnen</li>
</ul>
<h3>5.2 Header-Redaction: PII wird entfernt</h3>
<p>
Bei Dokumenten mit erkennbarem Kopfbereich (Namen, Adressen, IDs) kann das SDK diesen
Bereich <strong>automatisch entfernen</strong>. Die Entfernung ist <strong>permanent</strong>:
Die Originaldaten werden nicht an den Server uebermittelt.
</p>
<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">Methode</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Wie es funktioniert</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Wann verwenden</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr>
<td className="px-4 py-3 font-medium">Einfache Redaction</td>
<td className="px-4 py-3">Definierter Bereich des Dokuments wird entfernt</td>
<td className="px-4 py-3">Standardisierte Formulare mit festem Layout</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Smarte Redaction</td>
<td className="px-4 py-3">OpenCV/NER erkennt Textbereiche mit PII und entfernt gezielt</td>
<td className="px-4 py-3">Freitext-Dokumente, variable Layouts</td>
</tr>
</tbody>
</table>
</div>
<h3>5.3 Die Identitaets-Map: Nur der Kunde kennt die Zuordnung</h3>
<p>
Die Zuordnung <em>doc_token Originaldaten</em> wird als <strong>verschluesselte Tabelle</strong>
gespeichert. Das Datenmodell sieht vereinfacht so aus:
</p>
<CodeBlock language="text" filename="Datenmodell: Namespace-Session (vereinfacht)">
{`NamespaceSession
├── tenant_id = "kunde-firma-abc" ← Pflichtfeld (Isolation)
├── encrypted_identity_map = [verschluesselte Bytes] ← Nur mit Passphrase lesbar
├── identity_map_iv = "a3f2c1..." ← Initialisierungsvektor (fuer AES)
└── PseudonymizedDocument (pro Dokument)
├── doc_token = "a7f3c2d1-..." ← Zufaelliger Token (Primary Key)
├── session_id = [Referenz]
└── (Kein Name, keine personenbezogenen Daten)`}
</CodeBlock>
<InfoBox type="success" title="DSGVO Art. 4 Nr. 5 konform">
Die Pseudonymisierung erfuellt die Definition der DSGVO: Personenbezogene Daten
koennen <strong>ohne Hinzuziehung zusaetzlicher Informationen</strong>
(der verschluesselten Identitaets-Map + der Passphrase des Kunden) nicht mehr einer
bestimmten Person zugeordnet werden.
</InfoBox>
{/* ============================================================ */}
{/* 6. VERSCHLUESSELUNG */}
{/* ============================================================ */}
<h2 id="verschluesselung">6. Ende-zu-Ende-Verschluesselung</h2>
<p>
Die Verschluesselung ist das Herzstueck des Datenschutzes. Sie 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) │
│ │ → 100.000 Runden machen Brute-Force unpraktikabel │
│ ▼ │
│ 3. Verschluesselung: │
│ AES-256-GCM(Schluessel, zufaelliger IV, Dokument) │
│ │ │
│ │ → AES-256: Militaerstandard, 2^256 moegliche Schluessel │
│ │ → GCM: Garantiert Integritaet (Manipulation erkennbar) │
│ ▼ │
│ 4. Schluessel-Hash: │
│ SHA-256(abgeleiteter Schluessel) → Hash fuer Verifikation │
│ │ │
│ │ → Server speichert nur diesen Hash │
│ │ → Damit kann geprueft werden ob die Passphrase stimmt │
│ │ → Vom Hash kann der Schluessel NICHT zurueckberechnet │
│ │ werden │
│ ▼ │
│ 5. Upload: Nur diese Daten gehen an den Cloud-Server: │
│ • Verschluesselter Blob (unlesbar ohne Schluessel) │
│ • Salt (zufaellige Bytes, harmlos) │
│ • IV (Initialisierungsvektor, harmlos) │
│ • Schluessel-Hash (zur Verifikation, nicht umkehrbar) │
│ │
│ Was NICHT an den Server geht: │
│ ✗ Passphrase │
│ ✗ Abgeleiteter Schluessel │
│ ✗ Unverschluesselter 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>
{/* ============================================================ */}
{/* 7. NAMESPACE / TENANT-ISOLATION */}
{/* ============================================================ */}
<h2 id="namespace">7. Namespace-Isolation: Jeder Kunde hat seinen eigenen Bereich</h2>
<p>
Ein <strong>Namespace</strong> (auch &ldquo;Tenant&rdquo; genannt) ist ein vollstaendig
abgeschotteter Bereich im System. Man kann es sich wie <strong>separate Tresorraeume
in einer Bank</strong> vorstellen: Jeder Kunde hat seinen eigenen Raum, und kein Schluessel
passt in einen anderen.
</p>
<h3>7.1 Wie die Isolation funktioniert</h3>
<p>
Jeder Kunde erhaelt eine eindeutige <code>tenant_id</code>. Diese ID wird
bei <strong>jeder einzelnen Datenbankabfrage</strong> als Pflichtfilter verwendet:
</p>
<CodeBlock language="text" filename="Tenant-Isolation in der Vektordatenbank (Qdrant)">
{`Kunde A (tenant_id: "firma-alpha-001")
├── Dokument 1 (verschluesselt)
├── Dokument 2 (verschluesselt)
└── Referenz: Pruefkriterien 2025
Kunde B (tenant_id: "firma-beta-002")
├── Dokument 1 (verschluesselt)
└── Referenz: Compliance-Vorgaben 2025
Suchanfrage von Kunde A:
"Welche Klauseln weichen von den Referenzkriterien ab?"
→ 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")
]
Es gibt KEINE Abfrage ohne tenant_id-Filter.`}
</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: <code>/tenant-id/doc-id/encrypted.bin</code></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 und <strong>niemals zum Trainieren</strong> eines KI-Modells
eingesetzt.
</InfoBox>
{/* ============================================================ */}
{/* 8. RAG-PIPELINE */}
{/* ============================================================ */}
<h2 id="rag-pipeline">8. RAG-Pipeline: KI-Verarbeitung mit Kundenkontext</h2>
<p>
Die KI nutzt die vom Kunden hochgeladenen Referenzdokumente als Wissensbasis.
Dieser Prozess heisst <strong>RAG (Retrieval Augmented Generation)</strong>:
Die KI &ldquo;liest&rdquo; zuerst die relevanten Referenzen und generiert dann
kontextbezogene Ergebnisse.
</p>
<h3>8.1 Indexierung der Referenzdokumente</h3>
<CodeBlock language="text" filename="Indexierung: Vom Upload zum durchsuchbaren Referenzdokument">
{`Referenzdokument (verschluesselt auf Server)
|
v
┌────────────────────────────────────┐
│ 1. Passphrase-Verifikation │ ← SDK sendet Schluessel-Hash
│ Hash pruefen │ Server vergleicht mit gespeichertem Hash
└──────────┬─────────────────────────┘
|
v
┌────────────────────────────────────┐
│ 2. Entschluesselung │ ← Temporaer im Arbeitsspeicher
│ AES-256-GCM Decrypt │ (wird nach Verarbeitung geloescht)
└──────────┬─────────────────────────┘
|
v
┌────────────────────────────────────┐
│ 3. Text-Extraktion │ ← PDF → Klartext
│ Tabellen, Listen, Absaetze │
└──────────┬─────────────────────────┘
|
v
┌────────────────────────────────────┐
│ 4. Chunking │ ← Text in ~1.000-Zeichen-Abschnitte
│ Ueberlappung: 200 Zeichen │ (mit Ueberlappung fuer Kontexterhalt)
└──────────┬─────────────────────────┘
|
v
┌────────────────────────────────────┐
│ 5. Embedding │ ← Jeder Abschnitt wird in einen
│ Text → 1.536 Zahlen │ Bedeutungsvektor umgewandelt
└──────────┬─────────────────────────┘
|
v
┌────────────────────────────────────┐
│ 6. Re-Encryption │ ← Jeder Chunk wird ERNEUT verschluesselt
│ AES-256-GCM pro Chunk │ bevor er gespeichert wird
└──────────┬─────────────────────────┘
|
v
┌────────────────────────────────────┐
│ 7. Qdrant-Indexierung │ ← Vektor + verschluesselter Chunk
│ tenant_id: "firma-alpha-001" │ werden mit Tenant-Filter gespeichert
│ training_allowed: false │
└────────────────────────────────────┘`}
</CodeBlock>
<h3>8.2 Wie die KI eine Anfrage bearbeitet (RAG-Query)</h3>
<ol>
<li>
<strong>Anfrage formulieren:</strong> Das SDK sendet eine Suchanfrage mit dem
zu verarbeitenden Dokument und den gewuenschten Kriterien.
</li>
<li>
<strong>Semantische Suche:</strong> Die Anfrage wird in einen Vektor umgewandelt und
gegen die Referenz-Vektoren in Qdrant gesucht -- <em>nur im Namespace des Kunden</em>.
</li>
<li>
<strong>Entschluesselung:</strong> Die gefundenen Chunks werden mit der Passphrase
des Kunden entschluesselt.
</li>
<li>
<strong>KI-Antwort:</strong> Die entschluesselten Referenzpassagen werden als Kontext
an die KI uebergeben, die daraus ein Ergebnis generiert.
</li>
</ol>
{/* ============================================================ */}
{/* 9. KEY SHARING */}
{/* ============================================================ */}
<h2 id="key-sharing">9. Key Sharing: Zusammenarbeit ermoeglichen</h2>
<p>
In vielen Geschaeftsprozessen muessen mehrere Personen oder Abteilungen auf die gleichen
Daten zugreifen -- z.B. fuer Vier-Augen-Prinzip, Qualitaetskontrolle oder externe Audits.
Das Key-Sharing-System ermoeglicht es dem Eigentuemer, seinen Namespace sicher mit
anderen zu teilen.
</p>
<h3>9.1 Einladungs-Workflow</h3>
<CodeBlock language="text" filename="Key Sharing: Sicheres Teilen zwischen Bearbeitern">
{`Eigentuemer Server Eingeladener
│ │ │
│ 1. Einladung senden │ │
│ (E-Mail + Rolle + Scope) │ │
│─────────────────────────────────▶ │
│ │ │
│ │ 2. Einladung erstellt │
│ │ (14 Tage gueltig) │
│ │ │
│ │ 3. Benachrichtigung ──────▶│
│ │ │
│ │ 4. Einladung annehmen
│ │◀─────────────────────────────│
│ │ │
│ │ 5. Key-Share erstellt │
│ │ (verschluesselte │
│ │ Passphrase) │
│ │ │
│ │ 6. Eingeladener kann ──────▶│
│ │ jetzt Daten im │
│ │ Namespace abfragen │
│ │ │
│ 7. Zugriff widerrufen │ │
│ (jederzeit moeglich) │ │
│─────────────────────────────────▶ │
│ │ Share deaktiviert │`}
</CodeBlock>
<h3>9.2 Rollen beim Key-Sharing</h3>
<div className="not-prose my-4 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">Rolle</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Typischer Nutzer</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Rechte</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr><td className="px-4 py-3 font-medium">Owner</td><td className="px-4 py-3">Projektverantwortlicher</td><td className="px-4 py-3">Vollzugriff, kann teilen &amp; widerrufen</td></tr>
<tr><td className="px-4 py-3 font-medium">Reviewer</td><td className="px-4 py-3">Qualitaetssicherung</td><td className="px-4 py-3">Lesen, RAG-Queries, eigene Anmerkungen</td></tr>
<tr><td className="px-4 py-3 font-medium">Auditor</td><td className="px-4 py-3">Externer Pruefer</td><td className="px-4 py-3">Nur Lesen (Aufsichtsfunktion)</td></tr>
</tbody>
</table>
</div>
{/* ============================================================ */}
{/* 10. AUDIT-TRAIL */}
{/* ============================================================ */}
<h2 id="audit">10. Audit-Trail: Vollstaendige Nachvollziehbarkeit</h2>
<p>
Jede Aktion im Namespace wird revisionssicher im <strong>Audit-Log</strong> gespeichert.
Das ist essenziell fuer Compliance-Anforderungen und externe Audits.
</p>
<div className="not-prose my-4 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">Event</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Was protokolliert wird</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr><td className="px-4 py-3 font-medium">upload</td><td className="px-4 py-3">Dokument hochgeladen (Dateigroesse, Metadaten, Zeitstempel)</td></tr>
<tr><td className="px-4 py-3 font-medium">index</td><td className="px-4 py-3">Referenzdokument indexiert (Anzahl Chunks, Dauer)</td></tr>
<tr><td className="px-4 py-3 font-medium">rag_query</td><td className="px-4 py-3">RAG-Suchanfrage ausgefuehrt (Query-Hash, Anzahl Ergebnisse)</td></tr>
<tr><td className="px-4 py-3 font-medium">analyze</td><td className="px-4 py-3">KI-Verarbeitung gestartet (Dokument-Token, Modell, Dauer)</td></tr>
<tr><td className="px-4 py-3 font-medium">share</td><td className="px-4 py-3">Namespace mit anderem Nutzer geteilt (Empfaenger, Rolle)</td></tr>
<tr><td className="px-4 py-3 font-medium">revoke_share</td><td className="px-4 py-3">Zugriff widerrufen (wer, wann)</td></tr>
<tr><td className="px-4 py-3 font-medium">decrypt</td><td className="px-4 py-3">Ergebnis entschluesselt (durch wen, Zeitstempel)</td></tr>
<tr><td className="px-4 py-3 font-medium">delete</td><td className="px-4 py-3">Dokument geloescht (Soft Delete, bleibt in Logs)</td></tr>
</tbody>
</table>
</div>
{/* ============================================================ */}
{/* 11. API-ENDPUNKTE */}
{/* ============================================================ */}
<h2 id="api">11. API-Endpunkte (SDK-Referenz)</h2>
<p>
Die folgenden Endpunkte sind ueber das SDK oder direkt via REST ansprechbar.
Authentifizierung erfolgt ueber API-Key + JWT-Token.
</p>
<h3>11.1 Namespace-Verwaltung</h3>
<div className="not-prose my-4 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">Methode</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Endpunkt</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Beschreibung</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/upload</td><td className="px-4 py-3">Verschluesseltes Dokument hochladen</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/documents</td><td className="px-4 py-3">Eigene Dokumente auflisten</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/documents/{'{id}'}</td><td className="px-4 py-3">Einzelnes Dokument abrufen</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-red-100 text-red-800 text-xs font-bold">DELETE</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/documents/{'{id}'}</td><td className="px-4 py-3">Dokument loeschen (Soft Delete)</td></tr>
</tbody>
</table>
</div>
<h3>11.2 Referenzdokumente &amp; RAG</h3>
<div className="not-prose my-4 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">Methode</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Endpunkt</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Beschreibung</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/references/upload</td><td className="px-4 py-3">Referenzdokument hochladen</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/references/{'{id}'}/index</td><td className="px-4 py-3">Referenz fuer RAG indexieren</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/rag-query</td><td className="px-4 py-3">RAG-Suchanfrage ausfuehren</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/analyze</td><td className="px-4 py-3">KI-Verarbeitung anstossen</td></tr>
</tbody>
</table>
</div>
<h3>11.3 Key Sharing</h3>
<div className="not-prose my-4 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">Methode</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Endpunkt</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Beschreibung</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-blue-100 text-blue-800 text-xs font-bold">POST</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/share</td><td className="px-4 py-3">Namespace mit anderem Nutzer teilen</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/shares</td><td className="px-4 py-3">Aktive Shares auflisten</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-red-100 text-red-800 text-xs font-bold">DELETE</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/shares/{'{shareId}'}</td><td className="px-4 py-3">Zugriff widerrufen</td></tr>
<tr><td className="px-4 py-3"><span className="px-2 py-0.5 rounded bg-green-100 text-green-800 text-xs font-bold">GET</span></td><td className="px-4 py-3 font-mono text-sm">/api/v1/namespace/shared-with-me</td><td className="px-4 py-3">Mit mir geteilte Namespaces</td></tr>
</tbody>
</table>
</div>
{/* ============================================================ */}
{/* 12. ZUSAMMENFASSUNG */}
{/* ============================================================ */}
<h2 id="zusammenfassung">12. Zusammenfassung: Compliance-Garantien</h2>
<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">Garantie</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Wie umgesetzt</th>
<th className="px-4 py-3 text-left font-medium text-gray-500">Regelwerk</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
<tr>
<td className="px-4 py-3 font-medium">Keine PII verlaesst das Kundensystem</td>
<td className="px-4 py-3">Header-Redaction + verschluesselte Identity-Map</td>
<td className="px-4 py-3">DSGVO Art. 4 Nr. 5</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Betreiber kann nicht mitlesen</td>
<td className="px-4 py-3">Client-seitige AES-256-GCM Verschluesselung</td>
<td className="px-4 py-3">DSGVO Art. 32</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Kein Zugriff durch andere Kunden</td>
<td className="px-4 py-3">Tenant-Isolation (Namespace) auf allen 3 Ebenen</td>
<td className="px-4 py-3">DSGVO Art. 25</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Kein KI-Training mit Kundendaten</td>
<td className="px-4 py-3"><code>training_allowed: false</code> auf allen Vektoren</td>
<td className="px-4 py-3">AI Act Art. 10</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Alles nachvollziehbar</td>
<td className="px-4 py-3">Vollstaendiger Audit-Trail aller Aktionen</td>
<td className="px-4 py-3">DSGVO Art. 5 Abs. 2</td>
</tr>
<tr>
<td className="px-4 py-3 font-medium">Kunde behaelt volle Kontrolle</td>
<td className="px-4 py-3">Jederzeitiger Widerruf, Loeschung, Datenexport</td>
<td className="px-4 py-3">DSGVO Art. 17, 20</td>
</tr>
</tbody>
</table>
</div>
<InfoBox type="success" title="Das Wichtigste in einem Satz">
Die Namespace-Technologie ermoeglicht KI-gestuetzte Datenverarbeitung in der Cloud, bei der
<strong> keine personenbezogenen Daten das Kundensystem verlassen</strong>, alle Daten
<strong> Ende-zu-Ende verschluesselt</strong> sind, jeder Kunde seinen
<strong> eigenen abgeschotteten Namespace</strong> hat, und ein
<strong> vollstaendiger Audit-Trail</strong> jede Aktion dokumentiert.
</InfoBox>
</DevPortalLayout>
)
}