You Clicked “Revoke Sessions.” How Long Until the Token Actually Dies?

You Clicked "Revoke Sessions." How Long Until the Token Actually Dies?

Here’s the scenario that ruins a Tuesday. An account is compromised, your SOC hits Revoke sessions in Entra, and everyone exhales. The playbook says the attacker is out. Except the attacker’s mailbox client keeps syncing for a while, or their session against some newer first-party app hangs on past the point where your incident timeline claims it was dead.

Continuous Access Evaluation is supposed to close that gap. When it works, a revoked token gets challenged in near real time — minutes, not the lifetime of the token. The problem the recent research surfaced, and that Office365ITpros wrote up on 8 September, is that CAE coverage across Microsoft’s own applications isn’t uniform. The marquee workloads honour it. Some of the newer and edge-case first-party apps don’t fully implement it yet. So your real mean-time-to-revoke is only as fast as the least-compliant app in the session.

CAE isn’t broken. Where it’s implemented, it does exactly what it says. But “enabled in a Conditional Access policy” and “enforced everywhere your users go” are two different claims, and the second one is the one your incident response assumes. Here’s how to check what you’ve actually got, in the order I’d do it.

1. Confirm CAE is actually turned on — and understand what the toggle does

CAE lives in the session controls of a Conditional Access policy. If you’ve been running policies for years, or someone disabled it during a troubleshooting session and never turned it back on, you may not have it where you think.

audit.ps1PowerShell
# Requires Microsoft.Graph.Identity.SignIns
# Read-only inventory of which CA policies carry the CAE session control
Connect-MgGraph -Scopes 'Policy.Read.All' -NoWelcometry {
    $policies = Get-MgIdentityConditionalAccessPolicy -All -ErrorAction Stop
}
catch {
    Write-Error "Could not read CA policies: $($_.Exception.Message)"
    return
}$policies | ForEach-Object {
    [pscustomobject]@{
        Name         = $_.DisplayName
        State        = $_.State
        CaeMode      = $_.SessionControls.ContinuousAccessEvaluation.Mode
    }
} | Sort-Object CaeMode, Name | Format-Table -AutoSize

A populated Mode value means the policy is asking for CAE; a blank means that policy contributes nothing to continuous evaluation. Don’t over-index on the exact string — the property surfaces the enforcement mode Microsoft’s schema exposes at the time you run it, and that’s worth checking against the current Entra CAE documentation rather than a value someone hard-coded two years ago. The gotcha is conceptual: CAE is a property of the session, negotiated between Entra and the resource app. Turning it on in the policy is necessary, not sufficient. The app has to hold up its end.

2. Learn the difference between a CAE-aware token and a normal one

This is the concept everything else hangs on, so slow down here. A standard access token has a standard short lifetime and it’s valid until it expires, full stop. Revoke the session and the token keeps working until that clock runs out. That’s your gap.

A CAE-aware token is the opposite trade. Its lifetime is extended, but the client has declared it can handle a mid-session challenge. When a critical event fires — password reset, session revocation, account disable, a risky-user signal, a location change under strict enforcement — the resource returns a 401 with a claims challenge, and the client is forced back to Entra to re-evaluate immediately. Long token, short leash. Microsoft’s CAE documentation is the authoritative reference for the current token lifetimes and the exact list of critical events, and it’s worth reading rather than trusting a number you half-remember from a talk.

The signal that a client opted in is the xms_cc claim carrying the CP1 capability — the client capability announcement, documented in Microsoft’s Entra CAE guidance. No CP1, no CAE, and you’re back to waiting out the token. This is why the extended token lifetime is not the scary number people think it is when CAE is working. It’s the scary number when it isn’t.

3. Read the sign-in logs and see whether CAE actually applied

Don’t take the policy’s word for it. Go to the sign-in and look at what happened. In Entra admin center under Monitoring & health → Sign-in logs, open an interactive sign-in and check the Continuous access evaluation tab, plus the token/claims detail. You’re looking for evidence the session was evaluated under CAE (the caPolEval signal) rather than issued as a plain bearer token.

