How to Figure Out What Microsoft Graph Permissions You Need

How to Figure Out What Microsoft Graph Permissions You Need

https://ift.tt/L9z5C24

When Working with the Microsoft Graph PowerShell SDK

By now, you should be aware that Microsoft plans to retire the Azure AD and MSOL PowerShell modules at the end of 2022 or soon after. The cmdlets in the retired modules will continue to function afterwards, but they won’t have any support. Microsoft suggests that you upgrade scripts to use cmdlets from the Microsoft Graph PowerShell SDK. The actual conversion is often a matter of finding a matching cmdlet in Microsoft’s cmdlet map and switching to it. However, other complexities get in the way before cmdlets will run smoothly. Figuring out the right Microsoft Graph API permissions to use to access data is just one of those complexities.

Least Permission Model

Permission handling differs significantly between the Azure AD PowerShell module and the Microsoft Graph PowerShell SDK. When you sign in using the Connect-AzureAD cmdlet, you can use all the administrative permissions owned by the account you sign in with. However, the Graph SDK operates on a least permission model, which means that you must request permissions to perform actions, even when connecting with a highly-permissioned account.

The first step in updating a script from Azure AD cmdlets to SDK cmdlets is to consider what permissions the script needs to perform its processing. This rule applies no matter how you use SDK cmdlets – interactively, through a background job which uses certificate-based authentication, or in an Azure Automation runbook. Unlike permissions inherited from signed-in accounts, the permissions used by the SDK are granted to the service principal used to run SDK cmdlets. For interactive sessions, the service principal is the Microsoft Graph

The question then arises how to find the Microsoft Graph API permissions necessary to perform an action. You can accomplish the goal in four ways:

Guess and Over-permission

The first method is a guess and hope approach. In other words, grant all the permissions that a script might conceivably use or keep on adding permissions until the code runs. The danger here is that you end up with a heavily-permissioned service principal that becomes an attractive target for attackers. If you use interactive sessions to run SDK cmdlets, a fair chance exists that the Microsoft Graph PowerShell service principal will acquire many permissions over time and end up in a heavily-permissioned state (Figure 1). We’ll return to this issue later.

The Microsoft Graph PowerShell service principal can accumulate permissionsMicrosoft Graph permissions
Figure 1: The Microsoft Graph PowerShell service principal can accumulate permissions

Use the Graph Explorer to Highlight Graph Permissions

Next, if you run a query in the Graph Explorer, the explorer shows you the permissions required to run the query in the Modify permissions tab (Figure 2). The set of permissions shown include every valid permission which you could use, so you need to select the most appropriate permission. In this case, the query is to fetch the set of user accounts in the tenant (one of the basic set of user account operations), so the User.Read.All permission is a good choice.

The Graph Explorer lists the Graph permissions needed for an action
Figure 2: The Graph Explorer lists the Graph permissions needed for an action

Read the Graph documentation

All SDK cmdlets originate from Graph queries. Microsoft uses a process called AutoRest to process available Graph queries and create SDK cmdlets. This process happens monthly to create a new version of the SDK. The process also creates automated documentation, but the machine-generated text is often obtuse and difficult to follow, which is why I often revert to the underlying Graph documentation. Take the example of listing user accounts. A quick search brings us to the List users page, which lists the required permissions for both delegated (used to access data as the signed-in user) and application (used for background processes). In this case, the page confirms that User.Read.All is a good choice.

Use SDK Help to Identify Graph Permissions

The SDK includes two cmdlets to help developers figure out what permissions they need to perform actions.

  • Find-MgGraphPermission: Lists the delegated and application permissions for different actions.
  • Find-MgGraphCommand: Lists the cmdlets available to interact with different types of objects, including the required permissions. The cmdlet works by taking the URI for an object to find the available commands.

For example, let’s assume that I want to interact with organization information stored in Azure AD. I could start by running the Find-MgGraphPermission cmdlet:

FindMgGraphPermission organization | ? {$_.PermissionType eq “Application”} | FormatList Name, Description

 

Name        : Organization.Read.All

Description : Allows the app to read the organization and related resources, on behalf of the signedin user. Related resources include things like subscribed skus and tenant branding information.

 

Name        : Organization.ReadWrite.All

Description : Allows the app to read and write the organization and related resources, on behalf of the signedin user. Related resources include things like subscribed skus and tenant branding information.

The command pipes its output to filter and display application permissions (the same delegated permissions are available). From the output, it’s obvious that we should use the Organization.Read.All permission to read organization information (like the tenant name and identifier), and Organization.ReadWrite.All should we need to update a writeable setting.

For brevity, I show only the permission name and description above. Here’s the full output for the Group.ReadWrite.All permission, needed to update the properties of Azure AD groups, including Microsoft 365 groups.

