Aller au contenu
medium

SCIM : le provisioning automatique des identités

20 min de lecture

SCIM automatise le cycle de vie des comptes utilisateurs. Quand un collaborateur arrive, son compte est créé automatiquement dans toutes les applications. Quand il part, tous ses accès sont désactivés en quelques secondes, pas en quelques jours. Sans SCIM, vous gérez manuellement les comptes dans chaque application, avec les risques de sécurité et d'erreurs que cela implique.

Ce guide vous explique SCIM, le standard pour synchroniser automatiquement les identités entre l'IdP et les applications. À la fin, vous saurez :

  • Comprendre pourquoi SCIM est nécessaire (et ses alternatives)
  • Maîtriser les opérations SCIM : création, modification, désactivation
  • Configurer un offboarding propre (désactiver + révoquer)
  • Anticiper les pièges courants d'implémentation

Prérequis : avoir lu Les bases de l'IAM.

Sans provisioning automatique, voici ce qui se passe :

  1. Un employé arrive → création manuelle du compte dans chaque application
  2. L'employé change de service → modification manuelle des groupes
  3. L'employé part → on oublie de désactiver certains comptes

Résultat : des comptes orphelins qui persistent pendant des mois, voire des années. Le risque n'est pas théorique : ces comptes gardent leurs droits, n'apparaissent dans aucune revue puisque personne ne les réclame, et échappent souvent au MFA faute d'un utilisateur pour l'activer. Ils constituent une porte d'entrée idéale, sans propriétaire pour remarquer une connexion suspecte.

Le compte est créé au premier login via SSO (OIDC/SAML).

Comment ça marche :

  1. L'utilisateur se connecte pour la première fois
  2. L'application reçoit l'assertion SAML ou l'ID Token
  3. L'application crée le compte à partir des attributs reçus

Avantages :

  • Simple à mettre en place
  • Pas de synchronisation à maintenir

Limites :

  • Le compte n'existe qu'au premier login
  • Pas de pré-configuration (groupes, permissions spécifiques)
  • Pas de deprovisioning automatique

L'IdP pousse les changements vers les applications en temps réel. La différence de fond avec le JIT tient à ce sens de circulation : ici, l'IdP n'attend pas que l'utilisateur se manifeste, il agit dès que la donnée change côté annuaire. C'est ce qui rend le deprovisioning possible, un départ n'étant jamais suivi d'une connexion qui aurait pu servir de déclencheur.

Comment ça marche :

  1. Un utilisateur est créé/modifié/désactivé dans l'IdP
  2. L'IdP envoie une requête SCIM à l'application
  3. L'application applique le changement

Avantages :

  • Comptes pré-créés avant le premier login
  • Synchronisation des groupes et attributs
  • Deprovisioning automatique

Limites :

  • L'application doit supporter SCIM
  • Configuration plus complexe

SCIM (System for Cross-domain Identity Management) est défini par deux RFC :

  • RFC 7643 : Schéma SCIM (objets User, Group)
  • RFC 7644 : Protocole SCIM (API REST)

Cette séparation en deux documents a une conséquence concrète quand vous qualifiez une application : le support de SCIM n'est pas binaire. Un éditeur peut implémenter le schéma de la RFC 7643 tout en ne proposant qu'une partie des opérations de la RFC 7644, typiquement POST et PUT sans PATCH. Demandez toujours la liste des opérations supportées, pas seulement la mention « compatible SCIM 2.0 ».

Le sens des flèches est le point important du schéma, et il surprend souvent : c'est l'IdP qui joue le rôle de client et l'application qui joue le rôle de serveur. Autrement dit, c'est l'annuaire central qui appelle l'API REST exposée par chaque application, et non l'inverse. Cette inversion explique deux contraintes pratiques : l'application doit publier un endpoint SCIM joignable depuis l'IdP, et chaque application détient son propre jeton d'authentification que l'IdP conserve.

Architecture SCIM : l'IdP (SCIM Client) pousse les utilisateurs vers l'application (SCIM Server) via l'API REST

L'IdP agit comme SCIM Client (pousse les changements). L'application agit comme SCIM Server (reçoit et applique).

Le schéma RFC 7643 ne définit que deux ressources obligatoires, User et Group. Tout le reste (rôles applicatifs, licences, matricule) passe par des extensions de schéma, déclarées dans le tableau schemas. Lisez donc les exemples ci-dessous en regardant d'abord ce tableau : il indique quelle grammaire l'application doit savoir interpréter.

