Authentifizierung & Scopes
Die Platform API authentifiziert sich mit einem Schlüssel deiner Organisation. Es gibt ihn in zwei Formen — gleiche Organisation, gleiche Scopes, unterschiedliche Runtime:
| Form | Credential | Sent as |
|---|---|---|
| Server (backend) | kld_sk_live_… | Authorization: Bearer … oder X-Api-Key |
| Publishable (browser) | kld_pk_live_… | wird vom SDK gegen eine kurzlebige Session ausgetauscht; nie als Raw Bearer gesendet |
Authorization: Bearer kld_sk_live_…
# or
X-Api-Key: kld_sk_live_…
Server Keys sind der Bearer, den du von deinem Backend bei jeder Anfrage sendest.
Publishable Keys sind für den Browser: Das SDK tauscht sie zur Laufzeit gegen ein kurzlebiges,
Origin-gebundenes Session-Token aus, sodass der Publishable Key selbst niemals als
dauerhafte Zugangsinformation im Seitenquelltext steht. Ein Publishable Key, der direkt als
Bearer gesendet wird, wird abgelehnt — verwende ihn über das SDK. Ein Server Key erhält keine CORS-
Freigabe, sodass eine Seite eine damit erzeugte Response niemals lesen kann — CORS kann jedoch
nicht verhindern, dass die Anfrage den Browser verlässt. Ein Server Key im Seitenquelltext
ist daher bereits geleakt, bevor die API ihn ablehnt. Aus genau diesem Grund lehnt das SDK
kld_sk_…-Keys beim Mounten ab: Server Keys immer serverseitig halten.
Bestehende Legacy-Keys kld_live_… funktionieren weiterhin an beiden Stellen als Direct Bearer.
Scopes
Ein Schlüssel trägt Capability-Scopes; jede Route-Familie benötigt einen davon:
| Scope | Route family | Used by |
|---|---|---|
ai | /inference-api/b2b/v1/chat/*, /retrieval/* | chat embed |
design | /inference-api/b2b/v1/design/* | editor embed |
maps | designed basemaps | the tile embed |
vendor | (modifier, not a route) | the chat embed, on your own data |
Standardmäßig wird ein Pro-/Enterprise-Key mit ai, design und maps erstellt.
Free-Plan-Keys sind auf maps + das tile-Produkt beschränkt; siehe
API-Schlüssel erhalten für die maßgebliche
Plan × Scope × Produkt-Tabelle.
Effektive Zulassung = gespeicherter Schlüssel × aktueller Tier. Der Runtime-Session-Exchange
berechnet die Zulassung bei jedem Aufruf neu. Ein Pro-Tier-Key, der auf Free heruntergestuft wurde,
erstellt ab diesem Zeitpunkt nur noch Tile-Sessions — selbst wenn der gespeicherte Schlüssel weiterhin
ai und design in seinen Einschränkungen enthält. Der Rejection-Subcode
unterscheidet die beiden Fälle:
insufficient_scope— der Schlüssel hatte die Capability nie.tier_capability_not_allowed— der Schlüssel hatte sie, aber der aktuelle Tier lässt sie nicht mehr zu. Upgrade den Plan, um sie wiederherzustellen.
Ein leeres allowed_products im gespeicherten Schlüssel bedeutet alle Produkte (nicht
keine). Der Tier schränkt diese Obermenge weiterhin auf das ein, was der Plan zulässt.
vendor — bewusst anfordern, und nur dort, wo du ihn brauchst
vendor ist kein Route-Gate. Er lässt eine Anfrage weder zu noch lehnt er sie ab; er entscheidet,
ob der AI-Chat bei Antworten auf die hochgeladenen Vendor-Daten deiner Organisation zugreifen darf.
Jeder andere Scope beantwortet "darf dieser Schlüssel diesen Endpoint aufrufen"; vendor
beantwortet "darf dieser Schlüssel für unsere internen Daten sprechen".
Deshalb ist er niemals standardmäßig enthalten — fordere ihn beim Mint ausdrücklich an:
{ "name": "our-site-widget", "scopes": ["ai", "vendor"] }
Welcher Schlüssel vendor trägt, ist die gesamte Sicherheitsentscheidung. Das Chat-Embed ist ein
Browser-Widget: Es tauscht einen Publishable Key gegen eine kurzlebige Session aus, sodass ein
Vendor-fähiger Schlüssel zwangsläufig auf einer öffentlichen Seite liegt. Das ist für Daten in Ordnung,
die du jedem Besucher der Website zeigen möchtest — Objektlisten, Öffnungszeiten,
öffentliche Preise. Es ist nicht in Ordnung für Inhalte, die du nicht veröffentlichen würdest. Die Origin-
Allowlist, die den Exchange schützt, ist eine Browser-Konvention, keine Vertraulichkeitsgrenze:
Ein Aufrufer, der seinen eigenen Origin-Header setzt, wird dadurch nicht gestoppt.
Daher:
- Ein Schlüssel pro Oberfläche. Marketing-Website, Demo-Seite und kundenorientierte
App sollten keinen Schlüssel teilen. Nur die Oberfläche, die aus deinen Daten antworten muss, erhält
vendor. - Niemals Preislisten, Kostenbasis oder unveröffentlichte Informationen hinter einen Publishable Key legen. Wenn dich die Antwort auf einer öffentlichen Seite in Verlegenheit bringen würde, gehören die Daten nicht in ein Vendor-Scoped Embed.
- Sessions werden auf ihr Produkt eingeschränkt, daher trägt eine
tile- oderviewer-Session niemalsvendor, selbst wenn der Parent Key ihn besitzt.
Um ihn zu entziehen, bearbeite die Scopes des Schlüssels oder widerrufe ihn — beides wirkt ab der nächsten Anfrage, auch bei bereits laufenden Sessions. Der Entzug wird nicht bis zum Ablauf der Session verzögert.
401 vs. 403
Diese sind bewusst unterschiedlich:
- 401 Unauthorized — fehlender / ungültiger / widerrufener / abgelaufener Schlüssel. Prüfe
den Schlüsselwert und dass er nicht widerrufen wurde. Außerdem
publishable_requires_session, wenn ein Publishable Key als Raw Bearer gesendet wurde. - 403 Forbidden — der Schlüssel existiert, ist hier aber nicht zugelassen. Häufige
Subcodes:
insufficient_scope(nie vorhanden),tier_capability_not_allowed(war vorhanden, Tier lässt ihn nicht mehr zu),session_origin_mismatch,ip_not_allowed(Server Keys),server_key_in_browser,product_not_allowed.
Beide schlagen geschlossen fehl: Ein Schlüssel ohne Scopes wird überall abgelehnt.
Session-Tokens
Die Session, gegen die das SDK einen Publishable Key austauscht, sieht so aus:
kld_sess_{env}_{jwt}
zum Beispiel kld_sess_live_eyJhbGciOi…. Bei Runtime-Aufrufen wird sie als
Authorization: Bearer oder X-Api-Key gesendet. Standard-TTL 900 Sekunden (15
Minuten); das Server-Maximum beträgt 30 Minuten. Sessions werden auf das Produkt eingeschränkt,
für das sie erstellt wurden, und jede Anfrage liest die Live-Richtlinie des Parent Keys erneut.
Entzug ist sofort wirksam; eine neue Freigabe nicht. Die beiden Richtungen sind bewusst asymmetrisch und fail closed:
| Change to the parent key | Effect on a session already in flight |
|---|---|
| Revoked or deleted | Bei der nächsten Anfrage abgelehnt |
| A scope removed | Bei der nächsten Anfrage entfernt |
| Plan downgraded | Tier-gebundene Capabilities werden bei der nächsten Anfrage abgelehnt |
| Rate limit or monthly cap set to a new value | Gilt bei der nächsten Anfrage |
| A scope added, plan upgraded, or a limit lifted entirely | Nicht sichtbar — neue Session erstellen |
Eine Session kann gegenüber ihrem Parent nur eingeschränkt werden, niemals über die Scopes hinaus erweitert, mit denen sie erstellt wurde. Eine neue Freigabe erfordert daher einen neuen Exchange. Sessions sind bewusst kurz (Standard 15 Minuten), damit diese Lücke klein bleibt.
Siehe Errors für die vollständige Status-Tabelle.