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.

Approfondir Cours 17 sur 17 de Keycloak Academy 35 min 4 questions de quiz

Sur cette page
  1. L’Admin REST API
  2. Les comptes de service
  3. Les rôles minimaux
  4. Les appels courants
  5. Sécuriser les comptes de service
  6. Et SCIM ?
  7. À retenir pour l’architecture
  8. Natif, extension ou hébergeur
  9. Quiz

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ôlePermetRemarque
query-users, query-groupsRechercher, ouvrir les menus de la consoleNe donne pas la lecture du détail
view-usersLire tous les utilisateurs et groupesInclut les rôles de recherche
manage-usersCréer, modifier, désactiver, réinitialiser, gérer groupes et rôles des utilisateursPorte sur tout le realm
view-eventsLire les événements stockésUtile pour un outil de support
manage-organizationsGérer les organisations et leurs membresDepuis 26.7 ; avant, manage-realm
manage-clients, manage-realmModifier la configurationÀ réserver à l’outillage de configuration
realm-adminTout le realmJamais pour une application

D’où les profils types :

Besoin de l’applicationRôles à accorder
Vérifier qu’un compte existeview-users
Créer des comptes, les mettre dans un groupe, envoyer l’invitationmanage-users
Créer des comptes dans un seul groupe ou une seule organisationquery-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’appel reset-password existe, 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

MesurePourquoi
Un client par application appelanteTracer et révoquer séparément
Secret dans un coffre, rotation planifiéeLa 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 permetAucun secret partagé à transmettre
Événements d’administration activésChaque appel est attribué au client et au compte de service qui l’a fait
Chemins /admin non exposés sur InternetLa 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
  1. Dans le realm approfondir, créez le groupe partenaires-acme s’il n’existe pas.

  2. Créez un client provisioning-app : Client authentication activé, Standard flow et Direct access grants désactivés, Service accounts roles activé.

  3. Onglet Service accounts roles : assignez le rôle manage-users du client realm-management, et lui seul.

  4. Onglet Client scopes, client scope provisioning-app-dedicated, onglet Scope : désactivez Full scope allowed et ajoutez le rôle realm-management manage-users.

  5. Onglet Client scopes, sous-onglet Evaluate : choisissez l’utilisateur service-account-provisioning-app et générez l’access token. Vérifiez que resource_access.realm-management.roles contient manage-users, et rien de plus.

  6. 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'
  7. 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"
  8. Vérifiez dans la console que dany@acme.test est membre de partenaires-acme. Rejouez la création du compte : la réponse est 409.

  9. 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"
  10. 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éVerdictPrécision
Admin REST API (création, recherche, désactivation, réinitialisation de comptes)NatifCouvre tout ce que fait la console d'administration.
Comptes de service avec rôles du client realm-managementNatifClient confidentiel, grant client credentials, rôles assignés au compte de service.
Limiter un compte de service à un groupe ou une organisationNatifAvec les permissions d'administration v2 et une policy qui désigne l'utilisateur du compte de service.
API SCIM pour le provisionnement standardNatifSupporté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 APIHébergeurExposition des chemins /admin et filtrage par origine à vérifier avec l'hébergeur.

Vérifier ce que vous avez retenu

4 questions

  1. Une application doit créer des comptes et les placer dans un groupe. Quel rôle accorder à son compte de service ?

  2. Après création d'un compte, comment l'utilisateur définit-il son mot de passe dans la solution la plus sûre ?

  3. Deux applications partenaires doivent chacune gérer uniquement leurs propres utilisateurs. Que faites-vous ?

  4. Un éditeur de logiciel de gestion RH propose un connecteur SCIM. Quel est l'intérêt par rapport à l'Admin REST API ?