Announcement

User.ReadBasic.All loses access to app roles and license data this month (MC1470871)

User.ReadBasic.All has quietly exposed app role assignments and license details since it shipped. That access closes in a rollout completing late September 2026. What breaks, and one discrepancy in Microsoft's own migration guidance worth checking before you act on it.

Source MC1470871
Action required Audit apps holding User.ReadBasic.All and grant User.Read.All or LicenseAssignment.Read.All before rollout completes late September, testing the actual call rather than assuming the permission name is enough.

If an app in your tenant has only User.ReadBasic.All granted and it reads a user’s app role assignments or license details, that call stops working this month. Not because someone misconfigured a policy. Because Microsoft is closing a permission scope that never should have covered that data in the first place.

Microsoft announced the change under message center post MC1470871. The rollout starts mid-September 2026 and completes by late September 2026, worldwide.

Key Takeaways

  • User.ReadBasic.All currently allows reading a user’s app role assignments and license details, alongside its intended basic profile properties, a scope gap Microsoft is now closing (MC1470871)
  • Rollout runs mid-September through late September 2026. No action needed if your app only reads basic profile fields
  • Microsoft’s own migration guidance recommends User.Read.All to keep reading app role assignments. The official Graph endpoint documentation lists a different permission entirely. Check both before you grant anything
  • Affected calls: GET /users/{id}/appRoleAssignments and license-detail reads, including the Get-MgUserAppRoleAssignment PowerShell SDK cmdlet

What was User.ReadBasic.All actually exposing?

Microsoft’s own permissions reference defines User.ReadBasic.All narrowly. For app-only access, it’s scoped to display name, first and last name, email address, open extensions, and photo. For delegated access, it’s the same list minus open extensions: display name, first and last name, email address, and photo. App role assignments and license information don’t appear anywhere in that description (Microsoft Graph permissions reference).

In practice, the permission has been returning more than that. Microsoft’s own text in MC1470871 confirms the gap directly: an app holding only User.ReadBasic.All could still call the endpoint that lists which enterprise apps a user has been assigned to, and could still read that user’s license details, data that has nothing to do with a “basic profile.” That’s the gap MC1470871 closes. You can read Microsoft’s exact wording by searching for MC1470871 in your own Microsoft 365 admin center message center.

What changes, and when

Before the rolloutAfter the rollout completes
Basic profile fields (name, email, photo)Readable with User.ReadBasic.AllUnchanged, still readable
App role assignments (/users/{id}/appRoleAssignments)Readable with User.ReadBasic.All aloneNo longer readable with this permission
License detailsReadable with User.ReadBasic.All aloneNo longer readable with this permission
Rollout scopeN/AWorldwide, mid-September to late September 2026

Nothing about how User.ReadBasic.All is granted or consented changes. The permission itself isn’t deprecated. It just stops returning data it was never supposed to return.

Who’s actually affected

What I run into most often isn’t a deliberate design choice. It’s a script or internal tool that got User.ReadBasic.All granted early on because it sounded broad enough to “just work,” and someone later bolted on a license or app-assignment check without anyone reviewing whether the original grant actually covered it. Custom onboarding tools, license-reporting dashboards, and internal HR integrations are the most common places this shows up, because those are exactly the tools that end up reading both profile data and licensing in the same call.

To find out if you’re affected, check any app registration in your tenant that has User.ReadBasic.All and look at what its code actually calls. The two calls to search for:

  • GET /users/{id}/appRoleAssignments (or the PowerShell SDK’s Get-MgUserAppRoleAssignment)
  • Any license-detail read on a user object

If neither shows up, you’re done. The change doesn’t touch you. If either does, that call starts failing (or silently returning nothing, depending on how the app handles a permissions error) once the rollout reaches your tenant.

Checking every app registration by hand doesn’t scale past a handful of apps. Tenant Wizards has published a PowerShell script that inventories every app in your tenant holding User.ReadBasic.All, delegated or application, and flags whether it already also holds User.Read.All or LicenseAssignment.Read.All. It can’t see what an app’s code actually calls (Graph doesn’t log that), so it’s a starting list for review, not a verdict. Uses delegated permissions, no stored credentials.

Get-ReadBasicAllExposureReport.ps1 on GitHub

How to migrate (and one thing to check first)

Microsoft’s guidance in MC1470871 is straightforward: grant User.Read.All if you need app role assignments, LicenseAssignment.Read.All if you need license details, or User.Read.All alone if you need both.

Before you grant that, check the endpoint’s own documentation. The official reference page for GET /users/{id}/appRoleAssignments lists its required permissions as AppRoleAssignment.ReadWrite.All (delegated) or Directory.Read.All (application). User.Read.All doesn’t appear in that table at all (Microsoft Learn: List appRoleAssignments). That’s two Microsoft-owned pages giving different answers for the same call. It’s most likely the endpoint’s permissions table hasn’t caught up with the MC1470871 change yet, not that the MC guidance is wrong, but “most likely” isn’t good enough to grant a broader permission and walk away. Test the actual call against a non-production app registration with User.Read.All granted before you roll the change out to anything that matters, and don’t assume the MC text is the last word if the live API tells you something different.

Once you’ve confirmed which permission actually satisfies the call in your tenant:

  1. Update the app registration’s API permissions in the Entra admin center. Add the confirmed replacement permission alongside (not instead of) User.ReadBasic.All, since other code paths in the same app may still rely on it for basic profile reads.
  2. Get fresh admin consent. A new permission grant needs re-consent before it takes effect, whether that’s through the Entra portal or your own consent flow.
  3. Redeploy and test the specific call (the app role assignment or license read, not just a general smoke test) before the rollout reaches your tenant.

What happens if you don’t act

If your app only ever used User.ReadBasic.All for names, emails, and photos, nothing happens. That’s most of the apps that hold this permission.

If it also reads app role assignments or license details, the call starts failing once the rollout reaches your tenant sometime between mid- and late September 2026. There’s no announced grace period beyond the rollout window itself, and no indication this fails loudly. Plan on it looking like a silent permissions error in your app’s logs rather than a tenant-wide alert.

Frequently Asked Questions

Does this affect delegated permissions, application permissions, or both?

Both. Microsoft’s guidance in MC1470871 applies to User.ReadBasic.All regardless of whether it’s granted as a delegated or an application permission. The fix removes the unintended app-role-assignment and license access from the permission itself, not from one specific consent type.

I only use User.ReadBasic.All to show a user’s name and photo. Do I need to do anything?

No. That’s exactly the intended scope of the permission, and it’s unaffected by this change.

We already have User.Read.All granted for something else. Are we covered?

Likely yes for app role assignments, based on Microsoft’s MC1470871 guidance, but given the documentation discrepancy above, confirm the actual call still succeeds against a test app registration rather than assuming it from the permission name alone.

Is this a breaking change or a security fix?

Both, depending on which side of it you’re on. For the small number of apps relying on the unintended access, it’s a breaking change that needs a permissions update before the rollout completes. For everyone else, it’s a quiet security fix: a permission that was returning more than it was designed to is being brought back in line with its documented scope.

← All announcements