Id             : 62a82d7670ea41e29197370581804d09

PermissionType : Application

Consent        : Admin

Name           : Group.ReadWrite.All

Description    : Allows the app to create groups, read all group properties and memberships, update group properties and memberships, and delete groups. Also allows the app to read and write group calendar and conversations.  All of these operations can be performed by the app without a signedin user.

You could try a modified version of the commands to see what permissions are needed to interact with Users, Groups, Azure AD (Directory), Apps (Application), and so on.

The Find-MgGraphCommand cmdlet passes part of a Graph URL to see what SDK cmdlets are available for that URL. A URL is something like Users or Groups to list cmdlets available for dealing with sets of objects. If you add {id}, it means that you want to see the cmdlets available to process individual objects.

For example, let’s see what cmdlets are available to process individual groups. The command and its output are shown below:

FindMgGraphCommand uri “/groups/{id}” | ? {$_.APIVersion eq “v1.0”} | Fl Command, Method, Permissions

 

Command     : GetMgGroup

Method      : GET

Permissions : {Directory.AccessAsUser.All, Directory.Read.All, Directory.ReadWrite.All, Group.Read.All...}

 

Command     : RemoveMgGroup

Method      : DELETE

Permissions : {Directory.AccessAsUser.All, Group.ReadWrite.All}

 

Command     : UpdateMgGroup

Method      : PATCH

Permissions : {Directory.AccessAsUser.All, Directory.ReadWrite.All, Group.ReadWrite.All}

The Graph has two endpoints, V1.0 and beta. The V1.0 endpoint is the production version while the beta endpoint is under development. In many cases, you’ll use cmdlets with the beta endpoint because they provide added functionality. For example, if you run the Get-MgUser cmdlet against the V1.0 endpoint, it doesn’t return any license information for accounts, but it does when run against the beta endpoint.

In this case, I’ve filtered the output to show just the commands available in the V1.0 endpoint, and we can see that three cmdlets are available to list a group, delete a group, and update the properties of a group. We can also see that the Group.Read.All permission is sufficient to read group information, but we need Group.ReadWriteAll to delete or update a group.

Scoping

Once you’ve found out which Microsoft Graph API permissions are needed for a script to perform whatever actions it takes care of, you state the set of required permissions when connecting to the Graph in the Scopes parameter for the Connect-MgGraph cmdlet. For example:

$RequiredScopes = (“Organization.ReadWrite.All”, “Directory.Read.All)

ConnectMgGraph Scope $RequiredScopes

For interactive sessions, if the Microsoft Graph PowerShell service principal doesn’t have consent to use any of the requested permissions, you’ll be prompted for consent (Figure 3).

How to Figure Out What Microsoft Graph Permissions You Need
Figure 3: Requesting consent to use a Graph permission

If you allow the app to use the permission, the session can use the delegated version of the permission for the duration of the session. If you grant consent on behalf of the organization, Azure AD adds the permission to the service principal, and it becomes available for all sessions thereafter. Consent granted to the service principal is for a delegated permission, meaning that the user is limited to whatever data is permitted by the administrative roles assigned to their account.

After connecting, you can check what permissions are active by running:

Accumulated Graph Permissions

The constant accumulation of permissions by the Microsoft Graph PowerShell service principal is something to guard against. If you want to remove all the permissions from the service principal, you can do so through the Azure AD admin center (as in Figure 1), or you can remove the service principal. When this happens, the SDK detects that the service principal is missing the next time someone attempts to sign in and recreates it (the AppId for the service principal is always 14d82eec-204b-4c2f-b7e8-296a70dab67e).

To create the service principal, connect to the Graph with the Application.ReadWrite.All permission and run these commands:

The Remove-MgServicePrincipal cmdlet won’t prompt for confirmation. Fortunately, soon Azure AD will prove the ability to restore soft-deleted service principal objects, just in case you make a mistake.

$SDKServicePrincipalId = (GetMgServicePrincipal all | ? {$_.DisplayName eq “Microsoft Graph PowerShell”}).Id

RemoveMgServicePrincipal ServicePrincipalId $SDKServicePrincipalID

More Complex, More Control

Working with the Microsoft Graph PowerShell SDK requires more attention to permissions than is the norm (up to now) with PowerShell modules. Instead of assuming administrative permissions, you must request permissions and use just the required set. It takes a little getting used to and is part of the checklist for conversion of scripts based on the Azure AD and MSOL modules. Like most other things in life, we’ll get used to permission management for connections in time.

exchange

via Practical 365 https://ift.tt/5uM4pBF

April 12, 2022 at 02:02PM
Tony Redmond