Blog Post

Azure Integration Services Blog
2 MIN READ

Grant Graph API Permission to Managed Identity Object

Joyce_Dorothy's avatar
Joyce_Dorothy
Icon for Microsoft rankMicrosoft
Sep 28, 2021

Managed identities provide an identity for applications to use when connecting to resources that support Azure Active Directory (Azure AD) authentication. We can access Graph API either using service principal object in Azure or using Managed Identity.   

 

When it comes to service Principal, we can grant API Permissions to the service principal object in Azure but incase of Managed Identity, we do not have option to provide Graph API permission for Managed Identity object via portal.  Hence we need to use the below PowerShell script to grant Graph API Permission (Application Permission) to the managed Identity object.

 

 In this blog, we will see how to grant graph API permission to the Managed Identity object

 

Note: To provide Graph API Permission you need to be Global Administrator in Azure Active Directory

 

Below Parameters needs to be modified as per your resources:

  • TenantID : Provide the tenantID of your subscription
  • GraphAppId : This parameter is optional. We don’t have to change this value. This corresponds to Graph API Guid.
  • DisplayNameofMSI :  Provide your Logic App name. Since managed identity will be created in the same name as the resource on which identity is enabled, we can provide the Logic App name
  • Permissions : Provide the appropriate Graph API Permission. https://docs.microsoft.com/en-us/graph/permissions-reference. Note: These are application permission.

 

Powershell Script:

 

$TenantID="provide the tenant ID"

$GraphAppId = "00000003-0000-0000-c000-000000000000"

$DisplayNameOfMSI="Provide the Logic App name"

$PermissionName = "Directory.Read.All"

 

 

# Install the module

Install-Module AzureAD

 

Connect-AzureAD -TenantId $TenantID

$MSI = (Get-AzureADServicePrincipal -Filter "displayName eq '$DisplayNameOfMSI'")

Start-Sleep -Seconds 10

$GraphServicePrincipal = Get-AzureADServicePrincipal -Filter "appId eq '$GraphAppId'"

$AppRole = $GraphServicePrincipal.AppRoles | `

Where-Object {$_.Value -eq $PermissionName -and $_.AllowedMemberTypes -contains "Application"}

New-AzureAdServiceAppRoleAssignment -ObjectId $MSI.ObjectId -PrincipalId $MSI.ObjectId `

-ResourceId $GraphServicePrincipal.ObjectId -Id $AppRole.Id

 

 

Logic App:

 

 

 Execute the Powershell script to grant appropriate Graph API Permission to the Managed Identity object

 

 

 Once the Powershell is executed, you will be able to see the below Graph API permission added.

 

 

 

Updated Sep 28, 2021
Version 1.0

