Utilisateurs et profils
Le modèle de profil d'annuaire, qui peut éditer quels champs, les claims OIDC correspondants, le cycle de vie du compte et le libre-service RGPD.
Chaque utilisateur de votre organisation porte un profil d'annuaire compact et délibéré. Cette page décrit les champs, qui les écrit, comment ils apparaissent dans les jetons, et les opérations de cycle de vie qu'un administrateur (ou SCIM) applique au compte.
Le modèle de profil
| Champ | Clé API | Claim OIDC | Attribut SCIM |
|---|---|---|---|
| Prénom | givenName | given_name | name.givenName |
| Nom | familyName | family_name | name.familyName |
| Nom d'affichage | displayName | name | displayName |
| Poste | jobTitle | (aucun) | title |
| Département | department | (aucun) | extension entreprise department |
| Langue | locale | locale | locale |
Tous les champs sont optionnels. Le nom d'affichage effectif est calculé partout par la même règle (API, OIDC, SCIM) : le nom d'affichage explicite s'il est renseigné, sinon « Prénom Nom » si au moins l'un des deux existe, sinon l'adresse e-mail. locale est une étiquette RFC 5646 (fr, en, en-US).
Il n'y a volontairement pas de champ date de naissance. Obexal applique la minimisation des données du RGPD : un IdP n'en a pas besoin pour authentifier qui que ce soit.
Qui édite quoi
L'annuaire appartient à l'organisation. Les champs de profil sont écrits par un admin ou par le SCIM entrant ; l'employé les consulte en lecture seule via GET /v1/auth/me. Il n'existe aucun endpoint d'écriture en libre-service (pas de PATCH /v1/me/profile). Seule exception : à l'activation de l'invitation, l'invité peut poser ou compléter son prénom et son nom.
Un admin édite le profil avec PUT /v1/admin/users/{userId} (permission de gestion des membres). La requête remplace tous les champs : un champ omis ou vide est effacé.
curl -sS -X PUT https://accounts.obexal.com/v1/admin/users/<userId> \
-H "Authorization: Bearer $OBEXAL_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"givenName":"Alice","familyName":"Martin","displayName":"","jobTitle":"DAF","department":"Finance","locale":"fr"}'
# 200 -> {"status":"ok"} (événement d'audit : user.profile_updated)L'adresse e-mail est l'identité d'entreprise du compte : l'employé ne peut pas la changer lui-même (l'endpoint en libre-service répond 403 email_change_forbidden par défaut). Le changement d'e-mail passe par un admin ou par SCIM. La liste complète de l'annuaire est disponible sur GET /v1/admin/users.
Les claims de profil dans les jetons
Avec le scope profile, l'id_token et /oauth/userinfo portent given_name, family_name, name (le nom d'affichage calculé, omis s'il ne ferait que répéter l'e-mail) et locale, chacun émis seulement s'il est renseigné. Avec le scope email : email et email_verified.
Le poste et le département ne sont pas des claims OIDC standard : ils ne sont pas émis dans les jetons ; ils sont exposés via SCIM (title et l'extension entreprise). L'appartenance aux groupes apparaît dans un claim groups : voir Groupes et accès aux apps.
Cycle de vie du compte
Les opérations de cycle de vie sont des actions d'admin, chacune tracée dans le journal d'audit :
| Opération | Endpoint | Effet |
|---|---|---|
| Suspendre | POST /v1/admin/users/{userId}/suspend | Statut deactivated, toutes les sessions révoquées, connexion refusée |
| Réactiver | POST /v1/admin/users/{userId}/reactivate | Statut de retour à active |
| Déconnexion forcée | POST /v1/admin/users/{userId}/logout | Toutes les sessions révoquées, compte toujours actif |
| Déverrouiller | POST /v1/admin/users/unlock | Lève le verrou anti-bruteforce pour {"email":"..."} |
La suspension accepte un corps JSON optionnel {"reason":"offboarding"}, conservé dans l'audit. Deux gardes s'appliquent : seul un owner peut suspendre un owner, et le dernier owner d'une organisation ne peut jamais être suspendu.
curl -sS -X POST https://accounts.obexal.com/v1/admin/users/<userId>/suspend \
-H "Authorization: Bearer $OBEXAL_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"reason":"offboarding"}'
# 200 -> {"status":"ok"} (événement d'audit : admin.user.suspended)Si le provisioning SCIM sortant est configuré, la suspension désactive automatiquement le compte sur toutes les cibles aval, et la réactivation le repousse.
Retirer un membre avec DELETE /v1/admin/members/{userId} retire seulement son rôle dans l'organisation ; cela ne suspend ni ne supprime le compte.
Export et suppression RGPD
Un utilisateur connecté peut exporter ses données à tout moment (droit à la portabilité) : GET /v1/auth/account/export renvoie une pièce jointe JSON avec le profil public, les identités fédérées liées et les métadonnées des facteurs MFA. Elle ne contient jamais de secret (ni hash de mot de passe, ni graine TOTP). L'export est audité (auth.account.exported).
La suppression de compte en libre-service existe (POST /v1/auth/account/delete, avec ré-authentification par mot de passe, ou par confirmation de l'e-mail exact pour les comptes sans mot de passe) mais elle est désactivée par défaut : dans un annuaire géré, le cycle de vie du compte appartient à l'organisation, et l'endpoint répond 403 account_delete_forbidden. Les déploiements auto-hébergés servant des tenants grand public peuvent l'activer : voir Configuration. Quand elle s'exécute, la suppression révoque toutes les sessions et efface le compte définitivement ; l'entrée d'audit ne conserve que l'identifiant de l'utilisateur, jamais l'e-mail. Voir RGPD pour la vue d'ensemble.