Dans la charge utile ci-dessous, trois champs pilotent tout le cycle de vie : externalId fait le lien avec l'IdP, active porte l'activation ou la désactivation du compte, et userName sert d'identifiant de connexion. Les autres attributs sont du confort d'affichage. Notez que id n'est pas fourni par l'IdP : c'est l'application qui le génère et le renvoie à la création.

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "2819c223-7f76-453a-919d-413861904646",
"externalId": "alice.martin",
"userName": "alice.martin@example.com",
"name": {
"givenName": "Alice",
"familyName": "Martin"
},
"emails": [
{
"value": "alice.martin@example.com",
"type": "work",
"primary": true
}
],
"active": true,
"groups": [
{
"value": "developers",
"display": "Developers Team"
}
],
"meta": {
"resourceType": "User",
"created": "2024-02-06T10:00:00Z",
"lastModified": "2024-02-06T10:00:00Z"
}
}

Retenez surtout la paire id / externalId : c'est la source de la majorité des incidents de synchronisation. Chaque système garde son propre identifiant, et l'IdP doit mémoriser le id renvoyé par l'application pour pouvoir la mettre à jour ensuite. Si cette correspondance est perdue, l'IdP ne sait plus quel compte modifier et recrée des doublons au lieu de désactiver l'existant.

AttributDescription
idIdentifiant unique côté application
externalIdIdentifiant unique côté IdP
userNameIdentifiant de login (souvent l'email)
activeCompte actif ou désactivé
emailsListe des adresses email
groupsGroupes auxquels appartient l'utilisateur

Un objet Group ne contient que son nom d'affichage et la liste de ses membres, référencés par leur id côté application. Conséquence directe : ajouter quelqu'un à un groupe se fait en modifiant le groupe, pas l'utilisateur. Beaucoup d'applications n'implémentent d'ailleurs que la ressource User et ignorent Group, auquel cas les appartenances doivent être gérées autrement, par exemple via un claim transmis au moment de la connexion SSO.

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
"id": "group-123",
"displayName": "Developers Team",
"members": [
{
"value": "2819c223-7f76-453a-919d-413861904646",
"display": "Alice Martin"
}
]
}

Deux lignes de ce tableau méritent votre attention. PUT remplace l'objet entier : tout attribut absent de la charge utile est effacé côté application, ce qui écrase parfois des données que l'IdP ne connaît pas. PATCH ne touche que les chemins listés, c'est donc l'opération à privilégier pour un changement ciblé comme une désactivation. Quant à DELETE, il est marqué « rare » à dessein : la plupart des intégrations ne l'utilisent jamais.

OpérationMéthode HTTPEndpointUsage
CréerPOST/UsersNouvel employé
LireGET/Users/{id}Vérifier un compte
ListerGET/Users?filter=...Rechercher des utilisateurs
ModifierPUT/Users/{id}Remplacement complet
Modifier partiellementPATCH/Users/{id}Modification ciblée
SupprimerDELETE/Users/{id}Suppression (rare)

Les trois échanges ci-dessous suffisent à couvrir 90 % d'une intégration réelle. Un détail les relie : le type de contenu application/scim+json, exigé par la RFC 7644. Beaucoup d'applications renvoient une erreur 415 Unsupported Media Type si vous envoyez un simple application/json, et c'est la première chose à vérifier quand un provisioning échoue sans message clair.

Créer un utilisateur :

Fenêtre de terminal
POST /scim/v2/Users
Content-Type: application/scim+json
Authorization: Bearer <token>
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "alice.martin@example.com",
"name": {
"givenName": "Alice",
"familyName": "Martin"
},
"emails": [{"value": "alice.martin@example.com", "primary": true}],
"active": true
}

Désactiver un utilisateur (PATCH) :

Fenêtre de terminal
PATCH /scim/v2/Users/2819c223-7f76-453a-919d-413861904646
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [
{
"op": "replace",
"path": "active",
"value": false
}
]
}

Rechercher des utilisateurs :

Fenêtre de terminal
GET /scim/v2/Users?filter=userName eq "alice.martin@example.com"

Les trois moments qui suivent portent un nom dans le vocabulaire IAM : Joiner, Mover, Leaver. C'est le même flux de données à chaque fois, seule l'opération SCIM change. Le point de départ est toujours le système RH, jamais l'IdP : si un compte est créé directement dans l'annuaire, il sortira du cycle et deviendra un compte orphelin.

