Saklam Bridge — Customer Setup Guide
Drop-in LLM-Proxy mit automatischer PII-Maskierung. On-Premises in eurer Infra, Zero-Knowledge gegenüber Saklam, §203-konform.
Diese Anleitung führt euch durch Installation und Inbetriebnahme des Saklam-Bridge-Containers im eigenen Netz.
Architektur in einem Bild
Kanzlei-Workstations / Server
Claude Code · Cursor · Eigenanwendungen
│
│ ANTHROPIC_BASE_URL=http://bridge.intern.kanzlei.de
│ ANTHROPIC_API_KEY=sk-bridge-<euer-master-key>
▼
┌─ Saklam Bridge (Docker im Kunden-Netz) ─────────────────────────┐
│ 1. Eingehender Request mit Mandanten-Klartext │
│ 2. PII-Maskierung (453 Patterns, EU-27, 22 Sprachen) │
│ 3. Forward an Anthropic/OpenAI/Mistral mit eurem API-Key (BYOK) │
│ 4. Response demaskieren │
└──────────────────────────────────────────────────────────────────┘
│
│ Maskierte Tokens, Customer-API-Key
▼
Anthropic / OpenAI / Mistral
Was Saklam sieht: nichts. Saklam-Server hat keine Verbindung zu eurem Container. Was der LLM-Provider sieht: maskierte Tokens, niemals Klartext.
Voraussetzungen
| Komponente | Detail |
|---|---|
| Host-OS | Linux x86_64 oder ARM64 (Container ist multi-arch). Windows/macOS via Docker Desktop. |
| Docker | Docker Engine ≥ 24 oder Docker Desktop ≥ 4.30 mit docker compose v2 Plugin |
| CPU/RAM | 2 vCPU + 4 GB RAM minimum, 4 vCPU + 8 GB empfohlen für Multi-User |
| Storage | ~3 GB für Image + Modelle (GLiNER 197 MB, spaCy-DE ~50 MB) |
| Netzwerk | Outbound HTTPS zu api.anthropic.com (bzw. eurem gewählten Provider) |
| API-Key | Pay-as-you-go API-Key beim LLM-Provider — nicht Max/Pro/Team-Subscription-OAuth (siehe Auth-Note unten) |
Quick-Install (5 Minuten)
# 1. Verzeichnis anlegen
mkdir -p /opt/saklam-bridge && cd /opt/saklam-bridge
# 2. docker-compose.yml + .env.example herunterladen
curl -fsSL https://saklam.com/bridge/docker-compose.yml -o docker-compose.yml
curl -fsSL https://saklam.com/bridge/env.example -o .env.example
# 3. .env vorbereiten
cp .env.example .env
$EDITOR .env
# - ANTHROPIC_API_KEY=sk-ant-api03-… (Pay-as-you-go-Key)
# - BRIDGE_MASTER_KEY=$(openssl rand -hex 32) (optional, siehe Auth-Modi unten)
# 4. Start
docker compose pull
docker compose up -d
# 5. Smoke-Test
sleep 5
curl -fsS http://localhost:4000/health/readiness
Auth-Modi (Master-Key)
| Setup | Konfiguration | Wann |
|---|---|---|
| Single-User auf Laptop (Anwalt nutzt Bridge nur lokal) | BRIDGE_BIND_ADDR=127.0.0.1, BRIDGE_MASTER_KEY= (leer) |
Solo-Pilot, Dogfooding. Bridge akzeptiert beliebigen x-api-key. Sicher weil nur Host-Prozesse zugreifen können. |
| Multi-User-Server (zentraler Bridge für ganze Kanzlei) | BRIDGE_BIND_ADDR=0.0.0.0, BRIDGE_MASTER_KEY=<openssl rand -hex 32>, TLS-Reverse-Proxy davor |
Production-Deployment. Master-Key + TLS sind beide zwingend. |
Erwartete Antwort: {"status":"connected"} (HTTP 200).
Tool-Integration
Claude Code (CLI)
export ANTHROPIC_BASE_URL=http://localhost:4000
export ANTHROPIC_API_KEY=<euer BRIDGE_MASTER_KEY aus .env>
claude
In der gestarteten Claude-Session beliebigen Prompt mit Klartext-PII testen:
> "Schreibe ein Mahnschreiben an Max Mustermann, Musterstr. 12, 80331 München, Forderung 1.245,50 €."
Die Bridge maskiert Max Mustermann → [PER_a1b2c3d4], Musterstr. 12, 80331 München → [LOC_…], sendet die maskierte Version an Anthropic und demaskiert die Antwort vor der Rückgabe.
Cursor
Cursor Settings → Models → API Keys:
- Anthropic API Key:
<BRIDGE_MASTER_KEY> - Anthropic Base URL:
http://localhost:4000(oderhttp://bridge.intern.kanzlei.de)
Eigene Skripte (Python anthropic SDK)
from anthropic import Anthropic
client = Anthropic(
base_url="http://localhost:4000",
api_key="<BRIDGE_MASTER_KEY>",
)
resp = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Mandant: Müller, Vorgang 2025/4711, Streitwert 18k €."}]
)
LAN-Erreichbarkeit für Mitarbeiter-Workstations
Default bindet die Bridge auf 127.0.0.1:4000. Für netzweiten Zugriff:
- In
.env:BRIDGE_BIND_ADDR=0.0.0.0 - Reverse-Proxy (nginx/Caddy/Traefik) mit TLS davor — niemals plain HTTP über LAN, weil Klartext-PII zwischen Workstation und Bridge fließt.
docker compose up -dneu starten.
Updates
cd /opt/saklam-bridge
docker compose pull
docker compose up -d
Wir empfehlen ein Wartungsfenster wöchentlich oder nach Saklam-Release-Notes. Patch-Releases sind kompatibel; Major-Versionen werden im Release-Channel angekündigt.
Auth-Note (wichtig vor Setup)
Saklam Bridge funktioniert ausschließlich mit klassischen API-Keys (pay-as-you-go), nicht mit Subscription-OAuth.
Funktioniert nicht:
- Anthropic Max / Pro / Team OAuth-Subscription-Tokens
- ChatGPT Plus / Team Web-Sessions
Unterstützte Provider (alle BYOK = Bring Your Own Key, Saklam tritt nicht als Reseller auf):
| Provider | Wann sinnvoll | Wo holen |
|---|---|---|
| Anthropic (direkt) | Frontier-Modelle (Claude Sonnet/Opus/Haiku) | console.anthropic.com → API Keys |
| OpenAI (direkt) | GPT-Modelle | platform.openai.com → API Keys |
| Azure OpenAI | Wenn M365-Enterprise-Vertrag vorhanden — gleiche GPT-Modelle mit EU-Data-Residency + Microsoft-DPA | Azure Portal → AI Services → Azure OpenAI |
| Google Gemini (Vertex AI) | Gemini-Familie, EU-Region Frankfurt verfügbar | aistudio.google.com oder Vertex AI |
| AWS Bedrock | Wenn AWS-Vertrag vorhanden — Claude / Llama / Mistral durch eine API mit AWS-DPA, EU-Frankfurt (eu-central-1) |
AWS IAM → Access Key + Bedrock Model Access |
| Mistral (direkt) | EU-Provider La Plateforme | console.mistral.ai |
| Self-hosted | Eigenes Inference-Cluster (Ollama / vLLM / TGI) — maximaler Zero-K | OLLAMA_API_BASE=http://ollama.intern:11434/v1 |
Customer wählt einen oder mehrere Provider und trägt die entsprechenden Env-Variablen in .env ein. Nur ANTHROPIC_API_KEY ist pflicht (Default-Provider beim ersten Start) — alle anderen optional. Config-Routing erfolgt automatisch über Modellname-Präfix:
claude-*→ Anthropicgpt-*/openai/*→ OpenAI (direkt)azure/*→ Azure OpenAIgemini/*→ Google Geminibedrock/*→ AWS Bedrockmistral/*→ Mistralollama/*→ Self-hosted
FAQ
Wird das LLM durch die [XXX_yyyyyyyy]-Platzhalter verwirrt oder verweigert es die Antwort?
Nein. Die Bridge injiziert automatisch eine System-Instruktion in jeden Request (wire-bewusst für Anthropic- und OpenAI-Format), die dem LLM erklärt: Tokens im Format [PER_a1b2c3d4], [EMA_…], [TEL_…] etc. sind maskierte personenbezogene Daten — exakt übernehmen, nicht verändern, nicht erfinden, und „wie die echten Daten" behandeln.
Für normale Aufgaben (Zusammenfassen, Schriftsätze, E-Mail-Entwürfe, Analysen) bleibt die Output-Qualität damit voll erhalten — der Platzhalter steht semantisch an Stelle der echten Person/IBAN/Adresse. In der Antwort werden die Platzhalter automatisch wieder demaskiert, bevor sie eure App/euren Client erreichen: Ihr seht die echten Werte, das LLM nie.
Grenzfall, der gewollt ist: Bei Aufgaben, die den exakten Originalwert eines maskierten Feldes brauchen — z.B. „prüfe die Prüfsumme dieser IBAN" oder „wie viele Ziffern hat diese Telefonnummer?" — merkt das LLM korrekt an, dass es nur einen Platzhalter sieht. Solche Format-/Validierungs-Prüfungen gehören auf eure Seite (vor oder nach der Bridge), nicht in die maskierte KI-Anfrage.
Praktischer Nebeneffekt für eigene Tests: Fragt ihr das LLM, ob ein maskiertes Feld „echt" ist, antwortet es mit „das ist ein Platzhalter" — ein direkter, sichtbarer Beleg, dass beim Provider nie Klartext ankommt.
Troubleshooting
unhealthy im docker ps
docker compose logs bridge
Typische Ursachen:
- Erste 60s nach Start: GLiNER lädt 197 MB Modell —
start_period: 60sim Healthcheck erlaubt das. Wenn nach 90s nochunhealthy: Logs prüfen. ANTHROPIC_API_KEYungültig → 401 von Anthropic → Bridge meldet keinen Fehler beim Start, aber jeder Request scheitert. Test:curl …/health/liveness(sollte 200 sein selbst ohne Anthropic).
401 Unauthorized bei Anthropic-Calls
Customer-API-Key ist ein Max/Team-OAuth-Token statt klassischem sk-ant-…-Key. Siehe Auth-Note oben.
Hohe Latenz erste Anfrage, dann schnell
Cold-Start: GLiNER lädt Modell beim ersten PII-haltigen Request. Anfragen 2+ sind <100ms.
PII wird nicht maskiert
Logs prüfen: docker compose logs bridge | grep -i 'mask'. Häufige Ursachen:
MASK_API_URList gesetzt, aber das Ziel ist nicht erreichbar → Variable in.enventfernen. Default ist in-process (kein externer Mask-Service, kein Netzwerk-Hop).- Prompt enthält nur Domain-spezifische Kürzel die nicht in den 453 Patterns sind → Custom-Patterns gibt's im Enterprise-Tier
"Disclosure": Bridge zwischenspeichert PII während Request-Verarbeitung
Ja, das ist architektonisch zwangsläufig (RAM-only, kein Disk-Persistence). Ein böswilliger Container-Admin könnte den Process inspizieren. Daher: Bridge gehört in eure Infra, nicht zu Saklam.
Logs & Datenschutz
- Default-Logging: strukturierte JSON-Logs (
json-file-Driver), rotiert nach 50 MB. - PII in Logs: Bridge loggt Request-Metadaten (Model, Token-Counts, Latenz), nicht Prompt-Klartext.
- Externes Log-Forwarding (Splunk, ELK, Loki): Standard-Docker-Logging-Mechanismen.
- Auditfähigkeit: Enterprise-Tier bringt Audit-Trail-Export (CSV) + tamper-evident Hashing — kommt mit Phase 2 (siehe Roadmap).
Pricing & Lizenz
| Tier | Pricing | Inhalt |
|---|---|---|
| Pilot | 30 Tage gratis, 1-3 Lighthouse-Kunden | unlimited Volume + Setup-Support direkt mit Stefan |
| Pro | €299 / MA / Jahr | Auto-Updates, Email-Support, AVV-PDF |
| Enterprise | €499 / MA / Jahr | + Priority-Support + Custom-Patterns + Audit-Trail-Export |
AVV (Auftragsverarbeitung): Saklam tritt nicht als Auftragsverarbeiter auf, weil Saklam keine personenbezogenen Daten empfängt. Stattdessen liefern wir eine Site-License-Vereinbarung + technisches Whitepaper für eure DSB-Dokumentation. Vorlage: docs/AVV_TEMPLATE.md.
Support
| Kanal | Detail |
|---|---|
| support@saklam.com | |
| Status-Page | https://status.saklam.com |
| Release-Notes | https://saklam.com/changelog |
Pilot-Kunden bekommen direkte Stefan-Erreichbarkeit (Signal/Email) während der ersten 30 Tage.
Verwandte Docs
- DOGFOODING.md — Local-Dev-Setup (für Saklam-interne Nutzung)
- AVV_TEMPLATE.md — Site-License + Vertragsvorlage
- SAKLAM_TOKEN_FORMAT.md — Token-Spec (
[PRE_8hex]) - SAKLAM_MASK_ROADMAP.md — Phase-2-Features