You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Microsoft Graph PowerShell SDK application requires users to have domain knowledge of both the semantics and syntax of Microsoft Graph API permissions used to authorize access to the API. There are two key permissions scenarios that present a challenge for users:
How do I find the values to supply to the permission-related parameters of commands like New-MgApplication and other application and consent related commands? Commands that allow the user to specify permissions like User.Read in order to grant those permissions to an application or ensure that the application requests those permissions offer a parameter to identify the permission(s) in question. While the user will be familiar with those permissions through their documented names like User.Read that are also used in many other user-facing contexts, the commands require that they be referred to not through the human readable name but by using a GUID identifier. Unfortunately, the identifiers are not documented, so there is no way for a user to tranlsate the intention of say granting an application User.Read to parameters that can be supplied to an MS Graph PowerShell SDK command-line. The workaround is for the user to perform the task using the Azure Portal which does allow the user to specify the human-readabl name, and once the application is configured other commands that read the configured permissions could return the GUIDs, allowing the user to "reverse-engineer" the friendly-name to GUID mappings.
What permissions should I ask for when I invoke the mandatory Connect-MgGraph command? To use Microsoft Graph PowerShell SDK to access Microsoft Graph, users must sign in to an Azure Active Directory application using the Connect-MgGraph command. Users must explicitly specify the permissions required for the API they are accessing when issuing the command. If a user fails to include required permissions when issuing the Connect-MgGraph command and those permissions have not already been consented to the application / user, subsequent commands that access the APIs authorized by those permissions will fail.
Currently PowerShell commands and scripts, including those implemented with Microsoft Graph PowerShell SDK itself have no way of validating user input that refers to permissions or providing "auto-complete" user experiences to help users accurately supply input to commands
Note that these cases are listed in priority order -- the first in particular is considered a blocking issue. The other two still have significant impact on user experience, but there are some less-productive workarounds that users may employ.
Solution
All three issues can be resolved through a solution that addresses the first issue, which is itself a blocking issue
Example 1: Find permissions related to a given domain
PS>Find-MgGraphPermission mailbox
PermissionType: Delegated
PermissionType Consent Name Description
------------------------------------
Delegated User MailboxSettings.Read Allows the app to the read user's mailbox settings. Does...Delegated User MailboxSettings.ReadWrite Allows the app to create, read, update, and delete user's...
PermissionType: Application
PermissionType Consent Name Description
------------------------------------
Application Admin MailboxSettings.Read Allows the app to read user's mailbox settings without a...Application Admin MailboxSettings.ReadWrite Allows the app to create, read, update, and delete user's...
Example 2: Find the identifier for a specific permission
PS>Find-MgGraphPermission User.Read |Format-List
PermissionType: Delegated
Id : e1fe6dd8-ba31-4d61-89e7-88639da4683d
PermissionType : Delegated
ConsentType : User
Name : User.Read
Description : Allows users to sign-in to the app, and allows the app to read the profile of signed-in users.
It also allows the app to read basic company information of signed-in users.
Implementation
To successfully execute, the command must be able to retrieve the following information:
The list of all delegated and app-only permissions
For each retrieved permission the following are needed:
The friendly name of the permission, i.e. User.Read
The permission identifier guid that may be used to grant consent through the application API
The kinds of consent that are allowed, i.e. consent by the signed-in user, or consent by by an administrator
Whether the consent is for the application only or delegated by the user to the application
Some basic description of the permission
Fortunately, it turns out that Microsoft Graph can actually find out the permissions it supports from... itself.
Using Microsoft Graph to get Microsoft Graph Permissions
The following approach described earlier on StackOverflow may be used to get both delegated and application permissions:
Sign in to any AAD organization
Note that this means the approach here will not work for Microsoft Accounts (more later)
TODO: What permission is needed on sign-in?
Make a REST request to MS Graph to get the service principal for the Microsoft Graph application -- an example of such a request using Microsoft Graph PowerShell is as follows:
$msgraphServicePrincipal=Invoke-MgGraphRequest-method GET 'https://graph.microsoft.com/v1.0/servicePrincipals?filter=appId eq ''00000003-0000-0000-c000-000000000000'''|select-object-expandproperty value
Parse the permissions from the serviceprincipal:
a. Obtain all of the delegated permissions by enumerating the elements of the oauth2PermissionScopes property of the aforementioned service principal
b. Obtain all of the application permissions by enumerating the elements of the appRoles property of the service principal
c. Note that these parsed permissions include the friendly name, the id of the permission such that it may be used win APIs that require permission id's (e.g. app creation / modification APIs), descriptions for user and application consent, and other information. Note that the elements of the appRoles and oauth2PermissionScopes properties have similar but not identical structure
Once the permissions are obtained, they may be searched based on user input, e.g. a user may want all permissions with mail in the name. Or they way want a permission with an exact name (e.g. User.Read exactly and not User.Read.All). They may even want to perform a "reverse" lookup by id instead of name. Perhaps they want to have the search include the descriptions in case the topic of the permission is not always described solely by the name.
Considerations
We should avoid making a REST request on every invocation of the command -- it likely only needs to be done once per PowerShell session. At most we should just cache it in memory after the first successful retrieval, or have a very long expiration on the cache. A force parameter is also an option to ensure the latest data.
We will likely need to have a static fallback built into the command for the following reasons:
There may be instances where the command is used but Connect-MgGraph has not been invoked (e.g. parameter completion of Connect-M gGraph itself). So we still need to give a good, if not perfect answer.
If you connect using a Microsoft Account rather than an AAD account, then it does not appear we can query the MS Graph service principal, and hence cannot obtain the permissions
Even if you are signing in to an AAD account, you may not have sufficient permissions to read the Microsoft Graph service principal
Fallback logic
When obtaining permissions data, the behavior should be as follows:
If the data were retrieved earlier from the directory (not the static file), the cached version should be used
Otherwise, we should try to get the data from the directory
If we retrieve data successfully from the directory, cache it so it can be used in future invocations
If we cannot get it for any reason, return back static file data
Exception: if the user specifies the online parameter, then try to get it from the directory only -- if we can't, the command should fail
If successful, the cached data should be updated
Failure here should not impact the state of the cached data -- it should not be cleared or otherwise reset if we fail
@peombwa , should it be Find-MgPermission or Find-MgGraphPermission?
This is good question. We should go with Find-MgGraphPermission to avoid potential conflict with a /permissions API in the future. This will also align nicely with existing commands such as Invoke-MgGraphRequest and Connect-MgGraph. See the discussion here on why we settled for Connect-MgGraph.
Uh oh!
There was an error while loading. Please reload this page.
Find-MgGraphPermission Command
Problem
The Microsoft Graph PowerShell SDK application requires users to have domain knowledge of both the semantics and syntax of Microsoft Graph API permissions used to authorize access to the API. There are two key permissions scenarios that present a challenge for users:
New-MgApplication
and other application and consent related commands? Commands that allow the user to specify permissions likeUser.Read
in order to grant those permissions to an application or ensure that the application requests those permissions offer a parameter to identify the permission(s) in question. While the user will be familiar with those permissions through their documented names likeUser.Read
that are also used in many other user-facing contexts, the commands require that they be referred to not through the human readable name but by using a GUID identifier. Unfortunately, the identifiers are not documented, so there is no way for a user to tranlsate the intention of say granting an applicationUser.Read
to parameters that can be supplied to an MS Graph PowerShell SDK command-line. The workaround is for the user to perform the task using the Azure Portal which does allow the user to specify the human-readabl name, and once the application is configured other commands that read the configured permissions could return the GUIDs, allowing the user to "reverse-engineer" the friendly-name to GUID mappings.Connect-MgGraph
command? To use Microsoft Graph PowerShell SDK to access Microsoft Graph, users must sign in to an Azure Active Directory application using theConnect-MgGraph
command. Users must explicitly specify the permissions required for the API they are accessing when issuing the command. If a user fails to include required permissions when issuing theConnect-MgGraph
command and those permissions have not already been consented to the application / user, subsequent commands that access the APIs authorized by those permissions will fail.Note that these cases are listed in priority order -- the first in particular is considered a blocking issue. The other two still have significant impact on user experience, but there are some less-productive workarounds that users may employ.
Solution
All three issues can be resolved through a solution that addresses the first issue, which is itself a blocking issue
Find-MgGraphPermission
Example 1: Find permissions related to a given domain
Example 2: Find the identifier for a specific permission
Implementation
To successfully execute, the command must be able to retrieve the following information:
User.Read
Fortunately, it turns out that Microsoft Graph can actually find out the permissions it supports from... itself.
Using Microsoft Graph to get Microsoft Graph Permissions
The following approach described earlier on StackOverflow may be used to get both delegated and application permissions:
a. Obtain all of the delegated permissions by enumerating the elements of the
oauth2PermissionScopes
property of the aforementioned service principalb. Obtain all of the application permissions by enumerating the elements of the
appRoles
property of the service principalc. Note that these parsed permissions include the friendly name, the
id
of the permission such that it may be used win APIs that require permission id's (e.g. app creation / modification APIs), descriptions for user and application consent, and other information. Note that the elements of theappRoles
andoauth2PermissionScopes
properties have similar but not identical structureUser.Read
exactly and notUser.Read.All
). They may even want to perform a "reverse" lookup byid
instead of name. Perhaps they want to have the search include the descriptions in case the topic of the permission is not always described solely by the name.Considerations
force
parameter is also an option to ensure the latest data.Connect-MgGraph
has not been invoked (e.g. parameter completion ofConnect-M gGraph
itself). So we still need to give a good, if not perfect answer.Fallback logic
When obtaining permissions data, the behavior should be as follows:
online
parameter, then try to get it from the directory only -- if we can't, the command should failReferences
AB#9941
The text was updated successfully, but these errors were encountered: