New the least privileged permission for Microsoft Graph to create a user

The principle of least privilege

A good Microsoft Graph integration should request only the permissions your app really needs. This is the core of the least privilege principle: the narrower the accessthe lower the privacy riskthe easier it is for tenant admins to trust and approve the app.

In practice, that means rethinking features that demand broad permissions and choosing simpler approaches when they deliver similar value with less access.

When selecting permission types, the safest order is to prefer resource-specific consent (RSC) where possible, then delegated permissions that act only in the signed-in user’s scope, and use application permissions only when no narrower option works.

For example, an app that only reads a user profile should request User.Read, not User.ReadWrite, and an app that deletes or restores the users needs only User.DeleteRestore.All permission. Applying least privilege this way reduces customer concerns, improves approval chances, and strengthens trust in the app.

Granular permissions for users

In the last two years, Microsoft Graph has introduced a new set of granular permissions for users. These permissions allow apps to request access to specific user properties and actions, rather than broad access to all user data.

Microsoft Graph currently supports the following granular permissions for users:

Permission Delegated text
User-LifeCycleInfo.Read.All Read all users' lifecycle information
User-LifeCycleInfo.ReadWrite.All Read and write all users' lifecycle information
User-Mail.ReadWrite.All Read and write all secondary mail addresses for users
User-OnPremisesSyncBehavior.ReadWrite.All Read and update the on-premises sync behavior of users
User-PasswordProfile.ReadWrite.All Read and write all password profiles and reset user passwords
User-Phone.ReadWrite.All Read and write all user mobile phone and business phones
User.ConvertToInternal.ReadWrite.All Convert an external user to internal memeber user
User.Create Create users
User.DeleteRestore.All Delete and restore users
User.EnableDisableAccount.All Enable and disable user accounts
User.Export.All Export user's data
User.Invite.All Invite guest users to the organization
User.ManageIdentities.All Manage user identities
User.Read Sign in and read user profile
User.Read.All Read all users' full profiles
User.ReadBasic.All Read all users' basic profiles
User.ReadUpdate.All Read and update users
User.ReadWrite Read and write access to user profile
User.ReadWrite.All Read and write all users' full profiles
User.ReadWrite.CrossCloud Read and write profiles of users that originate from an external cloud.
User.RevokeSessions.All Revoke all sign in sessions for a user

The latest addition to these granular permissions is the User.Create permission, which allows an app to create new users.

It's useful when your admin wants to delegate user creation to another users like a helpdesk or HR team, without giving them full access to all user data.

With the User.Create permission, your app can create a new user, but it cannot read or modify existing users. This is a significant improvement over the previous User.ReadWrite.All permission required for user creation, which granted full access to all user data.

What's important, the user who will be creating new users must have the User Administrator role assigned in Entra ID, otherwise the app will not be able to create new users even with the User.Create permission.

Create a user with the User.Create permission

Go to Entra Admin Center, select App registrations and register a new app.

For redirect URL, I've set public client and http://localhost, because I want to test the app via PowerShell script.

Go to API permissions under Manage and add and grant delegated permissions User.Read and User.Create for Microsoft Graph.

That's it. No other setup is required. Use application id and your tenant id in the following script to test the creation of a new user.

$clientId = '<client_id>'
$tenantId = '<tenant_id>'

Connect-MgGraph -ClientId $clientId -TenantId $tenantId

#Import-Module Microsoft.Graph.Users

$params = @{
  accountEnabled = $true
  displayName = "John Rambo"
  mailNickname = "john.rambo"
  userPrincipalName = "john.rambo@contoso.onmicrosoft.com"
  passwordProfile = @{
    forceChangePasswordNextSignIn = $true
    password = "xWwvJ]6NMw+bWH-d"
  }
}

New-MgUser -BodyParameter $params

Disconnect-MgGraph

It will create a new user and returns the user's properties. If you try to read or update the user via Get-MgUser or Update-MgUser, you will get 403 forbidden error, because the app does not have permission to read or update users.

Conclusion

The new User.Create permission is a strong example of least-privilege design improving Microsoft Graph. It allows organizations to delegate user provisioning to helpdesk or HR scenarios without granting broad read/write access to the full directory. Combined with the required Entra ID role assignment, it creates a much cleaner security boundary: the app can create new users, but it still cannot read or modify existing ones. That makes the solution safer for tenants, easier for admins to approve, and a much better default for developers building trusted integrations. Don't forget that the user must have the User Administrator` role.

0
Buy Me a Coffee at ko-fi.com
An error has occurred. This application may no longer respond until reloaded. Reload x