Keycloak Service Accounts statt technischer Benutzer: M2M-Authentifizierung mit OAuth
Wenn Systeme miteinander kommunizieren, stellt sich immer die Frage: Wie weist sich ein System gegenüber einem anderen aus? Ein Microservice, der nachts einen Batchjob ausführt, ein CI/CD-System, das Deployments anstößt, oder ein Backend, das im Hintergrund auf eine API zugreift – all diese Szenarien brauchen eine Systemidentität.
Die klassischen Lösungen für dieses Problem – API-Keys, technische Benutzerkonten oder Shared Secrets – haben alle ihre Schwächen. Keycloak bietet mit Service Accounts eine deutlich bessere Alternative, die auf dem bewährten OAuth 2.0 Standard aufbaut.
Das Problem mit klassischen Ansätzen
Bevor wir uns Service Accounts ansehen, lohnt ein Blick auf die Alternativen und warum diese in der Praxis problematisch sind.
API-Keys
API-Keys sind weit verbreitet und auf den ersten Blick einfach: Man generiert einen langen, zufälligen String, hinterlegt ihn im aufrufenden System und schickt ihn bei jeder Anfrage mit – meist als HTTP-Header.
Das Problem liegt jedoch im Betrieb: API-Keys haben häufig kein Ablaufdatum und sind damit dauerhaft gültig. Einmal ausgestellt, sind sie oft schwer zu rotieren, weil alle Systeme, die den Key verwenden, gleichzeitig umgestellt werden müssen. Sie tragen keine Identitätsinformationen in sich – der Server kann lediglich prüfen, ob der Key bekannt ist, aber nicht, welches System gerade anfragt. Feingranulare Berechtigungen sind meist nicht vorgesehen: Ein API-Key öffnet in der Regel Tür und Tor. Und wird ein Key kompromittiert, ist das Schadenspotenzial hoch, weil er bis zur expliziten Sperrung weiter missbraucht werden kann.
Technische Benutzerkonten
Ein verbreiteter Workaround ist das Anlegen von "technischen Benutzern": normale Benutzerkonten in Keycloak oder einem LDAP-Verzeichnis, die einfach keinem Menschen gehören, sondern für Systeme gedacht sind.
Das klingt pragmatisch, bringt aber eigene Probleme mit: Das Passwort muss irgendwo gespeichert werden – im Anwendungsconfig, in einem Secret-Store oder im Code. Für die Anmeldung wird der Resource Owner Password Credentials Grant (ROPC) verwendet, der im OAuth 2.0 Security Best Current Practice als veraltet und unsicher gilt und in OAuth 2.1 ganz entfernt wurde. Benutzerkonten durchlaufen Passwort-Ablaufrichtlinien, werden gesperrt oder erfordern eine MFA-Einrichtung – alles Mechanismen, die für menschliche Identitäten sinnvoll sind, für Systeme aber zu unerwarteten Ausfällen führen. Der Audit-Trail vermischt menschliche und maschinelle Aktivitäten.
Shared Secrets und Basic Auth
Ähnliche Schwächen hat die direkte Verwendung von HTTP Basic Auth mit einem gemeinsamen Passwort: keine Granularität, schwer zu rotieren, kein Ablaufdatum.
Service Accounts: die bessere Alternative
Keycloak Service Accounts lösen diese Probleme, indem sie auf dem OAuth 2.0 Client Credentials Flow aufbauen. Die Idee ist einfach: Statt einem menschlichen Benutzer wird einem OAuth 2.0 Client eine eigene Identität gegeben. Dieser Client authentifiziert sich direkt beim Authorization Server (Keycloak) und erhält ein kurzlebiges Access Token – ohne Umweg über einen Benutzer-Login.
Der Ablauf sieht so aus:
System A Keycloak System B
| | |
|-- POST /token ----------->| |
| grant_type=client_cred | |
| client_id=system-a | |
| client_secret=... | |
| | |
|<-- access_token ----------| |
| (kurzlebig, z.B. 5min) | |
| | |
|-- GET /api/resource --------------------------------->|
| Authorization: Bearer <token> |
| | |
System A fragt also zunächst bei Keycloak ein Token an, und schickt dieses Token dann bei der eigentlichen API-Anfrage mit. System B validiert das Token, ohne Keycloak erneut kontaktieren zu müssen.
Konfiguration in Keycloak
In Keycloak wird ein Service Account aktiviert, indem beim Client die Option Service accounts roles eingeschaltet wird. Damit erhält der Client automatisch ein eigenes Benutzerkonto im Realm, dem Rollen und Scopes zugewiesen werden können.
Client anlegen und konfigurieren
Im Keycloak Admin-UI legt man einen neuen Client an:
-
Client ID vergeben, z.B.
batch-processor -
Client authentication aktivieren (macht den Client zu einem Confidential Client)
-
Unter Authentication flow nur Service accounts roles aktivieren, alle anderen Flows deaktivieren
-
Nach dem Speichern erscheint der Tab Service account roles, über den dem Client Realm-Rollen oder Client-Rollen zugewiesen werden können
Das Client Secret findet sich im Tab Credentials und kann bei Bedarf jederzeit neu generiert werden.
Rollen zuweisen
Dem Service Account sollten nur die Rollen zugewiesen werden, die er tatsächlich benötigt – Principle of Least Privilege.
Verfügt die Ziel-API z.B. über die Rollen report:read und report:write, bekommt ein Leseclient nur report:read.
Das ist einer der wesentlichen Vorteile gegenüber API-Keys: Die Berechtigungen sind direkt in der Identität kodiert und werden im Token mitgeliefert.
Token-Lebensdauer
Die Lebensdauer des Access Tokens lässt sich pro Client oder global konfigurieren. Für Service Accounts empfiehlt sich eine kurze Lebensdauer von wenigen Minuten. Das aufrufende System holt sich bei Bedarf ein neues Token – das ist mit ein paar Zeilen Code schnell umgesetzt und schränkt das Missbrauchsrisiko bei einem kompromittierten Token erheblich ein.
Token anfordern: ein Beispiel
Das Anfordern eines Tokens ist ein einfacher HTTP-POST-Request an den Token-Endpunkt des Realms:
curl -s -X POST \
"https://keycloak.example.com/realms/myrealm/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=batch-processor" \
-d "client_secret=s3cr3t"
Die Antwort enthält das Access Token, seine Lebensdauer und den Token-Typ:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6...",
"expires_in": 300,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "profile email"
}
Das Token ist ein JWT und kann vom aufrufenden System gecacht werden, bis es abläuft. Danach wird einfach ein neues angefordert.
Integration in Spring Boot
Spring Security OAuth2 Client unterstützt den Client Credentials Flow direkt. Mit wenigen Konfigurationszeilen kümmert sich Spring automatisch um das Token-Caching und die Erneuerung:
spring:
security:
oauth2:
client:
registration:
reporting-api:
provider: keycloak
client-id: batch-processor
client-secret: ${KEYCLOAK_CLIENT_SECRET}
authorization-grant-type: client_credentials
scope: profile
provider:
keycloak:
issuer-uri: https://keycloak.example.com/realms/myrealm
Ein WebClient wird dann mit dem ServletOAuth2AuthorizedClientExchangeFilterFunction konfiguriert, der das Token automatisch anhängt:
@Bean
WebClient reportingApiClient(OAuth2AuthorizedClientManager authorizedClientManager) {
var oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2.setDefaultClientRegistrationId("reporting-api");
return WebClient.builder()
.baseUrl("https://reporting.example.com")
.apply(oauth2.oauth2Configuration())
.build();
}
Alle Aufrufe über diesen WebClient erhalten automatisch ein gültiges Access Token – inklusive transparenter Erneuerung, wenn das Token abgelaufen ist.
Vorteile von Service Accounts im Überblick
Kurzlebige Tokens statt dauerhafter Credentials
Das Access Token läuft nach wenigen Minuten ab. Wird es abgefangen oder in einem Log-Eintrag gespeichert, ist der Schaden begrenzt. API-Keys dagegen sind oft jahrelang gültig.
Einfache Rotation
Das Client Secret kann jederzeit in der Keycloak Admin-Konsole neu generiert werden – ohne dass andere Systeme davon betroffen sind. Das neue Secret muss lediglich in der Konfiguration des einen betroffenen Clients aktualisiert werden. Bei API-Keys sind typischerweise viele Systeme betroffen, die alle gleichzeitig umgestellt werden müssen.
Feingranulare Berechtigungen
Rollen und Scopes werden im Token mitgeliefert und können pro Client exakt konfiguriert werden. Ein Service Account für einen Leseclient bekommt keine Schreibrechte – auch wenn er ein gültiges Token vorlegt.
Sauberer Audit-Trail
Jeder Token-Request wird in Keycloak protokolliert. Im Audit-Log ist klar erkennbar, welches System wann ein Token angefordert hat – nicht nur "jemand mit diesem API-Key". Das erleichtert die Fehlersuche und die Reaktion auf Sicherheitsvorfälle.
Zentrales Identity Management
Alle Systemidentitäten werden an einer Stelle verwaltet: in Keycloak. Service Accounts können deaktiviert werden, ohne dass Passwörter gesperrt oder Keys aus Datenbanken gelöscht werden müssen. In einer Umgebung mit vielen Microservices behält man so den Überblick.
Kein Password Grant notwendig
Der Client Credentials Flow ist explizit für Machine-to-Machine-Kommunikation vorgesehen und in OAuth 2.1 weiterhin vorhanden. Er erfordert keinen Benutzer-Kontext und unterliegt nicht den Einschränkungen, die für interaktive Logins gelten.
Noch mehr Sicherheit: Alternativen zum Client Secret
Das Client Secret ist einfach einzurichten, aber ein geteiltes Geheimnis bleibt ein geteiltes Geheimnis. Für besonders sicherheitskritische Anwendungen bietet Keycloak weitere Authentifizierungsmethoden für Clients:
-
Signed JWT: Der Client besitzt einen privaten Schlüssel und signiert ein JWT, das er anstelle des Secrets mitschickt. Der private Schlüssel verlässt das System nie.
-
MTLS: Der Client authentifiziert sich mit einem Client-Zertifikat. Das Access Token kann zusätzlich an dieses Zertifikat gebunden werden (sender-constrained), was den Missbrauch gestohlener Tokens verhindert.
Diese Verfahren bieten ein höheres Sicherheitsniveau, erfordern aber auch mehr Aufwand bei der Verwaltung von Schlüsselmaterial.
Zusammenfassung
Service Accounts in Keycloak sind die richtige Wahl, wenn Systeme sicher miteinander kommunizieren sollen. Sie vermeiden die Schwächen von API-Keys und technischen Benutzern und bauen stattdessen auf dem etablierten OAuth 2.0 Standard auf.
Die wichtigsten Vorteile auf einen Blick:
| Kriterium | API-Key / technischer Benutzer | Service Account (Client Credentials) |
|---|---|---|
Token-Lebensdauer |
Permanent / bis zur Sperre |
Wenige Minuten, automatisch erneuert |
Rotation |
Aufwändig, viele Systeme betroffen |
Einfach, nur ein Client betroffen |
Berechtigungen |
Meist pauschal |
Feingranular per Rollen und Scopes |
Audit-Trail |
Key-ID oder Benutzername |
Client-Identität, Zeitstempel, Scope |
Standards |
Proprietär |
OAuth 2.0, RFC 6749 |
Zukunftssicherheit |
ROPC in OAuth 2.1 entfernt |
Explizit vorgesehen für M2M |
Wer Keycloak bereits im Einsatz hat, kann Service Accounts ohne zusätzliche Infrastruktur nutzen. Die Konfiguration ist in wenigen Minuten erledigt, und die Integration in gängige Frameworks wie Spring Boot ist gut unterstützt.
Zum Thema Keycloak und Security bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:
Vor der Inbetriebnahme einer Keycloak-Installation sollte sichergestellt sein, dass das System tatsächlich bereit für den produktiven Einsatz ist und alle wesentlichen Punkte bei Konfiguration, Integration und Betriebsprozessen berücksichtigt wurden. Hierbei hilft unser Production Readiness Review für Keycloak.
Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.