Conditional Access on All resources: the baseline scopes exemption ends on 15 June
If you have a Conditional Access policy on All resources with even one resource excluded, there is a small class of sign-ins that policy has never evaluated: clients that ask only for OIDC scopes or a handful of low-privilege directory scopes. From 15 June 2026 Microsoft starts enforcing those sign-ins (MC1223829). Below I go through how the old exemption actually worked, how to find the sign-ins in your own tenant that fall in it, and what the new Baseline scopes settings page does before you click anything on it.
Photo: Annie Spratt on Unsplash
How the old exemption worked
User.Read next to its real resource (Outlook does it with its Exchange token, to show who is signed in), and an excluded app wouldn't work if that part of the request was still held to the policy.The list is split by client type, and the condition differs between the two:
- Native clients and SPAs: Azure AD Graph
email,offline_access,openid,profile,User.Read, and on Microsoft Graph the same plusPeople.Read. - Confidential clients, "if they're excluded from an All resources policy": additionally
User.Read.AllandUser.ReadBasic.All, and on Microsoft Graph alsoPeople.Read.All,GroupMember.Read.AllandMember.Read.Hidden.
openid and profile) and Azure CLI (which asks for only User.Read at sign-in). Neither is excluded in a typical tenant; it was the exclusion of an unrelated app that let them through.What came through that gap was limited. The tokens give access to your own profile, and for an excluded confidential client to user and group membership reads across the directory. A follow-up token for a real resource (Exchange, SharePoint, Azure Resource Manager) is still evaluated against your policies at that point, so this was never a full bypass. But a sign-in that succeeds without the MFA or compliant device your baseline policy asks for also confirms to whoever holds the password that it works, and directory reads are the usual first step of reconnaissance. Microsoft has long recommended a baseline MFA policy on All resources without exclusions; the documented workaround for protecting directory data was a separate policy on Windows Azure Active Directory (00000002-0000-0000-c000-000000000000), selected through a custom security attribute filter because that resource doesn't appear in the app picker.
What changes on 15 June
User.Read, User.Read.All, User.ReadBasic.All, People.Read, People.Read.All, GroupMember.Read.All and Member.Read.Hidden) are evaluated as directory access and mapped to Azure AD Graph, the Windows Azure Active Directory resource, as the Conditional Access audience. Policies on All resources with exclusions, and policies that explicitly target Azure AD Graph, are then enforced for sign-ins that request only these scopes. A client that requests even one scope outside the list doesn't change: it was already evaluated against the resource it asked for. An excluded confidential client that asks only for OIDC scopes doesn't change either.Microsoft's list of scenarios that justify keeping the legacy behavior shows where this causes problems, and it matches the policy sets I see in larger environments: an All resources policy with Require compliant device and an excluded app that has to work from unmanaged devices, an All resources policy with Require app protection policy and clients that don't integrate the Intune SDK, block policies with exclusions, and public clients that were deliberately kept away from device compliance. In each of those, a sign-in that requested only baseline scopes used to succeed, and from the rollout onwards it has to satisfy the policy. For apps you build yourself, check that they handle a Conditional Access challenge (developer guidance), and for a confidential client that only needs the user's name and email, switching from
User.Read to openid and profile keeps it out of scope entirely.The rollout is progressive over several weeks. Since the 5 June revision of MC1223829, Microsoft says you get another Message Center post two weeks before the rollout reaches your tenant and one after it completes.
Finding the affected policies and sign-ins
All and has at least one entry in excludeApplications is in scope. An exclusion of Office365 or MicrosoftAdminPortals counts as a resource exclusion as well. Connect-MgGraph -Scopes "Policy.Read.All"
Get-MgIdentityConditionalAccessPolicy -All |
Where-Object {
$_.Conditions.Applications.IncludeApplications -contains "All" -and
$_.Conditions.Applications.ExcludeApplications.Count -gt 0
} |
Select-Object DisplayName, State,
@{ n = "ExcludedApps"; e = { $_.Conditions.Applications.ExcludeApplications -join ", " } },
@{ n = "Grant"; e = { $_.GrantControls.BuiltInControls -join ", " } }
compliantDevice, compliantApplication or block.For the sign-ins themselves there are two routes. Without changing anything, Log Analytics already shows candidates: sign-ins to Microsoft Graph or Windows Azure Active Directory where your All resources policy reports
notApplied. ConditionalAccessPolicies is a dynamic column in SigninLogs and a string in AADNonInteractiveUserSignInLogs, hence the parse_json on one side. let policyId = "<object ID of your All resources policy>";
let directoryResources = dynamic(["00000003-0000-0000-c000-000000000000", "00000002-0000-0000-c000-000000000000"]);
union
(SigninLogs
| where TimeGenerated > ago(14d)
| extend CAPolicies = ConditionalAccessPolicies),
(AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(14d)
| extend CAPolicies = parse_json(ConditionalAccessPolicies))
| where ResourceIdentity in (directoryResources)
| mv-expand CAPolicy = CAPolicies
| where tostring(CAPolicy.id) == policyId and tostring(CAPolicy.result) == "notApplied"
| summarize SignIns = count(), Users = dcount(UserPrincipalName) by AppDisplayName, AppId, ResourceDisplayName
| order by SignIns desc
notApplied also appears when the user is excluded or a condition such as platform or location didn't match. The precise route goes through the new settings page. The Baseline scopes settings page
Enable enforcement switches to the new behavior right away, ahead of the rollout. Microsoft suggests trying it in a test tenant first. Disable enforcement keeps the legacy behavior for every policy in the tenant. Microsoft describes it as a temporary opt-out and doesn't recommend it, but hasn't published an end date for it. Whatever you choose here is not overridden by the rollout. If you choose nothing, enforcement is applied automatically and the page shows no selection afterwards, because enforcement has become the default.
Customize behavior takes more explanation. You register a single-tenant application (no further configuration needed), exclude it from the policies where you want to keep the legacy behavior, and select it on the settings page as the target for baseline scopes. Baseline-scope-only sign-ins are then evaluated against your placeholder app instead of Windows Azure Active Directory. Where the placeholder is excluded, the policy doesn't apply, which gives you the old behavior per policy. Everywhere else enforcement applies.
Two things follow from that design. First, Microsoft's wording implies that selecting Customize behavior before 15 June turns on enforcement for every policy that doesn't exclude the placeholder (Learn doesn't say in so many words that it takes effect ahead of the rollout), so treat it as live from the moment you save; it doesn't leave everything as it is. Second, the placeholder becomes a marker in your logs: every sign-in that requested only baseline scopes lists its app ID as a Conditional Access audience. The Learn page currently says this happens "after selecting the Enable enforcement option", but in that mode there is no custom application to show, so read it as Customize behavior.
That gives a clean measurement setup. Exclude the placeholder from exactly the All resources policies that already have exclusions, select Customize behavior, and your effective behavior stays legacy while the logs record every affected sign-in. Then:
let placeholderAppId = "<application (client) ID of your placeholder app>";
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(14d)
| where ConditionalAccessAudiences contains placeholderAppId
| summarize SignIns = count(), Users = dcount(UserPrincipalName) by AppDisplayName, AppId
| order by SignIns desc
Require approved client app retires on 30 June
approvedApplication without compliantApplication in the Grant column of the script above shows you which policies still need it.My suggestion for this week: run the policy script, list every exclusion on a policy with compliant device, app protection or block, and if there are any, set up the placeholder app with Customize behavior before 15 June so you have the list of affected sign-ins from your logs before the first users call the service desk.
Sources
- MC1223829: Conditional Access enforcement for All resources policies with resource exclusions
- Improved enforcement for All resources policies with resource exclusions
- Conditional Access target resources: legacy behavior when an All resources policy has a resource exclusion
- Require MFA strength for all users
- Developer guidance for Conditional Access
- Baseline scopes settings guidance (aka.ms/BaselineScopesSettings)
- SigninLogs table reference
- AADNonInteractiveUserSignInLogs table reference
- MC1220751: retirement of the Require approved client app grant
- Migrate approved client app to application protection policy in Conditional Access