L'étape 4 est celle qu'on oublie de vérifier. Tant que l'IdP n'a pas mémorisé le id retourné par l'application, il ne pourra ni modifier ni désactiver ce compte plus tard. Un onboarding qui « fonctionne » mais dont la réponse n'a pas été enregistrée produit un compte que personne ne pourra fermer au départ du collaborateur.

  1. Création dans l'IdP

    Le RH crée l'utilisateur dans le système source (AD, Workday, HR system).

  2. Synchronisation vers l'IdP

    L'IdP central (Keycloak, Okta) reçoit l'utilisateur.

  3. Provisioning SCIM

    L'IdP pousse l'utilisateur vers les applications configurées.

  4. Confirmation

    Chaque application retourne un id SCIM que l'IdP stocke pour les futures mises à jour.

Le changement de poste est le scénario le plus mal traité en pratique, parce qu'il exige un retrait de droits, pas seulement un ajout. Un PATCH qui ajoute le nouveau groupe sans retirer l'ancien laisse la personne cumuler les accès de ses deux postes. Au bout de quelques mobilités internes, ce cumul donne des comptes plus privilégiés que ceux des administrateurs.

  1. Modification des groupes dans l'IdP

    L'utilisateur change d'équipe, ses groupes sont mis à jour.

  2. PATCH SCIM vers les applications

    L'IdP envoie les modifications de groupes.

  3. Mise à jour des permissions

    L'application ajuste les accès selon les nouveaux groupes.

Suivez bien l'ordre des quatre étapes : elles vont de la source vers les extrémités. La désactivation dans l'IdP ne coupe rien toute seule, elle ne fait que déclencher les PATCH vers les applications. C'est l'étape 3, la révocation des tokens, qui met réellement fin aux accès en cours, et c'est justement celle que beaucoup d'applications n'implémentent pas.

  1. Désactivation dans l'IdP

    Le compte est marqué active: false dans l'IdP.

  2. PATCH SCIM : désactiver

    L'IdP envoie { "active": false } à toutes les applications.

  3. Révocation des tokens

    Les applications invalident les sessions et tokens existants.

  4. Blocage des logins

    L'IdP refuse toute nouvelle authentification.

Un offboarding est dit propre quand aucune des cinq garanties ci-dessous ne manque. Le critère de validation est simple à énoncer et rarement testé : quelques minutes après la désactivation dans l'IdP, plus aucune requête authentifiée au nom de cette personne ne doit aboutir, ni depuis un navigateur déjà ouvert, ni depuis un jeton d'API encore valide.

  1. Le compte est désactivé (plus de nouveaux logins)
  2. Les sessions actives sont terminées
  3. Les tokens (access, refresh) sont révoqués
  4. Les accès API sont bloqués
  5. Les données sont conservées ou archivées selon la politique

Le tableau se lit en colonnes : la partie gauche est ce que l'IdP déclenche, la partie droite ce que l'application doit effectivement faire pour que la promesse tienne. Le N/A de la ligne 2 n'est pas un détail : SCIM n'a aucune opération pour tuer une session. Si l'application ne coupe pas ses sessions d'elle-même à la réception de active: false, la personne reste connectée jusqu'à expiration naturelle du cookie.

ÉtapeAction IdPAction Application
1. Désactivationactive: false dans l'IdPSCIM PATCH reçu
2. SessionsN/AInvalider toutes les sessions du user
3. TokensRévoquer les refresh tokensSupprimer les tokens stockés
4. AuditLogger le deprovisioningLogger la désactivation

Le sort des données de la personne partie ne se décide pas au cas par cas au moment du départ : c'est une politique écrite à l'avance, sinon chaque offboarding devient une négociation. Les trois options ci-dessous s'excluent rarement, elles se combinent le plus souvent par type de donnée : conserver les traces d'audit, anonymiser les données personnelles au titre du RGPD, supprimer les brouillons personnels sans valeur.

OptionQuand l'utiliser
ConserverConformité, historique, audit
AnonymiserRGPD, données personnelles
SupprimerDemande explicite, données non critiques