7 Comments

  • woter,

    I wanted to say your script was extremely helpful, though I made a few additional modifications to it since your version still contained the "Get-AzADServicePrincipal" command. MgGraph now has a command that fully replaces this one (Get-MgServicePrincipal), though I don't personally know whether this new MgGraph command was available at your time of writing or now. I know it exists now at least! I also added the required MgGraph scopes to the "Connect-MgGraph" command so it's known the prerequisite permissions in order to run this script without error. Hope this helps everyone!

     

     

    #Requires -Modules Microsoft.Graph.Applications
    $DestinationTenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # Azure Tenant ID, can be found at https://portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/Overview
    $MsiName = "ManagedIdentityName" # Name of system-assigned or user-assigned managed service identity. (System-assigned use same name as resource).
    
    $oAssignPermissions = @(
      "Files.Read.All"
      "Sites.Read.All"
    )
    
    $MgRequiredScopes = @(
        "Application.Read.All"
        "AppRoleAssignment.ReadWrite.All"
        "Directory.Read.All"
    )
    
    $GraphAppId = "00000003-0000-0000-c000-000000000000" # Don't change this. This is the immutable application ID of the Microsoft Graph service principal.
    
    Connect-MgGraph -TenantId $DestinationTenantId -Scopes $MgRequiredScopes #-NoWelcome #Uncomment NoWelcome if desired
    
    $oMsi = Get-MgServicePrincipal -Filter "displayName eq '$MsiName'"
    $oGraphSpn = Get-MgServicePrincipal -Filter "appId eq '$GraphAppId'"
    
    $oAppRole = $oGraphSpn.AppRoles | Where-Object {($_.Value -in $oAssignPermissions) -and ($_.AllowedMemberTypes -contains "Application")}
    
    foreach($AppRole in $oAppRole)
    {
      $oAppRoleAssignment = @{
        "PrincipalId" = $oMSI.Id
        "ResourceId" = $oGraphSpn.Id
        "AppRoleId" = $AppRole.Id
      }
      
      New-MgServicePrincipalAppRoleAssignment `
        -ServicePrincipalId $oAppRoleAssignment.PrincipalId `
        -BodyParameter $oAppRoleAssignment `
        -Verbose
    }

     

  • Marc013's avatar
    Marc013
    Copper Contributor

    woter,

     

    Great updated, thnx for sharing!

     

    On the note of 'requiring the pain of a certificate-based SPN'. You don't need one.

    I'm connecting to Microsoft Graph using a service principal with secret. Using pwsh module MSAL.PS you can obtain a token that can be used for signing in.

     

    $ClientSecret = ConvertTo-SecureString -String '<service principal secret>' -AsPlainText -Force
    $AppId = '<service principal app ID>'
    $TenantId = '<Azure AD tenant ID>'
    
    Import-Module -Name MSAL.PS -Force
    $MsalAccessToken = (Get-MsalToken -TenantId $TenantId -ClientId $AppId -ClientSecret $ClientSecret -ErrorAction Stop).AccessToken
    Connect-MgGraph -AccessToken $MsalAccessToken

     

  • woter's avatar
    woter
    Copper Contributor

     

    Joyce_Dorothy  Thank you for sharing.

     

    The cmdlets you're using are out of date. `AzureAD` doesn't work with PowerShell 7 and the new way is using Microsoft Graph.

     

    This is the new current way: https://stackoverflow.com/questions/72904838/how-to-set-microsoft-graph-api-permissions-on-azure-managed-service-identity-wit

     

     

    $DestinationTenantId = "a3186524-d3d5-4820-8cb5-9ad21badb14a"
    $MsiName = "myUserMSI" # Name of system-assigned or user-assigned managed service identity. (System-assigned use same name as resource).
    
    $oPermissions = @(
      "Directory.ReadWrite.All"
      "Group.ReadWrite.All"
      "GroupMember.ReadWrite.All"
      "User.ReadWrite.All"
      "RoleManagement.ReadWrite.Directory"
    )
    
    $GraphAppId = "00000003-0000-0000-c000-000000000000" # Don't change this.
    
    $oMsi = Get-AzADServicePrincipal -Filter "displayName eq '$MsiName'"
    $oGraphSpn = Get-AzADServicePrincipal -Filter "appId eq '$GraphAppId'"
    
    $oAppRole = $oGraphSpn.AppRole | Where-Object {($_.Value -in $oPermissions) -and ($_.AllowedMemberType -contains "Application")}
    
    Connect-MgGraph -TenantId $DestinationTenantId
    
    foreach($AppRole in $oAppRole)
    {
      $oAppRoleAssignment = @{
        "PrincipalId" = $oMSI.Id
        "ResourceId" = $oGraphSpn.Id
        "AppRoleId" = $AppRole.Id
      }
      
      New-MgServicePrincipalAppRoleAssignment `
        -ServicePrincipalId $oAppRoleAssignment.PrincipalId `
        -BodyParameter $oAppRoleAssignment `
        -Verbose
    }

     

    There is one major issue with the Microsoft.Graph PowerShell module. The Connect-MgGraph doesn't support -Credential, or PSCredential object for authentication, instead requiring the pain of a certificate-based SPN. A bug/feature request has been raised on Github: https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/1366.

    Please give it the thumbs up.

     

  • SocInABox's avatar
    SocInABox
    Iron Contributor

    Hi Jens, I had tried that in the past and it didn't seem to work, but thanks.

  • Jens Stolle's avatar
    Jens Stolle
    Copper Contributor

    Thanks Joyce_Dorothy , this was tremendously helpful!

     

    SocInABox try

    Get-AzureADServiceAppRoleAssignment -ObjectId (Get-AzureADServicePrincipal -Filter "appId eq '$GraphAppId'").ObjectID

    Does that do what you need?

  • SocInABox's avatar
    SocInABox
    Iron Contributor

    What is the 'Get' command to return the permissions what were assigned?

    You'd think Get-AzureAdServiceAppRoleAssignment would work but it's not returning any permissions for me.