Die Sicherheitsschichten von Simmetric Chat: API-Schlüssel, signierte Webhooks und DLP
Wie Simmetric Chat jede Anfrage authentifiziert, API-Schlüssel mit HMAC-SHA256 hasht, Webhooks und Web Push signiert und personenbezogene Daten mit DLP-Filtern redigiert.
Sicherheit ist ein Stack, kein Schalter
Eine Chat-Plattform, die die Dokumente Ihres Unternehmens verwahrt, muss Vertrauen in Schichten verdienen: wie Anfragen sich authentifizieren, wie programmatischer Zugriff ausgegeben und aufbewahrt wird, wie Hintergrundintegrationen ihre Legitimität beweisen und was mit sensiblen Inhalten geschieht, während sie Prompts und Antworten durchlaufen. Simmetric Chat adressiert jeden dieser Aspekte mit einem benannten Mechanismus, und v0.22 hat einige der subtilsten Lücken geschlossen - timing-sichere Secret-Vergleiche, enumeration-resistenter Login und eine DLP-Engine, die nun auch strukturierte europäische Identifikatoren abdeckt. Dieser Artikel geht den Stack von der Eingangstür nach innen durch.
Drei Wege, wie Anfragen sich authentifizieren
Jeder Endpunkt unter /api fällt in eines von drei Credential-Regimen:
- JWT Bearer (primär). Menschliche Nutzer authentifizieren sich über den Login- oder Registrierungsendpunkt und erhalten ein signiertes JWT. Jedes Token trägt einen
jti-Claim, der gegen eine Widerrufsliste geprüft wird (optional auf Redis gestützt), damit Abmeldung oder administrativer Widerruf sofort wirken, nicht erst beim Ablauf. Ungültige oder abgelaufene Tokens erhalten ein sauberes401; die Middleware löst den Nutzer samt Rollen und Berechtigungen bei jeder Anfrage auf. - API-Schlüssel (`X-Api-Key`). Programmatischer Zugriff - die Servicekonto-Oberfläche des Widgets und die von Nutzern über die API-Key-Endpunkte erstellten Schlüssel - verwendet präfixierte Schlüssel, die gegen einen HMAC-Digest geprüft werden, unten beschrieben.
- Geteiltes Collector-Secret. Service-zu-Service-Aufrufe des Ingestion-Collectors tragen
X-Collector-Secret, timing-konstant mit einer Längenprüfung verglichen. Das war der letzte Ort, an dem ein Klartext-Secret-Vergleich auf dem Server überlebte, und v0.22 hat ihn geschlossen: Archiv-Import-Callbacks nutzen nun dieselbecrypto.timingSafeEqual-Disziplin wie jede andere Secret-Barriere.
Über der Authentifizierung liegen die RBAC-Guards, die in einem separaten Artikel behandelt werden - Berechtigungsprüfungen, Admin-Barrieren und IDOR-Prävention beim Zugriff auf Workspaces und Projekte. Authentifizierung beantwortet „wer sind Sie"; RBAC beantwortet „was dürfen Sie anfassen".
API-Schlüssel: HMAC-SHA256, at rest verschlüsselt
Ein API-Schlüssel ist ein Bearer-Credential, daher zählt die Art, wie der Server ihn aufbewahrt, genauso wie die Art, wie er ihn prüft. Simmetric Chat gibt Schlüssel mit einem erkennbaren sk--Präfix aus - vertraut für die Tool-Ökosysteme, die die meisten Entwickler ohnehin nutzen - und speichert den Schlüssel selbst nie. At rest existiert jeder Schlüssel nur als HMAC-SHA256-Digest, berechnet unter einem dedizierten serverseitigen Secret, API_KEY_HMAC_SECRET:
sk-abc123… (einmal ausgegeben, einmal dem Aufrufer gezeigt)
│ HMAC-SHA256(API_KEY_HMAC_SECRET, Schlüssel)
▼
key_hash in api_keys gespeichert - der Schlüssel selbst ist unwiederbringlichDas Design hat zwei gewollte Eigenschaften:
- Entkoppelte Rotation.
API_KEY_HMAC_SECRETist unabhängig vonJWT_SECRETundENCRYPTION_KEY. Das Rotieren des Session-Signaturschlüssels invalidiert keine API-Schlüssel, und das Rotieren des At-Rest-Verschlüsselungsschlüssels bricht die Schlüsselverifikation nicht. Jedes Secret hat genau eine Aufgabe. - Timing-konstante Verifikation. Die Prüfung ist eine gehashte HMAC-Digest-Suche - O(1), ohne
take-Limits auf einem Kandidaten-Scan. Das macht API-Key-Authentifizierung billig genug, um bei jeder Anfrage in einem Multi-Instanz-Deployment mitzulaufen.
Nutzer verwalten ihre eigenen Schlüssel über die API-Key-Endpunkte: Erstellung bei Bedarf, Auflistung auf Anfrage, Widerruf auf Anfrage. Der Widerruf entfernt die Fähigkeit, ein gültiges Credential zu rekonstruieren; der Digest passt zu nichts mehr.
Signierte Webhooks und Web Push
Ausgehende Integrationen müssen genauso verifizierbar sein wie eingehende.
Webhooks werden mit HMAC-SHA256 signiert. Der Server berechnet eine Signatur über das Payload mit dem Webhook-Secret, und Ihr empfangender Dienst berechnet den Digest neu, bevor er dem Ereigniskörper vertraut. Ein empfangender Endpunkt darf einem Aufrufer, der behauptet, Simmetric Chat zu sein, nie vertrauen - er kann es beweisen, Byte für Byte, mit seiner eigenen Kopie des Secrets. Ein Test-Event-Endpunkt lässt Sie einen Empfänger exercen, ohne echte Aktivität auf der Plattform zu erzeugen.
Web Push nutzt das VAPID-Protokoll für Browser-Benachrichtigungen. Der Server hält ein VAPID-Schlüsselpaar; der öffentliche Schlüssel wird authentifizierten Clients über einen Systemendpunkt exponiert, Abonnements werden über explizite Subscribe/Unsubscribe-Endpunkte verwaltet, und Administratoren können einen Test-Push senden, um die Pipeline end-to-end zu prüfen. Beide Kanäle sind auf Community-Stufe immer aktiv - Signierung und Push sind Basisverhalten der Plattform, keine Enterprise-Funktionen.
Rate Limiting an der Grenze
Rate Limiting ist nach Oberfläche geschichtet, mit den üblichen RateLimit-*-Headern auf limitierten Routen:
- Globaler API-Limiter - 200 Anfragen pro Minute pro IP auf allen Routen in der Produktion
- Authentifizierungs-Limiter - 10 Anfragen pro Minute auf den Schreibendpunkten der Authentifizierung, die engste Barriere, weil Credential-Endpunkte die ersten Ziele von Missbrauch sind
- Widget-Lead-Limiter - 3 Anfragen pro Stunde auf der Lead-Erfassung, weil ein öffentliches Formular dort ist, wo sich automatisierter Missbrauch konzentriert
- Probe-Limiter - 10 Anfragen pro Minute auf den Konnektivitätsprobe-Endpunkten, damit das Testen des Setup-Assistenten nicht zur Waffe gemacht werden kann
Wenn REDIS_URL konfiguriert ist, leben die Zähler in einem geteilten Redis-Store, damit Limits auf jeder Instanz dasselbe bedeuten; sonst hält jede Instanz ihren eigenen Store. Anfragen mit einem Widget-Header überspringen den globalen Limiter - Widget-Verkehr wird bereits vorgelagert durch den Per-Key-Limiter des Widget-Dienstes gedrosselt - und es gibt keinen dedizierten Chat-Limiter, weil der Agent intern Nebenläufigkeit pro Nutzer, Token-Budgets und Wall-Clock-Timeouts erzwingt.
DLP: Redaktion vor der Exfiltration
Data Loss Prevention in Simmetric Chat ist ein Filter-Plugin, das sowohl den eingehenden Prompt als auch die ausgehende Antwort scannt - einschließlich der progressiven Token-für-Token-Flushes des Streamings - und Treffer redigiert, bevor Inhalte Ihr Netzwerk verlassen. Der Scanner kennt 10 eingebaute PII-Pattern-Klassen:
- E-Mail-Adressen
- Kreditkartennummern
- API-Schlüssel und private Schlüssel
- Dazu die strukturierten europäischen Identifikatoren: italienische Partita IVA, codice fiscale und IBAN, in v0.22 hinzugefügt und idempotent ausgeliefert
Die Pattern-Konfiguration ist datenbankgestützt und admin-verwaltet: Aktivieren oder deaktivieren Sie jedes Pattern pro Zeile, fügen Sie bis zu 50 eigene Patterns mit Live-Compile-Validierung und Test-Vorschau hinzu, und inspizieren Sie ein DLP-Trefferhistorie-Panel, filterbar nach Quelle (Chat oder Widget). Die eingebauten regulären Ausdrücke sind eingefroren - Sie können ein eingebautes Pattern deaktivieren, aber nicht umschreiben -, während eigene Patterns Ihre Definitionen tragen. Scans, die konfigurierte Patterns lesen können, nutzen sie über einen kurzlebigen TTL-Cache und fallen auf das eingebaute Set zurück, wenn die Datenbank nicht erreichbar ist, damit ein Datenbankausfall die Redaktion nie deaktiviert.
Zwei Governance-Details runden das Bild ab. Eine Einstellung DLP_BYPASS_ROLES erlaubt Admins, bestimmte Rollen vom Scan auszunehmen, und jeder Bypass erzeugt ein Audit-Ereignis, das festhält, wer umgangen hat und auf welcher Oberfläche - nie den gescannten Inhalt. Administratoren können übereinstimmende Texte außerdem über eine Konversation mit einem einzigen Schalter aufdecken oder wieder verbergen, wobei die Sichtbarkeit auf die Sitzung beschränkt und standardmäßig verborgen ist, damit die Redaktion für eine autorisierte Prüfung umkehrbar bleibt, aber nicht still.
Die subtilste Härtung in v0.22
Kleine Änderungen zählen, weil sie die Kanäle schließen, die Angreifer tatsächlich sondieren:
- Timing-sichere Vergleiche überall. Jeder verbliebene Klartext-Secret-Vergleich - die Collector-Secret-Barrieren, der Archiv-Import-Callback, die Cache-Bust-Key-Prüfung des Widgets - nutzt nun
crypto.timingSafeEqualmit einer Längenprüfung und schlägt fail-closed fehl, wenn das erwartete Secret nicht gesetzt ist. - Enumeration-resistenter Login. Wenn ein Nutzername nicht existiert, führt der Login vor der Antwort trotzdem einen Dummy-Hash-Vergleich aus, damit die Antwortzeit existierende nicht mehr von nicht existierenden Nutzern unterscheidet. Ungültige Bodies liefern ein strukturiertes
400statt eines401, das Zod-Interna durchsickern ließe. - Fehlkonfigurationen, die laut fehlschlagen. Eine serverseitige HMAC-Fehlkonfiguration bei der API-Key-Prüfung liefert
500, per Wahl - ein falsch konfiguriertes Secret darf sich nie als Authentifizierungsfehler verkleiden. - Strukturierte Validierung. Request-Bodies werden mit geteilten Zod-Schemata über
safeParsevalidiert; jeder Fehler ist ein einheitlicher Umschlag mit Feld-Details, damit Clients vorhersehbar scheitern.
Die gesamte API-Oberfläche - Endpunkt-Tabellen, SSE-Ereignis-Rahmung und Auth-Anforderungen pro Route - ist in der API-Referenz dokumentiert, und eine Live-Swagger-Oberfläche ist im Server enthalten.
