Entra ID Disabled Account, Still Signed In, Revoke Sessions: What Each Term Actually Means
If you searched for entra id disabled account still signed in revoke sessions, you already have the punchline: disabling a departed employee's account does not, by itself, end their access to Microsoft 365. The gap between "disabled" and "signed out" isn't a bug — it's the documented, by-design behavior of three separate systems that a typical leaver process assumes work together, but doesn't actually wire together.
Two flags get confused constantly. On-premises Active Directory has userAccountControl with the ACCOUNTDISABLE bit (0x2) — what a helpdesk technician flips with Disable-ADAccount. Microsoft Entra ID has its own, separate accountEnabled property on the user object, exposed over Microsoft Graph and settable with Update-MgUser -AccountEnabled:$false. These are two attributes in two directories, connected only by whatever hybrid sync process runs between them. Disabling the on-prem account changes nothing in Entra ID until that sync runs — and even after it runs, "account disabled" and "session ended" are still two different events in Microsoft's own architecture.
How It Works: The Three Gaps Between "Disabled" and "Signed Out"
Gap 1 — the hybrid sync delay
If the leaver process starts on-premises, the disable has to reach Entra ID before anything downstream can react to it. Microsoft Entra Connect Sync runs on a scheduler whose default synchronization frequency is 30 minutes for import, sync, and export. Nothing in Entra ID sees the disable until that cycle runs — an account disabled at 9:01 AM is, from the cloud's perspective, still fully enabled until the next scheduled pass, unless someone manually triggers Start-ADSyncSyncCycle -PolicyType Delta.
Gap 2 — disabling doesn't revoke the tokens already issued
Once accountEnabled does flip to false in Entra ID, the user's already-issued refresh token isn't automatically invalidated. Microsoft's own refresh token documentation lists the exact events that revoke a refresh token: password change, SSPR, an admin password reset, a user or admin explicitly revoking sessions, or single sign-out. Account disablement is not one of the rows in that table. Refresh tokens default to a 90-day lifetime, and an already-issued access token is a self-contained, signed artifact a resource provider trusts until it expires on its own — a random 60 to 90 minutes, 75 on average — unless something checks back with Entra ID in the meantime. In a CAE-aware session that window is much wider, not narrower: Microsoft issues long-lived tokens of up to 28 hours on the understanding that revocation will be driven by critical events rather than by the clock.
That "checking back" is what continuous access evaluation (CAE) is for — and it's also where the third gap lives.
Gap 3 — CAE closes this, but only for some apps, and not instantly
CAE's critical-event list explicitly includes "User Account is deleted or disabled," alongside a password being changed or reset, multifactor authentication being enabled for the user, an admin explicitly revoking all refresh tokens, and high user risk detected by Microsoft Entra ID Protection. Critical event evaluation "doesn't rely on Conditional Access policies so it's available in any tenant" — no Conditional Access license is required for this part. But three limits matter for a leaver scenario:
- Microsoft states the goal is near-real-time, "but latency of up to 15 minutes might be observed because of event propagation time."
- The initial implementation "focuses on Exchange, Teams, and SharePoint Online" — not every app a departed employee might still hold a token for.
- "CAE doesn't support Guest user accounts" at all — revocation events and IP-based Conditional Access aren't enforced instantly for guests.
The reverse case has its own latency, which matters for the "wrong employee" or accidental-disable scenario rather than the leaver one: Microsoft documents that re-enabling a user right after disabling it isn't instant either — SharePoint Online and Teams "typically have a 15-minute delay," and Exchange Online "typically has a 35-40 minute delay," before downstream services recognize the account as enabled again.
Stack the three gaps and the honest answer to "how long can a disabled account stay signed in" is: at least the remaining sync delay, plus up to 15 minutes for CAE to catch up — if the app is CAE-aware, and the user isn't a guest. Outside those conditions, the access token simply runs out its own clock.
The Leaver Gap in Practice
This isn't a theoretical edge case — it's the default outcome of Microsoft's own recommended offboarding automation. Lifecycle Workflows' built-in "Offboard an employee" template runs exactly three tasks by default: Disable User Account, Remove user from all groups, Remove user from all Teams. A separate task, "Revoke all refresh tokens for user", exists in the Lifecycle Workflows task catalogue for the Leaver and Mover categories — but it isn't part of the default template. An organization running the out-of-the-box offboarding workflow disables the account and stops there.
The same asymmetry shows up in ordinary session-control thinking: as covered in Conditional Access session controls, sign-in frequency, and named locations, a session control describes what happens the next time a session is evaluated — it "does not reach into an access token that has already been issued and take it back." Disabling an account is, functionally, the same kind of forward-looking control unless CAE or an explicit revoke is layered on top of it.
It's also the mirror image of a very different problem the catalogue already covers: AiTM token replay and impossible-travel detection is about an attacker's stolen session outliving the controls meant to stop it. Here, it's a legitimate former employee's own session outliving the control meant to end it. Same underlying mechanism — a live token nobody explicitly killed — different actor.
Detection
Four signals catch different slices of this gap. All are queryable through Microsoft Graph; reading signInActivity requires a Microsoft Entra ID P1 or P2 license plus the AuditLog.Read.All and User.Read.All permissions, per Microsoft's inactive-account guidance. If the tenant already pays for P2-tier licensing, the same license also unlocks Identity Protection's risk-based CAE trigger and Access Reviews — both directly useful for closing this gap, and both commonly left unconfigured even after the license is assigned.
| Signal | What it finds | Graph query pattern |
|---|---|---|
USER_DISABLED_NOT_BLOCKED | Every account with accountEnabled: false — the population in which this gap can exist at all | GET /users?$filter=accountEnabled eq false |
USER_STALE_90_DAYS | No sign-in activity at all — interactive or non-interactive — for 90+ days on a still-enabled account, the low end of Microsoft's own "reasonable window... between 90 and 180 days" for inactivity | GET /users?$filter=signInActivity/lastSuccessfulSignInDateTime le {date-90d} |
USER_NEVER_SIGNED_IN | signInActivity present but blank — an account provisioned and never used, or used only before Entra ID's interactive sign-in log retention began (April 2020) | GET /users?$select=displayName,signInActivity, filtered for a null lastSignInDateTime |
USER_NO_MANAGER | No manager relationship set on the user object — breaks any leaver trigger that depends on manager action or notification | GET /users/{id}/manager |
Remediation
-
Make disable and revoke the same step, not two. Never disable a user without also invalidating their tokens in the same 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 $userIdThose two scopes are the least-privileged ones Microsoft documents for the two calls; without the
Connect-MgGraphline both cmdlets fail with an authentication error. Note the colon in-AccountEnabled:$false— it's a switch parameter, so the colon form is the only way to set it to false.Revoke-MgUserSignInSessioninvalidates every refresh token and browser session cookie issued to the user, with Microsoft's documented caveat that "there might be a small delay of a few minutes before tokens are revoked" — and it doesn't revoke sessions for external/guest users, who authenticate through their home tenant instead. -
Add the missing Lifecycle Workflows task. If offboarding runs through the built-in "Offboard an employee" template, add the "Revoke all refresh tokens for user" task explicitly — it's available for the Leaver category but isn't wired in by default.
-
Check that continuous access evaluation is on — don't assume you have to switch it on. Critical-event CAE needs no Conditional Access license, and per Microsoft's migration table new tenants are auto-enabled. Two groups are not: tenants that scoped the old preview to some users, and tenants that explicitly disabled it. Migrating either one sets the new Customize continuous access evaluation session control to Disabled, so those tenants are running without it while assuming they aren't. Verify that control rather than trusting the default. CAE won't close Gap 1 (the sync delay) or the guest-account blind spot, but it closes the largest slice of Gap 2/3 automatically, within the documented ~15-minute window, for Exchange, SharePoint, and Teams sessions.
-
Don't let the leaver process wait on the sync scheduler. For an involuntary termination, run
Start-ADSyncSyncCycle -PolicyType Deltaas part of the same runbook instead of waiting up to 30 minutes for the next scheduled cycle — or, better, run the disable and revoke directly against Entra ID via Graph first, and let on-premises AD catch up on its own schedule. -
Close the governance gaps that let this go unnoticed. A missing manager (
USER_NO_MANAGER) breaks the trigger that should have started offboarding in the first place — the same governance discipline applies to ungoverned guest accounts that never get an owner or a review either. Run the four detectors above on a schedule, not only at termination time:USER_STALE_90_DAYSandUSER_NEVER_SIGNED_INcatch the accounts nobody remembered to offboard at all.
How EtcSec Detects This
EtcSec's Azure Entra ID audit checks for all four gaps described above: USER_DISABLED_NOT_BLOCKED enumerates the disabled accounts whose sessions were never provably closed, USER_STALE_90_DAYS and USER_NEVER_SIGNED_IN surface the accounts a leaver process never touched at all, and USER_NO_MANAGER finds the accounts that will fail the same way next time, because nothing will trigger their offboarding either.
Explore the identity security pages that support this topic
