Reputation: 118
Good day,
We are struggling horribly with our infrastructure-as-code journey. We have set up an Azure Container Apps environment and written a bicep script which sets up all needed resource (app with managed identity, key vault, app registration, etc) which all works fine. Problem is, the new app's managed identity needs to be granted a custom role in an Enterprise App, let's call it ExternalAPIProxy.
Granting custom roles is not something which is possible directly via Bicep, it seems, so we have added a step to run an azure client command in order to grant the role. And this is where things have come to an abrupt stop. We seems to be completely unable to set up the DevOps Service Principal running the script correctly in order to grant the role (this is one of many attempts, some involving PowerShell, but all lead to the same issue):
az rest
--method POST
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$managedIdentity/appRoleAssignments"
--headers 'Content-Type=application/json'
--body "{"principalId": "$managedIdentity", "resourceId": "$externalApiProxyId"}"
This leads to an error:
Forbidden({"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-02-07T13:42:38","request-id":"3a5d779a-3243-4684-9058-c3002837016f","client-request-id":"3a5d779a-3243-4684-9058-c3002837016f"}}})
Which role assignment does the service principal need to be able to grant a custom role? Is there a better way to do this?
We have tried many different ways of adding the role, but seem to get stuck on more or less the same step - which service/identity/user needs what kind of permission to grant custom application roles to the newly created app in azure container service? Fwiw, it's a bog standard .net rest API being deployed, but I do not think that's important in this context.
Upvotes: 0
Views: 212
Reputation: 15574
Note that: To assign app roles to the service principal, the user performing the action must be assigned Application Administrator or Privileged Role Administrator role or any one of the roles mentioned in this MsDoc
Initially I got the same error as below:(For sample, I executed the command in bash)
For sample:
az rest --method POST --uri "https://graph.microsoft.com/v1.0/servicePrincipals/ManagedIdentityId/appRoleAssignments" --headers "Content-Type=application/json" --body "{\"principalId\": \"PrincipalID\", \"resourceId\": \"ResourceID\", \"appRoleId\": \"AppRoleID\"}"
Hence to resolve the error, I assigned the user with Application Administrator active role like below:
Go to Azure Portal -> Microsoft Entra roles and administrators -> Click on Application Administrator -> Assign
It takes few minutes to reflect the role to the user, wait for around ~20 mins and login again to perform the task.
After assigning the role, the user is able to assign app role to the managed identity successfully:
If you are using Service Principal then assign role to the application.
Upvotes: 0
Reputation: 118
The comments by Rukmini allowed us to solve this, finally.
The Service Principal set up by/via Azure Devops to perform the release needed to be set up as ApplicationAdministrator in Azure Entra Id. Getting the correct Id was surprisingly hard, but the easiest way I found was to do use PowerShell
Get-MgServicePrincipalByAppId -AppId <appId found in the app registration overview page>
Once we had the Id, a quick id search in Entra Id lead to the correct service principal, which was then granted the Application Administrator role.
When the correct role was granted, this section of our deployment script worked flawlessly:
hasAccess=$(az rest \
--method GET \
--uri "https://graph.microsoft.com/v1.0/servicePrincipals/$managedIdentity/appRoleAssignments" \
| jq ".value|any(.resourceId == \"$externalApiProxyResourceId\" and .principalId == \"$managedIdentity\")") \
|| { echo "Failed check for role assignment. Stopping..."; exit 3; }
if [[ "$hasAccess" == "true" ]]; then
echo "App has role assignment. Skipping."
else
echo "Assigning app role assignment to app"
az rest \
--method POST \
--uri https://graph.microsoft.com/v1.0/servicePrincipals/$managedIdentity/appRoleAssignments" \
--headers 'Content-Type=application/json' \
--body "{\"principalId\": \"$managedIdentity\", \"resourceId\": \"$exerpProxyResourceId\"}"
fi
Upvotes: 0
Reputation: 13534
If you want to use a Service Principal as authorization to run the related command lines to assign custom role to a managed identity on an enterprise app, the Service Principal should have the Privileged Role Administrator or Global Administrator role at the Azure AD (Microsoft Entra ID) level.
For more details, see the following documentation:
Upvotes: 0