Spring til indhold

Graph is closing off license data: check your reports now

By Michal Lampe Sørensen · 7 min read · 15 September 2026

Verified against Microsoft Learn, September 2026

Contents

TL;DR

Microsoft is closing a gap in the Graph permission User.ReadBasic.All. It has been able to read user license details and app role assignments, even though neither belongs to a basic profile. Rollout started mid-September 2026 and completes late in the month. Tenant totals (how many licenses you pay for and how many are assigned) are not affected. What is affected is the per-user lookup: who holds which license. If your reporting tool uses that permission, it stops returning the data, usually without saying so.

What Microsoft is closing, and when

The Graph permission User.ReadBasic.All has granted more than its name promises. Beyond name, email address and profile photo, it has also been able to read two things that don't belong in a basic profile: user license details and app role assignments.

Microsoft is closing that now. Rollout began in mid-September 2026 and is expected to complete late in the month. The change applies to both delegated and app-only access.

An app holding only User.ReadBasic.All will no longer be able to read:

  • Per-user license details — GET /users/{id}/licenseDetails, or Get-MgUserLicenseDetail in PowerShell
  • App role assignments — GET /users/{id}/appRoleAssignments, or Get-MgUserAppRoleAssignment in PowerShell

If an app uses the permission only for what it was meant for, namely names, email addresses and photos in a people search or an intranet, nothing needs changing.

Microsoft says affected apps may see "failures or permission-related errors". Whether your tool shows an error or simply an empty column depends entirely on how it was written. Don't count on being told.

The two license questions: only one breaks

There are two very different questions you ask Graph about licenses, and they use different endpoints. The difference decides whether this touches you.

"How many licenses do we pay for, and how many are in use?" comes from /subscribedSkus. Those are the tenant totals: prepaidUnits.enabled against consumedUnits, bought against assigned. The endpoint needs LicenseAssignment.Read.All at minimum and works both delegated and app-only. The change doesn't touch it.

"Who holds which license?" comes from /users/{id}/licenseDetails. That's where User.ReadBasic.All has worked, and that's where it stops. Worth noting: that endpoint doesn't support app-only access at all. Delegated only, on behalf of a signed-in user.

In practice, the coarse count is safe, and the detailed lookup is what can stall. That's the annoying way round, because totals rarely save money. "We have 47 E3 licenses and 45 are assigned" leads to no action. "These eight users have E3 and haven't touched Teams or SharePoint in three months" does. The second kind of report is built on the per-user lookup.

QuestionEndpointAffected
How many licenses have we bought and assigned?/subscribedSkusNo
Which licenses does this user hold?/users/{id}/licenseDetailsYes
Which apps is this user assigned?/users/{id}/appRoleAssignmentsYes

How to find out whether it affects you

Most smaller companies don't call Graph themselves. But something in your tenant almost certainly does, and it's rarely something you built.

The usual candidates are a third-party license optimization tool, a reporting portal at your IT provider, an HR or onboarding system that looks users up in Entra, or a PowerShell script somebody wrote two years ago and scheduled monthly.

You can look for yourself. In the Entra admin center under Identity → Applications → Enterprise applications, open an app and check its Permissions. If User.ReadBasic.All is among the consented ones and the app pulls license data, it's a candidate to break.

After the rollout there's one more place to look: service principal sign-in logs. A call that fails on missing permissions leaves a trace there, even when the tool's own interface stays quiet.

The script is the one that gets missed. An app in Enterprise applications shows up in a list. A PowerShell script on a server at your provider shows up nowhere, and it's exactly the kind of thing written with the broadest permission that happened to work that day.

How to fix it

Microsoft points to three routes, depending on what the app actually needs:

What the app readsPermission to move to
Per-user license detailsLicenseAssignment.Read.All
App role assignmentsUser.Read.All
BothUser.Read.All

The switch needs fresh administrator consent, and the app has to be redeployed and retested. It isn't much work, but it isn't work that happens on its own either.

One thing is worth holding on to along the way. The temptation, when a call suddenly fails, is to grant Directory.Read.All and move on. That permission opens the whole directory. If the app only reads licenses, LicenseAssignment.Read.All is the right call, and it's also the one Microsoft lists as least privileged on both license endpoints.

That is the point of the change, incidentally. User.ReadBasic.All got granted to apps because it sounded harmless, and license and role data came along with it that nobody had decided to share. Microsoft is closing the gap because the permission gave more than it promised.

If your tool needs per-user license data without a signed-in user, licenseDetails is a dead end: the endpoint only supports delegated access. Microsoft's newer Cloud Licensing API can do it with User-UsageRight.Read.All, which works both delegated and app-only. It is still in beta, though, so don't build production reporting on it yet.

Three questions for your IT provider

If you don't have anyone working with Graph in-house, this is where you can act. Pass on three questions:

1

Which permissions do the apps you use in our tenant hold?

We're looking for User.ReadBasic.All among the consented permissions under Enterprise applications.

2

Does our license report read per user, or only totals?

Per-user details are affected. Tenant totals from /subscribedSkus are not.

3

What happens in the report if the call fails?

Does an error appear, or does it just show zero?

The third one matters most. A report that shows an error gets fixed next week. A report that shows zero assigned licenses without saying why gets taken at face value, and then somebody decides to cancel or downgrade on an empty dataset.

"We only use the totals" is a valid answer and good news. "Let us check" is fine too. "It usually works" is the one to follow up on before the end of September.

One more thing: this costs nothing and requires no particular plan. Graph permissions don't track your license level. Whether you run Business Basic or E5, the change is the same and so is the fix.

Sources: Microsoft Graph permissions reference (Microsoft Learn), List licenseDetails (Microsoft Learn), List subscribedSkus (Microsoft Learn), Cloud licensing API in Microsoft Graph, beta (Microsoft Learn) and Message Center post MC1470871, as reported by mwpro.co.uk and ourcloudnetwork.com.

Do the license math without a reporting tool

Compare plans and see what you pay for against what you use. No access to your tenant, no permissions.

Open the optimizer

Frequently asked questions

When does the change take effect?+

Rollout began in mid-September 2026 and is expected to complete late in the month. There is no single cut-off date across all tenants, so it can reach you at any point in that window. That's why it makes sense to check now rather than wait for something to stop working.

Will our license reporting stop working?+

Only if it reads per-user license information using the User.ReadBasic.All permission. Reports built on tenant totals from /subscribedSkus, meaning how many licenses you've bought and assigned, are unaffected. Ask your provider which of the two your report uses. Note that a tool can keep running happily and simply show empty fields instead of an error.

Which permission should we use instead?+

LicenseAssignment.Read.All for license details and User.Read.All for app role assignments. If the app needs both, Microsoft points to User.Read.All. Pick the least privileged one that does the job, and avoid reaching for Directory.Read.All just to get the call working again. The switch requires fresh administrator consent.

Does fixing this require a particular Microsoft 365 plan?+

No. Graph permissions aren't tied to which plan you hold. The change and the fix are the same whether you run Business Basic, Business Premium or E5, and there's no extra cost to switching permission. It does require an administrator who can consent on behalf of the organization.

Want a second opinion on your licenses?

I work with Microsoft 365 day to day and help Danish companies choose the right license and avoid overpaying. Write to me and I'll get back to you.

Get in touch