☁️Entra IDIdentityMonitoring

Compte Entra ID Désactivé, Toujours Connecté, Révoquer Sessions : la faille du processus de départ

Désactiver un compte Entra ID ne met pas fin à une session active. Voici l'écart entre synchronisation hybride, jetons et CAE derrière ce problème, et comment le combler.

Younes AZABARPar Younes AZABAR11 min de lecture
Compte Entra ID Désactivé, Toujours Connecté, Révoquer Sessions : la faille du processus de départ

Compte Entra ID Désactivé, Toujours Connecté, Révoquer Sessions : Ce Que Chaque Terme Signifie Vraiment

Si vous avez cherché compte entra id désactivé toujours connecté révoquer sessions, vous avez déjà la conclusion : désactiver le compte d'un employé parti ne met pas fin, en soi, à son accès à Microsoft 365. L'écart entre « désactivé » et « déconnecté » n'est pas un bug — c'est le comportement documenté et voulu de trois systèmes distincts, qu'un processus de départ classique suppose reliés entre eux alors qu'ils ne le sont pas réellement.

Deux indicateurs sont constamment confondus. Active Directory sur site possède userAccountControl avec le bit ACCOUNTDISABLE (0x2) — celui qu'un technicien du support bascule avec Disable-ADAccount. Microsoft Entra ID possède sa propre propriété accountEnabled, distincte, sur l'objet utilisateur, exposée via Microsoft Graph et modifiable avec Update-MgUser -AccountEnabled:$false. Ce sont deux attributs dans deux annuaires, reliés uniquement par le processus de synchronisation hybride qui s'exécute entre eux. Désactiver le compte on-premise ne change rien dans Entra ID tant que cette synchronisation n'a pas tourné — et même après, « compte désactivé » et « session terminée » restent deux événements distincts dans l'architecture propre de Microsoft.

Comment ça marche : les trois écarts entre « désactivé » et « déconnecté »

Écart 1 — le délai de synchronisation hybride

Si le processus de départ démarre on-premise, la désactivation doit atteindre Entra ID avant que quoi que ce soit en aval puisse réagir. Microsoft Entra Connect Sync s'exécute sur un planificateur dont la fréquence de synchronisation par défaut est de 30 minutes pour l'import, la synchronisation et l'export. Rien dans Entra ID ne voit la désactivation avant ce cycle — un compte désactivé à 9h01 est, du point de vue du cloud, toujours pleinement actif jusqu'au prochain passage planifié, à moins que quelqu'un ne déclenche manuellement Start-ADSyncSyncCycle -PolicyType Delta.

Écart 2 — la désactivation ne révoque pas les jetons déjà émis

Une fois qu'accountEnabled bascule bien à false dans Entra ID, le refresh token déjà émis à l'utilisateur n'est pas invalidé automatiquement. La documentation Microsoft sur les refresh tokens liste précisément les événements qui révoquent un refresh token : changement de mot de passe, SSPR, réinitialisation de mot de passe par un administrateur, révocation explicite des sessions par un utilisateur ou un administrateur, ou déconnexion unique (single sign-out). La désactivation du compte ne figure pas parmi ces lignes. Les refresh tokens ont par défaut une durée de vie de 90 jours, et un access token déjà émis est un artefact signé et autonome qu'un fournisseur de ressources considère valide jusqu'à son expiration propre — un délai aléatoire de 60 à 90 minutes, 75 en moyenne — à moins que quelque chose ne revérifie entre-temps auprès d'Entra ID. Dans une session compatible CAE, cette fenêtre est beaucoup plus large, pas plus étroite : Microsoft émet des jetons longue durée allant jusqu'à 28 heures, partant du principe que la révocation sera pilotée par des événements critiques plutôt que par l'horloge.

Cette « revérification » est précisément le rôle de l'évaluation continue des accès (CAE) — et c'est aussi là que se situe le troisième écart.

Écart 3 — le CAE comble cet écart, mais seulement pour certaines applications, et pas instantanément

La liste des événements critiques du CAE inclut explicitement « le compte utilisateur est supprimé ou désactivé », aux côtés d'un changement ou d'une réinitialisation de mot de passe, de l'activation de l'authentification multifacteur pour l'utilisateur, d'une révocation explicite de tous les refresh tokens par un administrateur, et d'un risque utilisateur élevé détecté par Microsoft Entra ID Protection. L'évaluation des événements critiques « ne dépend pas des stratégies d'accès conditionnel, elle est donc disponible dans n'importe quel tenant » — aucune licence Accès conditionnel n'est requise pour cette partie. Mais trois limites comptent pour un scénario de départ :

  • Microsoft indique que l'objectif est le quasi temps réel, « mais une latence pouvant aller jusqu'à 15 minutes peut être observée en raison du temps de propagation des événements ».
  • L'implémentation initiale « se concentre sur Exchange, Teams et SharePoint Online » — pas sur toutes les applications pour lesquelles un employé parti pourrait encore détenir un jeton.
  • « Le CAE ne prend pas en charge les comptes d'utilisateurs invités » du tout — les événements de révocation et l'accès conditionnel basé sur l'IP ne sont pas appliqués instantanément pour les invités.

