How to add Graph api Roles to Managed Identity

suman saha
4 min readApr 3, 2023

--

In one of my previous stories, I touched upon how we can add permissions to a Managed Identity in the Azure AD. It was side-lined in a main story aiming for querying Azure AD objects from an automation account.

Recently, I had to use this technique more often for assigning permissions to managed identities created out of PaaS apps. So I thought to bring a dedicated story for this topic.

So far I couldn’t find a way to do this via azure portal. A PowerShell or azure cli script seems the available options.

Another advantage of this approach is that you don’t need to have a P1 or P2 license for this. It works with free tier as well.

Pre-Requisites

A Global Administrator will have to grant admin consent for these permissions.

Let’s build it up

I am using a consumption tier logic app with http trigger to get audit logs from azure ad. I will first develop the logic app, create an identity for it and then assign permissions to it.

Add a http trigger for ease of calling from postman or curl. For simplicity I am not putting any body payload to call this logic app.

Make an http call to graph endpoint https://graph.microsoft.com/v1.0/auditLogs/directoryAudits? with query parameter $filter=targetResources/any(s:s/type eq ‘Application’). This is just for fetching app registration related audit details only.

Set the authentication method of this rest call as managed identity with scope as https://graph.microsoft.com.

This block will look like this.

Finally return the output to the caller.

The logic app overall will look like this.

After creating the app, let’s turn on it’s system-assigned managed identity. Alternatively we can do an user assigned identity.

Next copy the object id and go to Azure AD. Search this id. You will find an enterprise app with name identical to the logic app.

If we come to the Permissions option under the security blade for this enterprise app, then we’d see nothing yet assigned to this.

Let’s assign some role using azure cli

Let’s login as GA to azure. I am using az login which will will open a web browser where we can put the necessary credentials.

az login

Then get the object id of the managed identity and also Microsoft Graph.

appName="Test-Logic-App-MSI-Role-Demo"

spId=$(az resource list -n $appName --query [*].identity.principalId --out tsv)

graphResourceId=$(az ad sp list --display-name "Microsoft Graph" --query [0].id --out tsv)

Then get the role id and assign it in a variable. Set a graph api uri and body json for making a rest call.

uri=https://graph.microsoft.com/v1.0/servicePrincipals/$spId/appRoleAssignments

appRoleId=$(az ad sp list --display-name "Microsoft Graph" --query "[0].appRoles[?value=='AuditLog.Read.All' && contains(allowedMemberTypes, 'Application')].id" --output tsv)

body="{'principalId':'$spId','resourceId':'$graphResourceId','appRoleId':'$appRoleId'}"

az rest --method post --uri $uri --body $body --headers "Content-Type=application/json"

After execution, this will add AuditLog.Read.All permission to the managed identity. This will allow the logic app to query Azure AD audit logs via Graph api.

The final output will be

{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('<id of the logic app's managed identity>')/appRoleAssignments/$entity",
"appRoleId": "b0afded3-3588-46d8-8b3d-9842eff778da",
"createdDateTime": "2023-04-02T23:36:28.3706758Z",
"deletedDateTime": null,
"id": "iG8SaL7ZoEGBv-AnZw_nN4n0sTXwRIxAjULoWPTERVo",
"principalDisplayName": "Test-Logic-App-MSI-Role-Demo",
"principalId": "<id of the logic app's managed identity>",
"principalType": "ServicePrincipal",
"resourceDisplayName": "Microsoft Graph",
"resourceId": "<id of Microsoft Graph>"
}

And if we revisit the permissions option under the security blade then we can see the new permission added.

Now once we call the logic app, we’ll get our audit data.

Here is the complete script

az login

appName="Test-Logic-App-MSI-Role-Demo" #put your app name here

spId=$(az resource list -n $appName --query [*].identity.principalId --out tsv)

graphResourceId=$(az ad sp list --display-name "Microsoft Graph" --query [0].id --out tsv)

uri=https://graph.microsoft.com/v1.0/servicePrincipals/$spId/appRoleAssignments

appRoleId=$(az ad sp list --display-name "Microsoft Graph" --query "[0].appRoles[?value=='AuditLog.Read.All' && contains(allowedMemberTypes, 'Application')].id" --output tsv)

body="{'principalId':'$spId','resourceId':'$graphResourceId','appRoleId':'$appRoleId'}"

az rest --method post --uri $uri --body $body --headers "Content-Type=application/json"

--

--

suman saha

Cloud Applications Developer | DevSecOps | Agile Practitioner