Ein HTTPS-Proxy-Server, der Secrets in LLM-Kommunikation erkennt, maskiert und nach der Antwort wieder einsetzt. Entwickelt fΓΌr die sichere Nutzung von LLM-Tools wie GitHub Copilot, ohne dass sensible Daten an Cloud-Provider ΓΌbertragen werden.
- Man-in-the-Middle Proxy mit eigener Self-Signed CA fΓΌr TLS-Interception
- Modulare Secret-Erkennung durch Plugin-Architektur (Entropie-basiert, Bitwarden, erweiterbar)
- Automatische Protokoll-Erkennung fΓΌr verschiedene LLM-APIs (OpenAI, Anthropic, etc.)
- Streaming-UnterstΓΌtzung mit intelligentem Read-Ahead Buffer
- Skalierbar durch In-Memory oder Redis-basierte Mapping-Speicherung
- Monitoring via Prometheus-Metriken-Endpunkt
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LLM Secret Interceptor β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββ HTTPS βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β ββββββββββββββΊ β PROXY SERVER β
β Client β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β (VSCode) β β β TLS Interception Layer β β
β β ββββββββββββββ β β (Self-Signed CA / MITM) β β
ββββββββββββ HTTPS β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Protocol Auto-Detection β β
β β (OpenAI Format, Anthropic Format, ...) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Standardized Internal Format β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Secret Interceptor Manager β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β β β Entropy β β Bitwarden β β Custom β β β
β β β Interceptor β β Interceptor β β Interceptor β β β
β β βββββββββββββββ βββββββββββββββ βββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Secret Replacer β β
β β "password123" β "__SECRET_a1b2c3d4__" β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Mapping Store (TTL-based) β β
β β [In-Memory Map] or [Redis] β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ HTTPS
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LLM Cloud Provider β
β (OpenAI, GitHub Copilot, etc.) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β REQUEST FLOW β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Client Request Proxy Processing To LLM
β β β
β "Fix bug with β β
β password: abc123" β β
β β β
βΌ βΌ βΌ
βββββββββββ βββββββββββββββ βββββββββββββ βββββββββββββββ βββββββ
β Client βββββΊβ TLS Decrypt βββββΊβ Detect βββββΊβ Replace βββββΊβ LLM β
β Request β β & Parse β β Secrets β β Secrets β β API β
βββββββββββ βββββββββββββββ βββββββββββββ βββββββββββββββ βββββββ
β β
βΌ βΌ
βββββββββββββ βββββββββββββ
β "abc123" β β Store β
β flagged β β Mapping β
βββββββββββββ βββββββββββββ
Sent to LLM: "Fix bug with password: __SECRET_a1b2c3d4__"
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RESPONSE FLOW β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
From LLM Proxy Processing To Client
β β β
β "Change __SECRET_a1b2c3d4__ β β
β to a stronger password" β β
β β β
βΌ βΌ βΌ
βββββββββββ βββββββββββββββ βββββββββββββ βββββββββββββββ ββββββββββ
β LLM βββββΊβ Read-Ahead βββββΊβ Lookup βββββΊβ Replace βββββΊβ Client β
β Stream β β Buffer β β Mapping β β Placeholder β β β
βββββββββββ βββββββββββββββ βββββββββββββ βββββββββββββββ ββββββββββ
β
βΌ
βββββββββββββ
β Buffer N β
β chars for β
β streaming β
βββββββββββββ
Sent to Client: "Change abc123 to a stronger password"
Der einfachste Weg, den Proxy zu starten:
# Repository klonen
git clone https://github.com/hfi/llm-secret-interceptor.git
cd llm-secret-interceptor
# Konfiguration anpassen (optional)
cp configs/config.example.yaml configs/config.yaml
# Starten mit Docker Compose
docker compose up -d
# Logs anzeigen
docker compose logs -f proxyDer Proxy ist nun erreichbar unter:
- Proxy:
http://localhost:8080 - Metrics/Health:
http://localhost:9090
# Image bauen
docker build -t llm-secret-interceptor:latest .
# Container starten
docker run -d \
--name llm-proxy \
-p 8080:8080 \
-p 9090:9090 \
-v $(pwd)/certs:/app/certs \
-v $(pwd)/configs/config.yaml:/app/configs/config.yaml:ro \
llm-secret-interceptor:latestInstall using Helm chart:
# Add the Helm repository
helm repo add llm-secret-interceptor https://hfi.github.io/llm-secret-interceptor/
helm repo update
# Install with default values
helm install llm-proxy llm-secret-interceptor/llm-secret-interceptor
# Or install with custom values
helm install llm-proxy llm-secret-interceptor/llm-secret-interceptor \
--set config.logging.level=debug \
--set config.interceptors.entropy.threshold=4.0With existing TLS CA secret:
# Create secret with your CA certificate
kubectl create secret generic llm-proxy-ca \
--from-file=ca.crt=./certs/ca.crt \
--from-file=ca.key=./certs/ca.key
# Install with existing secret
helm install llm-proxy llm-secret-interceptor/llm-secret-interceptor \
--set tls.existingSecret=llm-proxy-caWith inline CA certificate:
helm install llm-proxy llm-secret-interceptor/llm-secret-interceptor \
--set-file tls.caCert=./certs/ca.crt \
--set-file tls.caKey=./certs/ca.keyFull configuration example (values.yaml):
replicaCount: 2
config:
storage:
type: "redis"
interceptors:
entropy:
enabled: true
threshold: 4.5
bitwarden:
enabled: true
server_url: "https://vault.bitwarden.com"
logging:
level: "info"
redis:
external:
host: "redis.default.svc.cluster.local"
port: 6379
extraEnv:
- name: BITWARDEN_EMAIL
valueFrom:
secretKeyRef:
name: bitwarden-credentials
key: email
- name: BITWARDEN_PASSWORD
valueFrom:
secretKeyRef:
name: bitwarden-credentials
key: password
tls:
existingSecret: "llm-proxy-ca"
metrics:
serviceMonitor:
enabled: true
ingress:
enabled: true
className: "nginx"
hosts:
- host: llm-proxy.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: llm-proxy-tls
hosts:
- llm-proxy.example.comhelm install llm-proxy llm-secret-interceptor/llm-secret-interceptor -f values.yaml# Repository klonen
git clone https://github.com/hfi/llm-secret-interceptor.git
cd llm-secret-interceptor
# Binary bauen
make build
# CA-Zertifikat generieren
make generate-ca
# Proxy starten
./bin/llm-secret-interceptorBeim ersten Start wird automatisch ein CA-Zertifikat generiert. Manuell:
# Γber das Binary
./bin/llm-secret-interceptor generate-ca [cert-path] [key-path]
# Γber Make
make generate-caDie Konfiguration erfolgt ΓΌber eine YAML-Datei:
# config.yaml
proxy:
listen: ":8080"
tls:
ca_cert: "/app/certs/ca.crt"
ca_key: "/app/certs/ca.key"
storage:
# "memory" fΓΌr Single-Instance, "redis" fΓΌr Multi-Instance
type: "memory"
redis:
address: "localhost:6379"
password: ""
db: 0
ttl: "24h" # Mappings werden nach 24h InaktivitΓ€t gelΓΆscht
placeholder:
prefix: "__SECRET_"
suffix: "__"
interceptors:
entropy:
enabled: true
threshold: 4.5 # Shannon-Entropie Schwellenwert
min_length: 8
bitwarden:
enabled: false
server_url: "https://vault.bitwarden.com"
# Credentials via Environment-Variablen
logging:
level: "info" # debug, info, warn, error
audit:
enabled: true
log_interceptor_name: true
log_secret_type: true
# Secrets selbst werden NIEMALS geloggt!
metrics:
enabled: true
endpoint: "/metrics"
port: 9090-
CA-Zertifikat installieren:
# macOS sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ./certs/ca.crt # Linux sudo cp ./certs/ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates
-
Proxy in VSCode konfigurieren (settings.json):
{ "http.proxy": "https://localhost:8080", "http.proxyStrictSSL": true }
Der Proxy stellt folgende Metriken unter /metrics bereit:
llm_proxy_requests_totalβ Gesamtanzahl verarbeiteter Requestsllm_proxy_secrets_detected_totalβ Anzahl erkannter Secrets (nach Interceptor)llm_proxy_secrets_replaced_totalβ Anzahl ersetzter Secretsllm_proxy_mapping_store_sizeβ Aktuelle GrΓΆΓe des Mapping-Storesllm_proxy_request_duration_secondsβ Request-Latenz
Eigene Interceptors kΓΆnnen implementiert werden:
type SecretInterceptor interface {
// Name returns the interceptor name for logging/metrics
Name() string
// Detect analyzes text and returns found secrets
Detect(text string) []DetectedSecret
// Configure applies configuration from YAML
Configure(config map[string]interface{}) error
}
type DetectedSecret struct {
Value string
StartIndex int
EndIndex int
Type string // z.B. "password", "api_key", "token"
Confidence float64 // 0.0 - 1.0
}- Sprache: Go
- TLS: crypto/tls mit dynamischer Zertifikatsgenerierung
- HTTP Proxy: goproxy oder eigene Implementierung
- Konfiguration: gopkg.in/yaml.v3
- Metriken: prometheus/client_golang
- Redis: go-redis/redis
Apache 2.0 License