From 5b59986ae7d984fd7297f4545d4c7d83cb667b5d Mon Sep 17 00:00:00 2001 From: Sergio Garcia Date: Thu, 8 Jan 2026 09:04:04 +0100 Subject: [PATCH] docs(azure): enhance Managed Identity authentication documentation (#9012) Co-authored-by: Pepe Fagoaga Co-authored-by: Andoni A. <14891798+andoniaf@users.noreply.github.com> --- .../providers/azure/authentication.mdx | 213 +++++++++++++++++- 1 file changed, 212 insertions(+), 1 deletion(-) diff --git a/docs/user-guide/providers/azure/authentication.mdx b/docs/user-guide/providers/azure/authentication.mdx index 4e33da0775..57746e2d60 100644 --- a/docs/user-guide/providers/azure/authentication.mdx +++ b/docs/user-guide/providers/azure/authentication.mdx @@ -246,12 +246,223 @@ prowler azure --az-cli-auth *Available only for Prowler CLI* -Authenticate via Azure Managed Identity (when running on Azure resources): +Authenticate via Azure Managed Identity when running Prowler on Azure resources (VMs, Container Instances, Azure Functions, etc.): ```console prowler azure --managed-identity-auth ``` +### Prerequisites + +Before using Managed Identity authentication, the following steps are required: + +1. **Enable Managed Identity** on the Azure resource (e.g., VM, Container Instance) +2. **Assign the required permissions** to the Managed Identity on the target subscription(s) to scan + + +A common misconception is that enabling a Managed Identity on a resource automatically grants it permissions. **This is not the case.** Without explicit role assignments, Prowler will be unable to scan subscriptions and will return authorization errors, resulting in incomplete security assessments. The Managed Identity itself is a service principal that must be explicitly granted Reader and ProwlerRole permissions on each subscription to scan. + + +### Step-by-Step Setup Guide + +#### Step 1: Enable Managed Identity on the Azure Resource + + + + **Via Azure Portal:** + 1. Navigate to the VM in Azure Portal + 2. Select "Identity" from the left menu under "Security" + 3. Under "System assigned" tab, set Status to "On" + 4. Click "Save" + 5. Note the "Object (principal) ID" - this value is required for permission assignment + + **Via Azure CLI:** + ```console + # Enable system-assigned managed identity + az vm identity assign --name --resource-group + + # Get the principal ID + az vm identity show --name --resource-group --query principalId -o tsv + ``` + + + **Via Azure CLI:** + ```console + # Enable system-assigned managed identity + az container create \ + --resource-group \ + --name \ + --image \ + --assign-identity + + # Get the principal ID + az container show --resource-group --name --query identity.principalId -o tsv + ``` + + + +#### Step 2: Assign Reader Role to the Managed Identity + +The Managed Identity needs the **Reader** role on each subscription to scan. This role must be assigned to the **Managed Identity's principal ID**, not the VM or resource itself. + + + + 1. Navigate to the **target subscription** to scan (not the VM's resource group) + 2. Select "Access control (IAM)" from the left menu + 3. Click "+ Add" > "Add role assignment" + 4. Select "Reader" role, click "Next" + 5. Click "+ Select members" + 6. Search for the VM name or paste the Managed Identity's Object/Principal ID + 7. Select it and click "Select" + 8. Click "Review + assign" + + + When scanning a subscription different from where the VM is located, ensure the role is assigned on the **target subscription**, not the VM's subscription. + + + + ```console + # Get the principal ID of the resource's managed identity + PRINCIPAL_ID=$(az vm identity show --name --resource-group --query principalId -o tsv) + + # Assign Reader role on the target subscription + az role assignment create \ + --role "Reader" \ + --assignee-object-id $PRINCIPAL_ID \ + --assignee-principal-type ServicePrincipal \ + --scope /subscriptions/ + ``` + + + +#### Step 3: Create and Assign ProwlerRole to the Managed Identity + +The ProwlerRole is a custom role required for specific security checks. First, create the role if it does not exist, then assign it to the Managed Identity. + + + + **Create the ProwlerRole:** + ```console + az role definition create --role-definition '{ + "Name": "ProwlerRole", + "IsCustom": true, + "Description": "Role used for checks that require read-only access to Azure resources and are not covered by the Reader role.", + "AssignableScopes": ["/subscriptions/"], + "Actions": [ + "Microsoft.Web/sites/host/listkeys/action", + "Microsoft.Web/sites/config/list/Action" + ] + }' + ``` + + **Assign ProwlerRole to the Managed Identity:** + ```console + # Get the principal ID if not already available + PRINCIPAL_ID=$(az vm identity show --name --resource-group --query principalId -o tsv) + + # Assign ProwlerRole on the target subscription + az role assignment create \ + --role "ProwlerRole" \ + --assignee-object-id $PRINCIPAL_ID \ + --assignee-principal-type ServicePrincipal \ + --scope /subscriptions/ + ``` + + + Follow the same process as creating the ProwlerRole in the [Assigning ProwlerRole Permissions](/user-guide/providers/azure/authentication#assigning-prowlerrole-permissions-at-the-subscription-level) section, then assign it to the Managed Identity using the same steps as the Reader role assignment. + + + +#### Step 4: (Optional) Assign Microsoft Graph Permissions + +For Entra ID (Azure AD) checks, the Managed Identity needs Microsoft Graph API permissions: `Directory.Read.All`, `Policy.Read.All`, and optionally `UserAuthenticationMethod.Read.All`. + + +Assigning Microsoft Graph API permissions to a Managed Identity requires Azure CLI or PowerShell - it cannot be done through the Azure Portal's standard role assignment interface. + + +```console +# Get the Managed Identity's principal ID +PRINCIPAL_ID=$(az vm identity show --name --resource-group --query principalId -o tsv) + +# Get Microsoft Graph's service principal ID +GRAPH_SP_ID=$(az ad sp list --display-name "Microsoft Graph" --query [0].id -o tsv) + +# Assign Directory.Read.All permission (App Role ID: 7ab1d382-f21e-4acd-a863-ba3e13f7da61) +az rest --method POST \ + --uri "https://graph.microsoft.com/v1.0/servicePrincipals/$PRINCIPAL_ID/appRoleAssignments" \ + --headers "Content-Type=application/json" \ + --body "{\"principalId\": \"$PRINCIPAL_ID\", \"resourceId\": \"$GRAPH_SP_ID\", \"appRoleId\": \"7ab1d382-f21e-4acd-a863-ba3e13f7da61\"}" + +# Assign Policy.Read.All permission (App Role ID: 246dd0d5-5bd0-4def-940b-0421030a5b68) +az rest --method POST \ + --uri "https://graph.microsoft.com/v1.0/servicePrincipals/$PRINCIPAL_ID/appRoleAssignments" \ + --headers "Content-Type=application/json" \ + --body "{\"principalId\": \"$PRINCIPAL_ID\", \"resourceId\": \"$GRAPH_SP_ID\", \"appRoleId\": \"246dd0d5-5bd0-4def-940b-0421030a5b68\"}" +``` + +#### Step 5: Run Prowler + +SSH or connect to the Azure resource and run Prowler: + +```console +# Scan all accessible subscriptions +prowler azure --managed-identity-auth + +# Scan specific subscription(s) +prowler azure --managed-identity-auth --subscription-ids +``` + + +Wait a few minutes after assigning roles for Azure to propagate permissions. Role assignments are not always immediately effective. + + +### Troubleshooting + +#### Error: "No subscriptions were found, please check your permission assignments" + +**Cause:** The Managed Identity does not have the Reader role assigned on any subscription. + +**Solution:** +- Verify the Managed Identity has the Reader role assigned on at least one subscription. +- Wait a few minutes after role assignment for Azure to propagate permissions. +- Verify role assignments: + ```console + az role assignment list --assignee --all + ``` + +#### Error: "does not have authorization to perform action 'Microsoft.Resources/subscriptions/read'" + +**Cause:** The Managed Identity lacks the Reader role on the target subscription. + +**Solution:** +- Ensure the Reader role is assigned to the **Managed Identity's principal ID**, not the VM resource. +- Verify the role is assigned on the **target subscription** to scan, not just the VM's resource group. +- Check role assignments: + ```console + az role assignment list --assignee --scope /subscriptions/ + ``` + +#### Error: "CredentialUnavailableError: ManagedIdentityCredential authentication unavailable" + +**Cause:** Managed Identity is not enabled on the resource, or Prowler is running outside of Azure. + +**Solution:** +- Verify Managed Identity is enabled on the Azure resource. +- Ensure Prowler is running from within the Azure resource (not a local machine). +- Check Managed Identity status: + ```console + az vm identity show --name --resource-group + ``` + +#### Error: Access token validation failure for Entra ID checks + +**Cause:** The Managed Identity lacks Microsoft Graph API permissions. + +**Solution:** +- Assign the required Graph API permissions as shown in Step 4. +- These permissions are optional for basic resource scanning but required for Entra ID security checks. + ## Browser Authentication *Available only for Prowler CLI*