Ces cinq pièges se manifestent tous à la conception de l'intégration, pas à l'exploitation. Ils se traitent donc avant la mise en production, dans l'ordre du tableau : commencez par vérifier que l'application supporte réellement SCIM (beaucoup annoncent « SSO » sans provisioning), puis validez le mapping des identifiants, puis seulement testez les scénarios. Les erreurs de la section suivante, elles, apparaissent une fois le système en service.

PiègeConséquenceSolution
L'app ne supporte pas SCIMProvisioning manuelVérifier avant intégration
externalId vs id confondusÉchec des mises à jourexternalId = IdP, id = application
DELETE au lieu de désactiverPerte d'historiqueToujours préférer active: false
Pas de révocation des sessionsAccès persistant après départImplémenter la révocation côté app
Mapping d'attributs incorrectDonnées manquantesTester le mapping en pre-prod

Keycloak ne supporte pas SCIM nativement, ni comme client ni comme serveur. C'est le principal écart fonctionnel avec les IdP commerciaux, et il se comble par une extension communautaire. Le choix n'est pas neutre : vous confiez le cycle de vie de vos comptes à un composant tiers dont le rythme de mise à jour ne suit pas forcément celui de Keycloak. Vérifiez sa compatibilité avec votre version avant chaque montée de version majeure.

L'installation passe par le mécanisme de providers de Keycloak : un fichier JAR déposé dans /opt/keycloak/providers/, puis un kc.sh build qui reconstruit l'image de démarrage. Ce build est obligatoire, un simple redémarrage ne charge pas l'extension. Sur un Keycloak déployé en conteneur, la conséquence pratique est qu'il faut reconstruire l'image ou monter le JAR dans un volume persistant, sinon l'extension disparaît au prochain redéploiement.

  1. Installer l'extension

    Fenêtre de terminal
    # Ajouter le provider SCIM à Keycloak
    cp scim-for-keycloak.jar /opt/keycloak/providers/
    /opt/keycloak/bin/kc.sh build
  2. Configurer le endpoint SCIM

    Dans Keycloak Admin → Realm Settings → SCIM

  3. Configurer l'application cliente

    Entrer l'URL SCIM de l'application et le token d'authentification

  4. Tester le provisioning

    Créer un utilisateur dans Keycloak et vérifier sa création dans l'application

Ces IdP intègrent SCIM nativement, ce qui déplace la difficulté : le protocole n'est plus le sujet, le mapping des attributs le devient. C'est l'étape 4 qui prend le plus de temps, parce que chaque application attend ses champs sous un nom qui lui est propre. Passer par le catalogue d'applications plutôt que par une configuration SCIM générique vous évite ce travail : le connecteur embarque déjà le mapping validé par l'éditeur.

  1. Ajouter l'application depuis le catalogue
  2. Activer le provisioning
  3. Entrer l'URL SCIM et le token de l'application
  4. Mapper les attributs
  5. Tester

Le critère de choix n'est pas la qualité technique de chaque approche, c'est ce que l'application en face sait faire. Lisez la dernière colonne en premier : elle vous dit dans quel monde vous êtes. Une seule ligne devrait vous alerter, celle du JIT seul : sans deprovisioning, elle vous garantit des comptes orphelins à terme, et doit donc s'accompagner d'une revue d'accès périodique manuelle.

ApprocheAvantagesInconvénientsUsage
SCIMStandard, temps réel, deprovisioningL'app doit le supporterSaaS modernes
JIT (SSO)Simple, pas de configPas de deprovisioningApps sans SCIM
LDAP syncRobuste, maturePlus complexe, pollingApps on-prem
API customFlexibleSur-mesure, maintenanceLegacy, cas spéciaux

Contrairement aux pièges de conception vus plus haut, ces quatre erreurs surviennent une fois l'intégration en service, et elles ont un point commun : elles ne produisent aucun message d'erreur visible. Un provisioning SCIM qui échoue le fait silencieusement, du côté de l'IdP, sur un compte qui n'existe pas encore et que personne ne cherche. D'où la ligne « Pas de monitoring » : sans alerte sur les échecs SCIM, vous découvrez le problème le jour d'un audit.

ErreurConséquenceSolution
Pas de test de deprovisioningComptes orphelins au premier départTester le flow complet en pre-prod
Token SCIM en clairCompromission possibleStocker dans un vault
Pas de monitoringÉchecs silencieuxAlerter sur les erreurs SCIM
Mapping incompletAttributs manquantsDocumenter et valider le mapping

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn