SCIM 2.0 : provisionner les utilisateurs et les groupes
Sur cette page
À partir de la version 3.38.0, TOSIAM est un fournisseur de service SCIM 2.0 (RFC 7643 et RFC 7644). Un outil de gestion des identités, comme TOSIDM, Microsoft Entra ID ou Okta, crée, modifie, désactive et supprime les utilisateurs et les groupes d’un royaume.
Les écritures passent par les dépôts d’identités, jamais directement par l’annuaire. Les caches et les notifications aux autres serveurs du site restent donc justes, et un utilisateur désactivé perd ses accès en cours, voir Désactivation d’un compte et révocation des accès.
1. Activer SCIM dans un royaume#
SCIM est désactivé par défaut. Il faut trois choses, dans le royaume.
Un client OAuth2 autorisé à utiliser le flux client_credentials avec la portée tosiam:scim. Sa durée de vie de jeton se règle sur le client.
Un compte de service : un utilisateur actif du royaume, qui n’est pas un super-utilisateur, et qui a le privilège de délégation RealmAdmin, directement ou par l’un de ses groupes. Ses droits viennent de la délégation, jamais du client ni du jeton.
Le service ScimService du royaume :
| Réglage (API) | Rôle | Défaut |
|---|---|---|
enabled | Active SCIM | false |
clients | Clients OAuth2 acceptés | aucun |
serviceAccount | Compte de service | aucun |
userMapping | Attributs des utilisateurs | voir section 4 |
groupMapping | Attributs des groupes | voir section 4 |
idAttribute | Attribut de l’id | entryUUID |
indexedAttributes | Attributs avec un index d’égalité | uid, mail, cn, uniqueMember |
substringAttributes | Attributs avec un index de sous-chaîne | aucun |
searchWindow | Résultats qu’une recherche peut parcourir | 1000 |
curl -X POST "$TOSIAM/api/realms/clients/realm-config/services/ScimService" \
-H 'Content-Type: application/vnd.tosiam+json' -H "X-XSRF-TOKEN: $XSRF" -b cookies.txt \
-d '{"enabled": true, "clients": ["idm"], "serviceAccount": "scim-service"}'Le client obtient ensuite un jeton, et le présente à chaque requête :
curl -u idm:secret "$TOSIAM/oauth2/clients/access_token" \
-d grant_type=client_credentials -d scope=tosiam:scim
curl "$TOSIAM/scim/v2/realms/clients/Users?filter=userName%20eq%20%22bjensen%22" \
-H "Authorization: Bearer $TOKEN"L’URL de locataire à donner à l’outil est /scim/v2/realms/{royaume}. root désigne le royaume racine, et : sépare les sous-royaumes (clients:mobile).
Un outil qui ne sait qu’envoyer un en-tête fixe, comme Okta, reçoit un jeton obtenu à la main : donnez alors au client une durée de vie de jeton adaptée, et prévoyez son renouvellement.
Un jeton révoqué est refusé à la requête suivante. Un retrait de délégation, ou un compte de service désactivé, prend effet en 30 secondes au plus.
Les jetons des agents IA sont refusés, même si leur client est listé.
SCIM lit les administrateurs, mais ne les écrit pas. Les utilisateurs et les groupes qui portent un privilège de délégation, les membres de ces groupes et le compte de service répondent 403 à
PUT,PATCHetDELETE, et leur nom ne peut pas être recréé. Un client volé ne peut donc ni changer le mot de passe d’un administrateur, ni rejoindre un groupe privilégié. Gérez ces comptes par la console ou par/api. Un nouvel administrateur est protégé en 30 secondes au plus.
2. Points d’accès#
| Point d’accès | Opérations |
|---|---|
/Users, /Groups | GET (recherche), POST |
/Users/{id}, /Groups/{id} | GET, PUT, PATCH, DELETE |
/ServiceProviderConfig, /ResourceTypes, /Schemas | GET |
La recherche accepte filter, startIndex, count (200 au plus), attributes et excludedAttributes. meta.version est un ETag : If-Match protège une écriture (412), If-None-Match une lecture (304).
/Bulk, /Me et le tri ne sont pas pris en charge, comme l’annonce /ServiceProviderConfig.
Les schémas sont User, EnterpriseUser (dont manager) et Group. id est opaque et stable. Il vient de entryUUID.
Quand un PUT omet un attribut, celui-ci est vidé, sauf le mot de passe, le statut (active), et cn et sn, que l’annuaire exige. Sans members, un PUT sur un groupe ne change pas ses membres. Le mot de passe n’est jamais renvoyé.
3. Filtres et index#
Un filtre qu’aucun index ne peut servir est refusé par invalidFilter, avant toute recherche. Une liste sans filtre lit au plus searchWindow entrées, à chaque page : réservez-la aux petits annuaires ou aux tests de connexion.
| Forme | Acceptée si |
|---|---|
attr eq "v" | attr a un index d’égalité (indexedAttributes) |
attr sw "v" | attr a un index de sous-chaîne (substringAttributes) |
a and b | l’un des deux est accepté seul |
a or b | les deux sont acceptés seuls |
ne, co, pr, gt, ge, lt, le, not | seulement sous un and accepté |
ew | jamais |
id est toujours accepté. password ne l’est jamais.
userName eq "bjensen" accepté
userName eq "bjensen" and active eq true accepté
id eq "..." and members[value eq "..."] accepté
active eq true refusé : pas d'index
userName co "jen" refusé : pas d'indexPour filtrer sur un autre attribut, par exemple externalId, créez l’index dans l’annuaire, puis ajoutez l’attribut à indexedAttributes.
Les listes par défaut sont celles que TosDJ et OpenLDAP indexent tous les deux. Vérifiez-les sur un annuaire existant : sur OpenLDAP, entryUUID, uid, cn, mail et uniqueMember doivent avoir olcDbIndex ... eq. TosDJ a aussi des index de sous-chaîne : pour autoriser sw, ajoutez par exemple uid, cn et mail à substringAttributes.
4. Correspondance des attributs#
userMapping et groupMapping sont des lignes cheminScim=attribut. Un attribut sensible, comme userPassword hors du chemin password ou unicodePwd, est ignoré et signalé dans les journaux. La valeur par défaut convient à TosDJ et à OpenLDAP, sans schéma à ajouter :
| SCIM | Annuaire |
|---|---|
userName | uid |
externalId | sunIdentityServerPPLegalIdentityAltIdValue |
displayName | cn |
name.givenName, name.familyName | givenName, sn |
title | sunIdentityServerPPEmploymentIdentityJobTitle |
preferredLanguage, locale, timezone | preferredlanguage, preferredLocale, preferredtimezone |
active | inetUserStatus |
password | userPassword |
emails.value | mail |
phoneNumbers.value | telephoneNumber |
addresses.formatted | postalAddress |
employeeNumber, organization (entreprise) | employeeNumber, sunIdentityServerPPEmploymentIdentityOrg |
manager.value (entreprise) | manager |
displayName (groupe) | cn |
externalId (groupe) | description |
members.value (groupe) | uniqueMember |
Un chemin d’extension s’écrit avec son URN : urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber=employeeNumber.
Un attribut doit figurer dans la liste des attributs du data store, sinon le dépôt l’abandonne sans erreur. SCIM le signale alors dans les journaux, au niveau ERROR. Sur un data store créé avant la 3.38.0, ajoutez
descriptionaux attributs des groupes pour conserver l’externalIdd’un groupe.
5. Plusieurs dépôts d’identités#
Un royaume est vu comme le serveur le voit : une recherche interroge chaque dépôt et combine les résultats, et une création va dans le dépôt que le serveur choisit. SCIM n’a pas de réglage de dépôt cible.
6. Audit#
Chaque écriture produit un événement d’activité AM-IDENTITY-CHANGED, avec l’identité écrite, le compte de service en runAs, et dans after le client, l’identifiant d’audit du jeton et les noms des attributs écrits, jamais leurs valeurs.
7. Limites#
| Limite | Conséquence |
|---|---|
userName et le displayName d’un groupe sont immuables | Ils nomment l’entrée de l’annuaire : un changement est refusé (400, mutability). Avec Entra ID, un changement d’UPN échoue donc |
searchWindow résultats parcourables | Au-delà, le client reçoit tooMany : il doit filtrer. Une fin de liste n’est jamais silencieuse |
Un groupe de plus de searchWindow membres | Lu seulement avec excludedAttributes=members, jamais en partie |
| Active Directory | Non pris en charge : son objectGUID est binaire |
type et primary de emails et phoneNumbers | Non conservés : type vaut work, et primary désigne la première valeur |
| Groupes imbriqués | Refusés : un membre doit être un utilisateur |
| Noms | Ni =, ni *, ni caractère invisible dans un userName ou le displayName d’un groupe (400) |
| Annuaire partagé entre royaumes | SCIM ne lit que la délégation du royaume de l’URL : une écriture dans un sous-royaume peut toucher un administrateur du royaume parent. N’activez pas SCIM sur un tel royaume |
Mis à jour le