Most organizations believe they are protected once Conditional Access is enabled. The board gets a reassuring slide: "MFA deployed, identity secured." That is a dangerous oversimplification. I've spent years building CA policies for enterprises and auditing them for the weak spots an attacker would look for. The gaps are predictable, consistent, and surprisingly easy to miss from the inside.
Legacy Authentication — MFA's Blind Spot
Legacy authentication protocols — SMTP AUTH, IMAP, POP3, Exchange ActiveSync over Basic auth — authenticate with username and password only. They can't process an MFA challenge, so Conditional Access can only block them, never challenge them.
In Exchange Online, Microsoft turned off Basic auth for IMAP, POP, ActiveSync and EWS back in October 2022, so the classic IMAP password spray no longer works there. The big exception is SMTP AUTH (client submission): Basic auth still works in tenants that haven't switched it off. Microsoft will disable it by default at the end of December 2026 and plans to announce final removal in the second half of 2027. Legacy auth also still matters for hybrid on-premises Exchange and third-party apps.
December 2026 deadline: When Microsoft disables SMTP AUTH Basic auth by default, anything still relying on it — printers, scanners, line-of-business apps — will stop sending mail. Find them now with the query below and move them to OAuth or a connector. Otherwise the quick fix under pressure will be to switch Basic auth back on.
# Log Analytics → Entra ID Sign-in logs SigninLogs | where ClientAppUsed in ( "Exchange ActiveSync", "IMAP4", "POP3", "SMTP", "Other clients", "Authenticated SMTP" ) | where ResultType == "0" | summarize LastSeen=max(TimeGenerated), Count=count() by UserPrincipalName, ClientAppUsed, AppDisplayName | order by LastSeen desc # Run for 30 days minimum before blocking # Any result here = active legacy auth usage = active bypass risk
# Entra ID → Conditional Access → Policies → New policy Name: "BLOCK — Legacy Authentication" Users: All users Exclude: Break-glass accounts only ← keep this list SHORT Target: All resources Conditions → Client apps: ☑ Exchange ActiveSync clients ☑ Other clients # Do NOT check modern auth boxes Grant: Block access State: Report-only ← run 2 weeks, review, then enable
✦
Exclusion Groups — The Unmaintained Backdoor
Every CA policy has an exclusion list — accounts or groups that bypass the policy entirely. In every mature tenant I've reviewed, these exclusion groups have grown silently over years. Break-glass accounts, service accounts, vendor accounts, VIP user requests, "temporary" exceptions that became permanent. In many cases, ex-employees or ex-contractors remain in these groups long after their accounts are otherwise disabled.
The real risk: Exclusion groups are rarely monitored. An attacker who adds a user to an exclusion group and removes themselves hours later may never be caught — unless you have an alert on group membership changes for CA-excluded groups.
# List all CA policies and their exclusions Connect-MgGraph -Scopes "Policy.Read.All" Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State, @{N='ExcludedUsers';E={$_.Conditions.Users.ExcludeUsers}}, @{N='ExcludedGroups';E={$_.Conditions.Users.ExcludeGroups}} # Then for each excluded group, list members: Get-MgGroupMember -GroupId "<GroupId>" | Select-Object DisplayName, UserPrincipalName # Alert rule: Sentinel — Group membership change on CA exclusion groups AuditLogs | where OperationName == "Add member to group" | where TargetResources[0].DisplayName in ("CA-Exclusions", "BreakGlass-Accounts") | project TimeGenerated, InitiatedBy, TargetResources
- Keep a single named group per policy for exclusions — never add individual accounts directly
- Enable Entra ID Access Reviews on every CA exclusion group — quarterly review, auto-remove if no reviewer response
- Set a Sentinel alert on any membership change to exclusion groups — high-priority alert, 15-minute response SLA
- Limit who can add members to exclusion groups — scope this to a dedicated Identity Admin role, not Global Admin
- Document every exclusion with a justification and expiry date — use group description field as the audit trail
✦
OIDC Scope Bypass — The Silent 2026 Fix
This is the gap most enterprise admins didn't know existed. When a CA policy targets "All resources" with at least one resource exclusion, and an application requests only low-privilege OIDC or directory scopes (openid, profile, email, User.Read), the policy was silently skipped entirely. No MFA prompt. No device compliance check. Nothing.
Your policy said "require MFA for all cloud apps." The reality was "require MFA for all cloud apps, except when an app requests only basic scopes and your policy has any resource exclusion." Most admins had no idea this was happening.
Who was affected: Any tenant with a CA policy targeting "All cloud apps" or "All resources" that had at least one resource exclusion configured — almost every mature enterprise tenant. Developer tools and vendor apps that request only OIDC scopes were bypassing those policies silently. Microsoft let tenants opt out of the fix, and tenants that opted out are still exposed.
# Find sign-ins where Conditional Access was not applied # These may have been bypassing your policies via OIDC scope gap SigninLogs | where ConditionalAccessStatus == "notApplied" | where AuthenticationRequirement == "singleFactorAuthentication" | where TimeGenerated > ago(30d) | summarize Count=count(), LastSeen=max(TimeGenerated) by UserPrincipalName, AppDisplayName, ClientAppUsed | order by Count desc # High count + singleFactor + notApplied = was bypassing your policy # Since the rollout, these should show CA applied — if not, check for an opt-out
- Check whether your tenant opted out of or customized the change (Message Center: MC1223829 and MC1418116) — an opt-out leaves the bypass open
- Run the detection query above for the period since rollout — single-factor, "notApplied" sign-ins into apps your "All resources" policy should cover need investigating
- Review exclusions added since mid-June 2026 — apps that broke when enforcement arrived were often "fixed" with a quick new exclusion
- For apps that legitimately need OIDC-only flows, explicitly exclude them from the policy and document why
- Review and minimize resource exclusions — every exclusion is a surface you have to keep justifying
Silver lining: Your existing "All resources" CA policies now actually enforce what you intended. Use the change as a prompt for a full CA audit — especially any exclusions added in a hurry to unbreak apps.
✦
Device Compliance Spoofing
CA policies requiring "compliant device" rely on Intune's verdict, and that verdict is only as strong as the settings behind it. Two weaknesses show up again and again: the tenant-wide setting "Mark devices with no compliance policy assigned as" left at its default of Compliant, and compliance policies that check little more than OS version.
An attacker with a user's credentials registers or enrolls a device they control. If any user can register devices, and the device lands outside the scope of your compliance policies, or those policies only check OS version, it can be marked compliant without BitLocker, Secure Boot or antivirus. A "require compliant device" grant then waves the attacker straight through.
Key insight: "Compliant device" in Intune means "Intune says this device meets your policies" — not "this device is actually secure." Device compliance is only as strong as your compliance policy configuration and your health attestation requirements.
- In Intune's tenant-wide compliance settings, set "Mark devices with no compliance policy assigned as" to Not compliant
- Require BitLocker, Secure Boot, and Code Integrity as compliance requirements — not just OS version
- Enable Microsoft Defender for Endpoint integration with Intune — device risk score becomes a compliance dimension
- For hybrid environments: require Microsoft Entra hybrid join AND Intune compliance — not either/or
- Set compliance policy grace period to 0 days for high-risk device categories
- Restrict device registration in Entra ID — only IT-managed devices should be able to register
# Entra ID → Monitoring → Audit logs # Filter: Activity = "Register device", "Add device" # Look for devices registered outside business hours or from unusual locations AuditLogs | where OperationName == "Register device" | where TimeGenerated > ago(7d) | extend DeviceName = tostring(TargetResources[0].DisplayName) | extend RegisteredBy = tostring(InitiatedBy.user.userPrincipalName) | project TimeGenerated, RegisteredBy, DeviceName, Result | order by TimeGenerated desc # Cross-reference: device registered + became compliant within same hour # = suspicious enrollment flow — investigate manually
✦
Token Lifetime & Session Control Gaps
Conditional Access protects the moment of authentication — not the lifetime of the session. A valid access token obtained before a CA policy was enforced, or before a risk event was detected, continues to work until it expires. This is why the February 2026 change from "Revoke MFA sessions" to "Revoke sessions" is significant — the old action only reset per-user MFA state. Existing tokens remained valid. Attackers with stolen tokens continued operating even after admins believed they had revoked access.
February 2026 change: The new "Revoke sessions" action in Entra ID now invalidates all user sessions including MFA, regardless of whether MFA is enforced via CA or per-user policy. Make sure your IR playbooks reference the new control name. Note that it revokes refresh tokens and session cookies — access tokens already issued stay valid until they expire, unless the app supports Continuous Access Evaluation.
- Enable Sign-in frequency in CA policy — set to 1 hour for privileged roles, 4–8 hours for standard users
- Enable Continuous Access Evaluation (CAE) — forces near-real-time policy re-evaluation instead of waiting for token expiry
- Require phishing-resistant MFA (FIDO2 / Windows Hello) for all admins — these cannot be replayed by AiTM proxies
- Enable Token Protection in CA — binds sign-in tokens to the device so they can't be replayed elsewhere. Generally available on Windows for Exchange, SharePoint, Teams, Azure Virtual Desktop and Windows 365; preview on macOS and iOS; browsers not supported
- In IR scenarios, use Revoke sessions together with a password reset — it kills refresh tokens and sessions, and CAE-capable apps also cut off access tokens in near real time
# Same user, multiple IPs in short window — possible token replay SigninLogs | where TimeGenerated > ago(1h) | summarize IPCount=dcount(IPAddress), IPs=make_set(IPAddress) by UserPrincipalName, CorrelationId | where IPCount > 1 | order by IPCount desc # Also monitor for: sign-in from IP with no prior history # immediately followed by bulk mailbox access or file downloads
✦
Report-Only Policies That Never Got Enforced
Every good CA deployment starts in Report-only mode — you monitor before you enforce. The problem is that in many tenants, policies stay in Report-only indefinitely. The "we'll enforce it after we review" becomes "we never reviewed." I've seen tenants with 12–15 CA policies in Report-only mode that have been sitting there for over a year, providing zero actual protection.
From an attacker's perspective, Report-only policies are invisible. They generate log entries, but they block nothing. An attacker who enumerates your CA policies via Graph API will immediately identify which policies are enforced vs report-only — and plan their access accordingly.
# Get all CA policies and their current state Connect-MgGraph -Scopes "Policy.Read.All" Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State, CreatedDateTime, ModifiedDateTime | Sort-Object State | Format-Table # States: "enabled" | "disabled" | "enabledForReportingButNotEnforcing" # Any policy in "enabledForReportingButNotEnforcing" = report-only = not blocking # Review CreatedDateTime — policies older than 30 days in report-only need review
- Set a 30-day hard deadline for every new CA policy to move from Report-only to Enforced — put it in your change management process
- Review all current Report-only policies — any older than 90 days should either be enforced or deleted
- Use the CA What If tool to simulate sign-ins before enforcement — this is the correct way to validate, not indefinite report-only
- Create a Workbook in Entra ID showing policy states across your tenant — review monthly
- Never disable a CA policy — instead, document why it was removed and delete it. Disabled policies create confusion about your actual security posture
✦
Detection & The What If Tool
Before you can fix gaps, you need to see them. Microsoft's built-in What If tool is underused. It lets you simulate any sign-in scenario and shows exactly which CA policies would apply — and which wouldn't.
- Entra ID → Conditional Access → Policies → What If
- Test these scenarios at minimum: user + legacy auth client, user + unknown IP, user + non-compliant device, service account + any app
- Any scenario that returns "0 policies applied" or only report-only policies = gap in your coverage
# Full CA policy audit — export for review Connect-MgGraph -Scopes "Policy.Read.All" Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State, Conditions, GrantControls | Format-List # Review output for: # 1. Policies in "Report-only" → not enforced # 2. Policies with broad exclusions → potential bypass # 3. Cloud apps with zero CA coverage → unprotected resources # 4. No policy targeting legacy auth client apps → legacy auth open
✦
CA Baseline That Actually Holds
Here is the minimum viable CA policy set for an enterprise tenant in 2026. Every policy should be tested in Report-only first, then enforced within 30 days.
POLICY 1: BLOCK — Legacy Authentication Users: All · Exclude: Break-glass only Conditions: Other clients + Exchange ActiveSync Grant: Block POLICY 2: REQUIRE — MFA for All Users Users: All · Exclude: Break-glass, service accounts (monitored) Apps: All resources Grant: Require authentication strength → Multifactor authentication POLICY 3: REQUIRE — Phishing-Resistant MFA for Admins Users: All privileged roles (GA, PA, CA Admin, Exchange Admin...) Apps: All resources Grant: Require Authentication Strength → Phishing-resistant MFA Session: Sign-in frequency 1 hour POLICY 4: REQUIRE — Compliant Device for Corporate Apps Users: All · Exclude: Break-glass Apps: Exchange Online, SharePoint, Teams Grant: Require compliant device OR Microsoft Entra hybrid joined device POLICY 5: BLOCK — High-Risk Sign-ins Users: All · Exclude: Break-glass Apps: All resources Conditions: Sign-in risk = High Grant: Block ← requires Entra ID P2 POLICY 6: REQUIRE — Secure Password Change for High-Risk Users Users: All · Exclude: Break-glass Apps: All resources Conditions: User risk = High Grant: Require authentication strength (MFA) + Require password change Session: Sign-in frequency = Every time ← replaces the legacy Identity Protection user-risk policy (retired Oct 1, 2026) POLICY 7: REQUIRE — MFA Registration from Trusted Location Users: All Target resources: User actions → Register security information Conditions: Location = not named location Grant: Require MFA ← prevents attacker registering their own MFA method
Deployment rule: Never deploy a new CA policy in "On" mode directly. Always start in Report-only, review sign-in logs for 2 weeks, identify impacted service accounts and apps, add necessary exclusions — then enforce. One wrong click can lock out your entire organization including the C-Suite.
CA Is a Framework, Not a Finish Line
The gap between "Conditional Access enabled" and "identity secured" is enormous. Every policy has conditions, exclusions, and edge cases. Attackers don't need to break your encryption — they need to find the single sign-in flow you didn't account for.
The 2026 OIDC enforcement change is a reminder that even Microsoft's own platform had silent bypass conditions that persisted for years. Your job isn't to configure CA once and move on — it's to treat it as a living architecture that requires continuous review, monitoring, and testing.
Run the What If tool. Audit your exclusion groups. Check your Report-only policies. Then do it again next quarter. The attackers are checking.