audit.ps1PowerShell
# Requires Microsoft.Graph.Reports (AuditLog.Read.All)
# Pull recent sign-ins for one user and surface CAE-relevant fields
Connect-MgGraph -Scopes 'AuditLog.Read.All' -NoWelcome$upn   = '[email protected]'
$since = (Get-Date).AddDays(-1).ToString('yyyy-MM-ddTHH:mm:ssZ')try {
    $signIns = Get-MgAuditLogSignIn -All -ErrorAction Stop `
        -Filter "userPrincipalName eq '$upn' and createdDateTime ge $since"
}
catch {
    Write-Error "Sign-in query failed: $($_.Exception.Message)"
    return
}$signIns | ForEach-Object {
    [pscustomobject]@{
        Time        = $_.CreatedDateTime
        App         = $_.AppDisplayName
        Resource    = $_.ResourceDisplayName
        ClientApp   = $_.ClientAppUsed          # watch for legacy protocols here
        IsInteractive = $_.IsInteractive
        CaePolicies = ($_.SessionLifetimePolicies.Detail -join '; ')
    }
} | Sort-Object Time -Descending | Format-Table -AutoSize

Get-MgAuditLogSignIn -All handles pagination for you — don’t hand-roll $top loops and hope. The point of this pass is to build a real picture of which resources your users touch and whether those sessions show CAE evaluation. If Exchange Online, SharePoint, and Teams show it and something else doesn’t, you’ve found your coverage gap without guessing.

4. Know which workloads honour CAE — and treat the rest as “verify, don’t assume”

The confirmed, well-implemented set is the one you’d expect: Exchange Online, SharePoint Online (and OneDrive by extension), and Microsoft Teams. Those are the workloads Microsoft documents as CAE-enabled, and they’re where the mechanism is mature.

The research finding — and I want to be precise, because this is where people overreach — is that coverage across the broader first-party app estate is inconsistent, with gaps in newer and edge-case applications. I’m not going to hand you a comprehensive named blocklist, because the honest answer is that it shifts as Microsoft ships, and a stale list is worse than no list. The durable move is the one in step 3: verify per resource in your own tenant rather than trusting a screenshot from a conference slide. What supports CAE today may change; your verification method shouldn’t.

5. Block legacy authentication, because it bypasses CAE entirely

CAE is a modern-auth mechanism. Basic auth and the older POP/IMAP/SMTP/legacy-EAS protocols have no concept of a claims challenge — there’s no client sitting there ready to be told “go re-authenticate.” A legacy-auth session isn’t slow to revoke under CAE. It’s invisible to it.

If you’ve been putting off the legacy-auth block because “one finance app still needs it,” understand that every one of those sessions is a hole straight through your continuous evaluation story. Use the ClientAppUsed field from step 3 to find who’s actually still on legacy protocols before you swing the hammer, then build a CA policy that blocks it.

audit.ps1PowerShell
# Find legacy-auth sign-ins BEFORE building a block policy — reviewed input, not blind action
$legacy = $signIns | Where-Object {
    $_.ClientAppUsed -in @(
        'Exchange ActiveSync','IMAP4','POP3','SMTP','Other clients',
        'Authenticated SMTP','Exchange Web Services'
    )
}
$legacy | Select-Object CreatedDateTime, UserPrincipalName, AppDisplayName, ClientAppUsed |
    Export-Csv .\legacy-auth-review.csv -NoTypeInformation
Write-Host "Review legacy-auth-review.csv, then scope your block policy to the exceptions you find."

6. Shorten token lifetimes where CAE doesn’t reach

For the resources that don’t negotiate CAE, you’re back in the old world where revocation waits out the token. That’s exactly the situation Conditional Access sign-in frequency controls were built for. Setting a tighter sign-in frequency on sensitive apps caps how long a stale session survives when CAE isn’t there to kill it faster. It’s a blunt instrument — users re-authenticate more often — so scope it to the resources that warrant it, not the whole tenant. Don’t apply it to CAE-aware sessions; you’d be trading a near-instant leash for a fixed timer, which is a downgrade.

7. Add location-based Conditional Access and keep monitoring

When CAE is actively monitoring location, it can challenge a session on changes—but only if the app supports it. As a compensating control for the apps that don’t, IP-based Conditional Access at the front door still narrows where a stolen token can be replayed from. And keep the sign-in query from step 3 running as a scheduled report, not a one-time audit. Coverage changes as Microsoft ships new versions; your visibility shouldn’t be a thing you checked once in 2026.

If you only do one thing this week: pull the sign-in logs and confirm CAE is actually being evaluated for the resources your privileged users hit. Not the policy toggle — the evaluation. The number that matters isn’t whether CAE is “on.” It’s how long the token really lives after you click revoke, and right now that number is different depending on which app the attacker happened to be using.