- Published on
LiteLLM Keycloak: OIDC-SSO für das Gateway
- Authors

- Name
- Phillip Pham
- @ddppham
TL;DR
LiteLLM Keycloak ist die OIDC-Anbindung des Gateways an einen eigenen Identity-Provider. Zwei getrennte Wege, beide in der LiteLLM-Doku: die Admin-UI über Generic SSO (GENERIC_CLIENT_ID, Authorization-/Token-/UserInfo-Endpoint, Redirect /sso/callback, PROXY_BASE_URL mit Protokoll) und die API über JWT (enable_jwt_auth, JWKS unter /realms/{realm}/protocol/openid-connect/certs). SSO der Admin-UI ist laut LiteLLM ab v1.76.0 für bis zu fünf Nutzer frei, darüber Enterprise. JWT-Auth verlangt LITELLM_LICENSE. Gelesen in der LiteLLM- und Keycloak-Doku am 2026-10-16. Kein Anbieter-Ranking.
Gateway und IdP sind zwei Schichten
IT-Leiter suchen „litellm keycloak“, wenn das bereits laufende Gateway sich an das Firmenverzeichnis hängen soll — nicht, wenn sie LiteLLM nur als Provider-Proxy einordnen. Die Gateway-Übersicht bleibt LiteLLM: Provider hinter einer API. Keycloak als JWT-Schicht vor beliebigen LLM-Endpunkten, ohne LiteLLM-Config: LLM-API-Sicherheit Keycloak. Entra ID statt Keycloak: Entra-ID-SSO für Open WebUI, LiteLLM und n8n. Lokale Modelle hinter demselben Proxy: LiteLLM plus Ollama Routing.
LiteLLM behandelt Keycloak nicht als Sonderfall. Die JWT-Doku sagt: jeder Issuer funktioniert, der asymmetisch signiert, JWKS veröffentlicht, kid setzt und ein stabiles iss plus die konfigurierte Audience ausstellt. Keycloak erfüllt das über die Realm-Endpunkte.
Keycloak: Client und Endpunkte
In der Keycloak-Admin-Doku unter Clients → Create client:
- Client type OpenID Connect belassen.
- Eine Client-ID vergeben, speichern.
- Client authentication auf ON (confidential, Client-Secret).
- Standard Flow an (Authorization Code).
- Valid Redirect URIs exakt eintragen, keine Production-Wildcard
*.
Redirect für die LiteLLM-Admin-UI laut LiteLLM-SSO-Seite:
https://<ihr-proxy>/sso/callback
Beispiel der Doku für lokale Tests: http://localhost:4000/sso/callback. Zusätzlich /sso/debug/callback, wenn Sie Claims prüfen (ENABLE_SSO_DEBUG=true).
Keycloak veröffentlicht die OIDC-Pfade relativ zum Host, Realm-Name einsetzen:
/realms/{realm-name}/protocol/openid-connect/auth
/realms/{realm-name}/protocol/openid-connect/token
/realms/{realm-name}/protocol/openid-connect/userinfo
/realms/{realm-name}/protocol/openid-connect/certs
/realms/{realm-name}/protocol/openid-connect/logout
Discovery: https://<keycloak>/realms/<realm>/.well-known/openid-configuration. Issuer ist https://<keycloak>/realms/<realm> — Schrägstrich und http/https müssen bytegenau zum Token passen.
Das Secret steht im Tab Credentials. Die Keycloak-Doku: Lesen über die Admin-API braucht manage-clients; view-clients sieht nur einen Platzhalter.
Admin-UI: Generic SSO
LiteLLM hat keinen Keycloak-Schalter. Der Weg ist der Generic OAuth-Client. Pflichtvariablen der SSO-Doku:
GENERIC_CLIENT_ID="<client-id>"
GENERIC_CLIENT_SECRET="<client-secret>"
GENERIC_AUTHORIZATION_ENDPOINT="https://<keycloak>/realms/<realm>/protocol/openid-connect/auth"
GENERIC_TOKEN_ENDPOINT="https://<keycloak>/realms/<realm>/protocol/openid-connect/token"
GENERIC_USERINFO_ENDPOINT="https://<keycloak>/realms/<realm>/protocol/openid-connect/userinfo"
PROXY_BASE_URL="https://<ihr-proxy>"
PROXY_BASE_URL braucht das Protokoll. Ohne https:// oder http:// meldet LiteLLM den redirect_uri-Fehler. PKCE, falls der Keycloak-Client S256 verlangt: GENERIC_CLIENT_USE_PKCE=true. State gegen CSRF: GENERIC_CLIENT_STATE auf eine Zufallszeichenkette.
Test laut Doku: Proxy starten, https://<proxy>/ui öffnen, SSO klicken, in Keycloak anmelden, Rücksprung prüfen. Notfall ohne SSO: /fallback/login.
Welche Claim-Felder LiteLLM liest
Standard, überschreibbar:
GENERIC_USER_ID_ATTRIBUTE=sub
GENERIC_USER_EMAIL_ATTRIBUTE=email
GENERIC_USER_DISPLAY_NAME_ATTRIBUTE=display_name
GENERIC_USER_ROLE_ATTRIBUTE=given_role
GENERIC_SCOPE="openid profile email"
GENERIC_USER_ID_ATTRIBUTE muss ein unveränderlicher Claim sein. Unset liest LiteLLM preferred_username. Ändert der Nutzer das im Profil, entsteht beim nächsten Login ein zweites Konto mit eigenen Keys und Teams. sub ist der OIDC-Standard.
Rollenwerte, die die SSO-Doku akzeptiert:
proxy_adminproxy_admin_viewerinternal_userinternal_user_viewer
Pfade dürfen verschachtelt sein, zum Beispiel attributes.litellm_role. Zusätzliche Felder: GENERIC_USER_EXTRA_ATTRIBUTES=department,employee_id,groups. Fehlt UserInfo, Claims aus ID- und Access-Token: GENERIC_INCLUDE_TOKEN_CLAIMS=true — UserInfo hat Vorrang.
Teams aus einem Gruppen-Claim nur, wenn die Teams in LiteLLM schon existieren. Config-Feld team_ids_jwt_field (Beispiel groups). Kein Auto-Create. Debug: ENABLE_SSO_DEBUG=true, dann /sso/debug/login.
Lizenz der Admin-UI, wörtlich LiteLLM: Enterprise-Merkmal; ab v1.76.0 SSO frei bis fünf Nutzer, darüber Lizenz.
API: JWT gegen das Realm-JWKS
Das ist der zweite Weg: Anwendungen schicken ein Keycloak-JWT als Authorization: Bearer, nicht den LiteLLM-Master-Key. Die JWT-Doku und die Open-WebUI-Organisationsseite stufen das als Enterprise ein. Ohne LITELLM_LICENSE lehnt der Proxy mit JWT Auth is an enterprise only feature ab.
export JWT_PUBLIC_KEY_URL="https://<keycloak>/realms/<realm>/protocol/openid-connect/certs"
export JWT_AUDIENCE="litellm"
export JWT_ISSUER="https://<keycloak>/realms/<realm>"
Die JWT-Doku nennt denselben Certs-Pfad explizit für Keycloak. JWT_PUBLIC_KEY_URL darf auch die Discovery-URL sein; LiteLLM folgt jwks_uri. Ohne Audience und Issuer akzeptiert der Proxy jedes Token, das der IdP für irgendeine App signiert hat — die Organisationsseite warnt davor und loggt beim ersten Start.
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
enable_jwt_auth: true
litellm_jwtauth:
user_id_jwt_field: "email"
user_email_jwt_field: "email"
user_id_upsert: true
team_ids_jwt_field: "groups"
admin_jwt_scope: "litellm_proxy_admin"
issuers:
- issuer: "https://<keycloak>/realms/<realm>"
jwks_url: "https://<keycloak>/realms/<realm>/protocol/openid-connect/certs"
audience: "litellm"
user_id_jwt_field: "sub"
user_email_jwt_field: "email"
issuers scoped die Schlüsselwahl auf den Token-iss. Die JWT-Doku rät bei mehr als einem Provider zu dieser Liste und JWT_PUBLIC_KEY_URL leer zu lassen. Cache: public_key_ttl Standard 600 Sekunden, stale-Kopie danach public_key_stale_ttl Standard 3600. Transportfehler: bis zu drei Versuche, dann 30 Sekunden Sperre. Akzeptierte Algs: RS/PS/ES 256/384/512 und EdDSA; HMAC (HS*) wird abgelehnt.
Admin-Scope laut JWT-Doku: Client-Scope litellm_proxy_admin in Keycloak anlegen und im Token gewähren.
Modellzugriff über Rollen im Token beschreibt die Seite „Control Model Access with OIDC“: user_roles_jwt_field, user_allowed_roles, enforce_rbac, role_permissions. Keycloak legt Rollen oft unter resource_access.<client-id>.roles ab — dann genau diesen Pfad setzen. Die Seite mappt derzeit internal_user.
Claims, die Keycloak erst ausstellen muss
Die Open-WebUI-Organisationsseite (getestet mit Open WebUI v0.12.0, Keycloak 26.4, LiteLLM v1.105.0) nennt drei Mapper am dedizierten Client-Scope, alle „Add to access token“:
- Group Membership, Claim
groups, Full group path aus. - Audience, included custom audience
litellm. - Optional User Attribute
org→ Claimorg_id.
Keycloak 24 und neuer schreibt nur Attribute, die im Realm User Profile stehen. Sonst org_id still leer — Attribut deklarieren oder Unmanaged Attributes auf Enabled.
Access-Token-Lebensdauer laut derselben Seite mindestens 15 Minuten. Open WebUI erneuert fünf Minuten vor Ablauf; der Keycloak-Default von fünf Minuten trifft jedes Request. Realm- oder Client-Override: Access Token Lifespan in der Keycloak-Doku (Advanced Settings).
Direktzugriff (Password Grant) nur zum Claim-Check, danach in der Capability Config wieder aus. Decode vor dem Rollout:
printf '%s' "$TOKEN" | cut -d. -f2 | tr '_-' '/+' \
| awk '{ p=(4-length($0)%4)%4; printf "%s",$0; for(i=0;i<p;i++) printf "="; print "" }' \
| base64 -d | jq '{iss,aud,email,groups,org_id}'
iss, aud und groups müssen zu JWT_ISSUER, JWT_AUDIENCE und den vorhandenen team_ids passen. Team fehlt: 403 No teams found in token — auch Admins brauchen eine Gruppe.
Chat-UI vor dem Gateway, TLS und WebSocket: OpenWebUI Nginx Reverse Proxy. Mehrere Proxy-Instanzen: LiteLLM Cluster Setup. Port des lokalen Ollama-Backends: Ollama Port 11434. GPU-Klasse des Servers, unverändert mit kaufen: KI-Server kaufen.
Häufige Fehler
| Symptom | Ursache laut Doku |
|---|---|
redirect_uri passt nicht | URI fehlt im Client oder PROXY_BASE_URL ohne Protokoll |
| 401 Audience / Issuer | JWT_AUDIENCE oder JWT_ISSUER weicht vom decodierten Token ab |
401 No matching public key | kid nicht in der JWKS; nach Key-Rotation public_key_ttl abwarten |
| 401 HMAC nicht erlaubt | Client signiert mit HS*; auf RS256 stellen |
401 JWT Auth is an enterprise only feature | LITELLM_LICENSE fehlt |
| 403 keine Teams | groups fehlt oder team_id existiert nicht |
org_id leer | User Profile / Unmanaged Attributes in Keycloak 24+ |
Häufige Fragen
Ist das dasselbe wie Entra-ID-SSO?
Nein. Entra nutzt MICROSOFT_CLIENT_ID und Graph-Gruppen. Keycloak läuft über Generic SSO plus Realm-JWKS. Die Entra-Anleitung bleibt Entra-ID-SSO.
Reicht Admin-UI-SSO ohne JWT-Lizenz?
Für die Oberfläche: ja, im Rahmen der Fünf-Nutzer-Grenze ab v1.76.0. Für Bearer-JWTs der API: nein, das ist das Enterprise-Merkmal enable_jwt_auth.
Welches Secret kommt in GENERIC_CLIENT_SECRET?
Das Client-Secret aus dem Keycloak-Tab Credentials, Client authentication ON. Nicht den LiteLLM-Master-Key.
Warum schlägt der Rücksprung fehl?
Zuerst Redirect-URI und PROXY_BASE_URL inkl. Schema prüfen. Danach Assignments im Realm: Nutzer muss dem Client zugeordnet sein. Debug-Route nur temporär aktivieren.
Fazit
LiteLLM und Keycloak koppelt man in zwei dokumentierten Schritten: Generic-OIDC für /ui (GENERIC_*, /sso/callback) und JWT gegen das Realm-JWKS für die API. Claims, Audience und bestehende Teams müssen stimmen, bevor die erste Fachanwendung den Bearer schickt. Kein zweiter Hardware-Kaufguide und keine Euro-Versprechen.
Quellen & Weiterführende Links
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
Entra ID SSO für Open WebUI, LiteLLM und n8n einrichten
Drei KI-Werkzeuge, eine Anmeldung: OIDC gegen Entra ID für Open WebUI, LiteLLM und n8n — mit den Lizenzgrenzen, die vorher niemand nennt.
KI on-premise betreiben: der Einstieg
Was KI on-premise wirklich verlangt: Hardware, Stellplatz, Betrieb, Update-Konzept — und die drei Einstiegsszenarien, die in vier Wochen stehen.
Qdrant-Cluster aufsetzen: skalierbare Vektorsuche
Qdrant-Cluster on-premise aufsetzen: hochverfügbare Vektorsuche für RAG und Bildklassifizierung. Architektur, Replikation und Betrieb Schritt für Schritt.
Bereit für KI im Mittelstand?
Nutzen Sie unsere 10 kostenlosen KI-Tools und Praxis-Guides – oder sprechen Sie direkt mit unseren Experten.
Pexon Consulting – KI-Beratung für den Mittelstand | Scaly Academy – Geförderte KI-Weiterbildung (KI-Spezialist, KI-Experte, Workflow-Automatisierung)