Le cas inverse a sa propre latence, qui compte pour le scénario du « mauvais employé » ou de la désactivation accidentelle plutôt que pour le départ : Microsoft documente que réactiver un utilisateur juste après l'avoir désactivé n'est pas instantané non plus — SharePoint Online et Teams ont « généralement un délai de 15 minutes », et Exchange Online a « généralement un délai de 35 à 40 minutes », avant que les services en aval ne reconnaissent le compte comme réactivé.

En cumulant les trois écarts, la réponse honnête à « combien de temps un compte désactivé peut-il rester connecté » est : au moins le délai de synchronisation restant, plus jusqu'à 15 minutes pour que le CAE rattrape son retard — si l'application est compatible CAE, et si l'utilisateur n'est pas un invité. En dehors de ces conditions, l'access token épuise simplement son propre délai.

L'écart du processus de départ dans la pratique

Ce n'est pas un cas théorique — c'est le résultat par défaut de l'automatisation de désengagement recommandée par Microsoft elle-même. Le modèle intégré « Offboard an employee » de Lifecycle Workflows exécute par défaut exactement trois tâches : Disable User Account, Remove user from all groups, Remove user from all Teams. Une tâche distincte, « Revoke all refresh tokens for user », existe dans le catalogue de tâches de Lifecycle Workflows pour les catégories Leaver et Mover — mais elle ne fait pas partie du modèle par défaut. Une organisation qui exécute le workflow de désengagement prêt à l'emploi désactive le compte et s'arrête là.

La même asymétrie apparaît dans la logique ordinaire de contrôle de session : comme évoqué dans Contrôles de session d'accès conditionnel, fréquence de connexion et emplacements nommés, un contrôle de session décrit ce qui se passe la prochaine fois qu'une session est évaluée — il « n'atteint pas un access token déjà émis pour le reprendre ». Désactiver un compte est, fonctionnellement, le même type de contrôle tourné vers l'avenir, à moins que le CAE ou une révocation explicite ne vienne s'y ajouter.

C'est aussi le miroir d'un problème très différent déjà couvert dans le catalogue : la détection du rejeu de jeton AiTM et des déplacements impossibles concerne une session volée par un attaquant qui survit aux contrôles censés l'arrêter. Ici, c'est la propre session d'un ancien employé légitime qui survit au contrôle censé y mettre fin. Même mécanisme sous-jacent — un jeton actif que personne n'a explicitement tué — mais un acteur différent.

Détection

Quatre signaux couvrent des tranches différentes de cet écart. Tous sont interrogeables via Microsoft Graph ; la lecture de signInActivity nécessite une licence Microsoft Entra ID P1 ou P2 ainsi que les permissions AuditLog.Read.All et User.Read.All, selon les recommandations de Microsoft sur les comptes inactifs. Si le tenant paie déjà pour une licence de niveau P2, la même licence débloque aussi le déclencheur CAE basé sur le risque d'Identity Protection ainsi que les revues d'accès — tous deux directement utiles pour combler cet écart, et tous deux souvent laissés non configurés même une fois la licence attribuée. Comme pour d'autres détections pilotées par Identity Protection, ces déclencheurs restent inertes tant que personne ne les active : voir Azure Identity Protection : bloquer les identifiants divulgués pour un exemple comparable de fonctionnalité payée mais dormante.

SignalCe qu'il trouveModèle de requête Graph
USER_DISABLED_NOT_BLOCKEDTous les comptes avec accountEnabled: false — la population dans laquelle cet écart peut existerGET /users?$filter=accountEnabled eq false
USER_STALE_90_DAYSAucune activité de connexion — interactive ou non interactive — depuis 90 jours ou plus sur un compte toujours activé, la borne basse de la « fenêtre raisonnable... entre 90 et 180 jours » définie par Microsoft elle-même pour l'inactivitéGET /users?$filter=signInActivity/lastSuccessfulSignInDateTime le {date-90d}
USER_NEVER_SIGNED_INsignInActivity présent mais vide — un compte provisionné et jamais utilisé, ou utilisé uniquement avant le début de la rétention des journaux de connexion interactive d'Entra ID (avril 2020)GET /users?$select=displayName,signInActivity, filtré sur un lastSignInDateTime nul
USER_NO_MANAGERAucune relation manager définie sur l'objet utilisateur — casse tout déclencheur de départ qui dépend d'une action ou d'une notification du managerGET /users/{id}/manager

