API d'administration et comptes de service
Utiliser l'Admin REST API pour créer, rechercher et réinitialiser des comptes depuis une application, avec un compte de service limité au strict nécessaire.
Sur cette page
Beaucoup d’applications ne se contentent pas d’authentifier leurs utilisateurs : elles créent des comptes à l’inscription d’un partenaire, désactivent un compte au départ d’un agent, relancent une invitation. Avec Keycloak, elles le font par l’Admin REST API, au nom d’un compte de service. Ce cours montre les appels utiles, les droits minimaux à accorder et les garde-fous à poser.
L’Admin REST API
Tout ce que fait la console d’administration passe par l’Admin REST API : la console n’en est qu’un client. Les chemins commencent par /admin/realms/<realm>/… et la référence complète est publiée dans la documentation (format OpenAPI).
Chaque appel porte un jeton d’accès. Ce jeton doit contenir des rôles d’administration : soit le rôle admin du realm master (administrateur du serveur), soit des rôles du client realm-management du realm visé. Dans les versions récentes de la branche 26, les rôles d’administration ne comptent que s’ils sont réellement assignés au compte, directement ou par un groupe ; un rôle ajouté au jeton par un protocol mapper ne donne pas accès à l’API.
Les comptes de service
Un compte de service est l’identité d’un client confidentiel, utilisée avec le grant client credentials (RFC 6749). Il se configure sur le client :
- Client authentication activé (client confidentiel) ;
- Service accounts roles activé, les autres flux désactivés ;
- des rôles assignés dans l’onglet Service accounts roles.
Keycloak crée pour cela un utilisateur technique nommé service-account-<clientId>. L’application obtient son jeton dans son realm :
curl -s -X POST "$KC/realms/approfondir/protocol/openid-connect/token" \
-d grant_type=client_credentials \
-d client_id=provisioning-app \
-d client_secret="$CLIENT_SECRET"
Un compte de service d’un realm applicatif, doté de rôles realm-management de ce realm, ne peut agir que sur ce realm. C’est le premier cloisonnement, et il est gratuit.
Les rôles minimaux
Le client realm-management porte des rôles par domaine. Les principaux :
| Rôle | Permet | Remarque |
|---|---|---|
query-users, query-groups | Rechercher, ouvrir les menus de la console | Ne donne pas la lecture du détail |
view-users | Lire tous les utilisateurs et groupes | Inclut les rôles de recherche |
manage-users | Créer, modifier, désactiver, réinitialiser, gérer groupes et rôles des utilisateurs | Porte sur tout le realm |
view-events | Lire les événements stockés | Utile pour un outil de support |
manage-organizations | Gérer les organisations et leurs membres | Depuis 26.7 ; avant, manage-realm |
manage-clients, manage-realm | Modifier la configuration | À réserver à l’outillage de configuration |
realm-admin | Tout le realm | Jamais pour une application |
D’où les profils types :
| Besoin de l’application | Rôles à accorder |
|---|---|
| Vérifier qu’un compte existe | view-users |
| Créer des comptes, les mettre dans un groupe, envoyer l’invitation | manage-users |
| Créer des comptes dans un seul groupe ou une seule organisation | query-users et permissions v2 sur ce groupe ou cette organisation |
| Outil de support (consulter, relancer, débloquer) | view-users, view-events, et manage-users si l’outil agit |
manage-users reste un rôle large : il couvre tous les utilisateurs du realm. Pour qu’une application partenaire ne gère que ses comptes, il faut retirer ce rôle et passer par les permissions d’administration v2 (voir le cours sur la délégation), avec une policy de type User qui désigne service-account-<clientId>.
Les appels courants
Créer un compte (la réponse 201 renvoie l’URL du compte dans l’en-tête Location) :
curl -s -i -X POST "$KC/admin/realms/approfondir/users" \
-H "Authorization: Bearer $SA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"username": "dany@acme.test", "email": "dany@acme.test",
"firstName": "Dany", "lastName": "Martin", "enabled": true}'
Envoyer à l’utilisateur un lien pour choisir son mot de passe et vérifier son e-mail (le serveur SMTP du realm doit être configuré) :
curl -s -X PUT "$KC/admin/realms/approfondir/users/$USER_ID/execute-actions-email?client_id=portail&redirect_uri=https%3A%2F%2Fportail.example%2F&lifespan=86400" \
-H "Authorization: Bearer $SA_TOKEN" \
-H "Content-Type: application/json" \
-d '["UPDATE_PASSWORD", "VERIFY_EMAIL"]'
Rechercher par e-mail exact, puis désactiver :
curl -s "$KC/admin/realms/approfondir/users?email=dany%40acme.test&exact=true" \
-H "Authorization: Bearer $SA_TOKEN"
curl -s -X PUT "$KC/admin/realms/approfondir/users/$USER_ID" \
-H "Authorization: Bearer $SA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
Trois règles de conception pour l’application appelante :
- Ne jamais fixer le mot de passe à la place de l’utilisateur en production : préférer
execute-actions-email. L’appelreset-passwordexiste, mais l’application connaît alors un secret qui ne la regarde pas. - Gérer les conflits. Un nom d’utilisateur ou un e-mail déjà pris renvoie 409. La règle de rapprochement (rattacher, refuser, alerter) appartient à l’application, pas à Keycloak.
- Respecter le user profile. Les attributs envoyés sont validés contre la configuration du user profile. Un attribut non déclaré peut être ignoré ou refusé selon le réglage des attributs non gérés.
Sécuriser les comptes de service
| Mesure | Pourquoi |
|---|---|
| Un client par application appelante | Tracer et révoquer séparément |
| Secret dans un coffre, rotation planifiée | La rotation est supportée depuis 26.8, avec deux secrets actifs en transition |
| Clé privée signée plutôt que secret, si l’application le permet | Aucun secret partagé à transmettre |
| Événements d’administration activés | Chaque appel est attribué au client et au compte de service qui l’a fait |
Chemins /admin non exposés sur Internet | La documentation recommande de ne pas exposer les points d’administration sans nécessité |
Le dernier point dépend de l’architecture d’hébergement : vérifiez avec l’hébergeur si l’Admin REST API peut être exposée séparément du parcours de connexion, et filtrée par origine.
Et SCIM ?
Depuis 26.8, Keycloak propose en version supportée une API SCIM (RFC 7643 et 7644) sous /realms/<realm>/scim/v2, à activer realm par realm. Elle gère utilisateurs et groupes avec le même modèle de droits que l’Admin REST API. Si l’application ou l’outil RH dispose déjà d’un connecteur SCIM, c’est une option à privilégier : aucun client propre à Keycloak à écrire. Pour une version antérieure à 26.8, SCIM n’est pas disponible en version supportée.
Un compte de service de provisionnement
30 min
Installer le lab-
Dans le realm
approfondir, créez le groupepartenaires-acmes’il n’existe pas. -
Créez un client
provisioning-app: Client authentication activé, Standard flow et Direct access grants désactivés, Service accounts roles activé. -
Onglet Service accounts roles : assignez le rôle
manage-usersdu clientrealm-management, et lui seul. -
Onglet Client scopes, client scope
provisioning-app-dedicated, onglet Scope : désactivez Full scope allowed et ajoutez le rôlerealm-managementmanage-users. -
Onglet Client scopes, sous-onglet Evaluate : choisissez l’utilisateur
service-account-provisioning-appet générez l’access token. Vérifiez queresource_access.realm-management.rolescontientmanage-users, et rien de plus. -
Copiez le secret de l’onglet Credentials, obtenez un jeton et créez un compte :
KC=http://localhost:8080 CLIENT_SECRET='collez-le-secret' SA_TOKEN=$(curl -s -X POST "$KC/realms/approfondir/protocol/openid-connect/token" \ -d grant_type=client_credentials -d client_id=provisioning-app \ -d client_secret="$CLIENT_SECRET" | jq -r .access_token) curl -s -i -X POST "$KC/admin/realms/approfondir/users" \ -H "Authorization: Bearer $SA_TOKEN" -H "Content-Type: application/json" \ -d '{"username": "dany@acme.test", "email": "dany@acme.test", "firstName": "Dany", "lastName": "Martin", "enabled": true}' \ | grep -i '^location' -
Récupérez l’identifiant du compte et celui du groupe, puis placez le compte dans le groupe :
USER_ID=$(curl -s -H "Authorization: Bearer $SA_TOKEN" \ "$KC/admin/realms/approfondir/users?username=dany@acme.test&exact=true" | jq -r '.[0].id') GROUP_ID=$(curl -s -H "Authorization: Bearer $SA_TOKEN" \ "$KC/admin/realms/approfondir/groups?search=partenaires-acme&exact=true" | jq -r '.[0].id') curl -s -o /dev/null -w '%{http_code}\n' -X PUT -H "Authorization: Bearer $SA_TOKEN" \ "$KC/admin/realms/approfondir/users/$USER_ID/groups/$GROUP_ID" -
Vérifiez dans la console que
dany@acme.testest membre departenaires-acme. Rejouez la création du compte : la réponse est 409. -
Testez les limites du compte de service. Ces deux appels doivent être refusés (403, ou 401 pour le realm master selon la version) :
curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $SA_TOKEN" \ "$KC/admin/realms/approfondir/clients" curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $SA_TOKEN" \ "$KC/admin/realms/master/users" -
Si les événements d’administration sont activés (cours sur les événements), retrouvez la création du compte et vérifiez qu’elle est attribuée au client
provisioning-app.
À retenir pour l’architecture
Dans le questionnaire applicatif, demandez si l’application crée, modifie ou désactive elle-même des comptes. Si oui, prévoyez un compte de service par application, dans le realm applicatif, avec manage-users au plus, ou des permissions v2 si le périmètre doit se limiter à un groupe ou une organisation. Préférez l’invitation par e-mail au mot de passe fixé, envisagez SCIM quand l’outil appelant le parle, et vérifiez avec l’hébergeur comment l’Admin REST API est exposée.
Natif, extension ou hébergeur
Natif : fourni par Keycloak, à configurer. Extension : demande du code à maintenir (un SPI, le mécanisme de plugin de Keycloak). Hébergeur : dépend de la plateforme qui héberge Keycloak, à vérifier avec elle.
| Capacité | Verdict | Précision |
|---|---|---|
| Admin REST API (création, recherche, désactivation, réinitialisation de comptes) | Natif | Couvre tout ce que fait la console d'administration. |
| Comptes de service avec rôles du client realm-management | Natif | Client confidentiel, grant client credentials, rôles assignés au compte de service. |
| Limiter un compte de service à un groupe ou une organisation | Natif | Avec les permissions d'administration v2 et une policy qui désigne l'utilisateur du compte de service. |
| API SCIM pour le provisionnement standard | Natif | Supportée depuis 26.8, à activer par realm. Même modèle de droits que l'Admin REST API. |
| Règles métier de provisionnement (rapprochement, doublons, affectation) | Extension | À porter par l'application appelante ou un connecteur ; Keycloak n'exécute que les appels reçus. |
| Accès réseau des applications à l'Admin REST API | Hébergeur | Exposition des chemins /admin et filtrage par origine à vérifier avec l'hébergeur. |
Vérifier ce que vous avez retenu
4 questions
-
Une application doit créer des comptes et les placer dans un groupe. Quel rôle accorder à son compte de service ?
manage-users permet de créer des comptes et de gérer les appartenances aux groupes. realm-admin ou admin donneraient la main sur toute la configuration.
-
Après création d'un compte, comment l'utilisateur définit-il son mot de passe dans la solution la plus sûre ?
Le mot de passe n'est jamais connu de l'application. Le lien d'action expire, et la vérification de l'e-mail est faite au passage.
-
Deux applications partenaires doivent chacune gérer uniquement leurs propres utilisateurs. Que faites-vous ?
Un compte par application permet de tracer et révoquer. La restriction de périmètre passe par les permissions v2 ; manage-users les court-circuiterait.
-
Un éditeur de logiciel de gestion RH propose un connecteur SCIM. Quel est l'intérêt par rapport à l'Admin REST API ?
SCIM (RFC 7643 et 7644) évite d'écrire un client propre à Keycloak. Les droits restent ceux de l'Admin REST API.