Remediation / Remédiation

  1. Faites de la désactivation et de la révocation une seule et même étape, pas deux. Ne désactivez jamais un utilisateur sans invalider aussi ses jetons dans la même action :

    Import-Module Microsoft.Graph.Users
    Import-Module Microsoft.Graph.Users.Actions
    
    Connect-MgGraph -Scopes "User.EnableDisableAccount.All","User.RevokeSessions.All"
    
    Update-MgUser -UserId $userId -AccountEnabled:$false
    Revoke-MgUserSignInSession -UserId $userId
    

    Ces deux scopes sont les moins privilégiés que Microsoft documente pour ces deux appels ; sans la ligne Connect-MgGraph, les deux cmdlets échouent avec une erreur d'authentification. Notez les deux-points dans -AccountEnabled:$false — c'est un paramètre switch, donc la forme avec deux-points est la seule façon de le mettre à false. Revoke-MgUserSignInSession invalide chaque refresh token et cookie de session navigateur émis à l'utilisateur, avec la mise en garde documentée par Microsoft selon laquelle « il peut y avoir un petit délai de quelques minutes avant que les jetons ne soient révoqués » — et elle ne révoque pas les sessions des utilisateurs externes/invités, qui s'authentifient via leur tenant d'origine.

  2. Ajoutez la tâche manquante dans Lifecycle Workflows. Si le désengagement passe par le modèle intégré « Offboard an employee », ajoutez explicitement la tâche « Revoke all refresh tokens for user » — elle est disponible pour la catégorie Leaver mais n'est pas câblée par défaut.

  3. Vérifiez que l'évaluation continue des accès est activée — ne supposez pas qu'il faut l'activer. Le CAE basé sur les événements critiques ne nécessite aucune licence Accès conditionnel, et selon le tableau de migration de Microsoft, les nouveaux tenants sont activés automatiquement. Deux groupes ne le sont pas : les tenants qui avaient limité l'ancienne préversion à certains utilisateurs, et les tenants qui l'avaient explicitement désactivée. Migrer l'un ou l'autre positionne le nouveau contrôle de session Personnaliser l'évaluation continue des accès sur Désactivé — ces tenants fonctionnent donc sans CAE tout en pensant l'avoir. Vérifiez ce contrôle plutôt que de faire confiance à la valeur par défaut. Le CAE ne comblera pas l'Écart 1 (le délai de synchronisation) ni l'angle mort des comptes invités, mais il comble automatiquement la plus grande partie des Écarts 2/3, dans la fenêtre documentée d'environ 15 minutes, pour les sessions Exchange, SharePoint et Teams.

  4. Ne laissez pas le processus de départ attendre le planificateur de synchronisation. Pour un licenciement, exécutez Start-ADSyncSyncCycle -PolicyType Delta dans le même runbook plutôt que d'attendre jusqu'à 30 minutes le prochain cycle planifié — ou, mieux, exécutez la désactivation et la révocation directement sur Entra ID via Graph en premier, et laissez Active Directory on-premise rattraper son propre calendrier.

  5. Comblez les lacunes de gouvernance qui laissent cela passer inaperçu. L'absence de manager (USER_NO_MANAGER) casse le déclencheur qui aurait dû lancer le désengagement en premier lieu — la même discipline de gouvernance s'applique aux comptes invités non gouvernés qui n'obtiennent jamais de propriétaire ni de revue non plus. Exécutez les quatre détecteurs ci-dessus sur un planning, pas seulement au moment du départ : USER_STALE_90_DAYS et USER_NEVER_SIGNED_IN détectent les comptes que personne n'a jamais pensé à désengager.

Comment EtcSec détecte cela

L'audit Azure Entra ID d'EtcSec vérifie les quatre écarts décrits ci-dessus : USER_DISABLED_NOT_BLOCKED recense les comptes désactivés dont les sessions n'ont jamais été fermées de manière prouvée, USER_STALE_90_DAYS et USER_NEVER_SIGNED_IN révèlent les comptes qu'un processus de départ n'a jamais touchés, et USER_NO_MANAGER trouve les comptes qui échoueront de la même façon la prochaine fois, parce que rien ne déclenchera leur désengagement non plus.

Explorez les pages de sécurité des identités liées à ce sujet