Back to Checks
azure

Multifactor Authentication is required for Windows Azure Service Management API

entra_conditional_access_policy_require_mfa_for_management_api
Service: entraSeverity: medium
OfficialBuilt-inVerified
Categories:e3
Resource Type:NotDefined

Microsoft Entra Conditional Access is evaluated for a policy that requires multifactor authentication when accessing the Windows Azure Service Management API (Azure PowerShell, Azure CLI, Azure Resource Manager API, etc.). The check confirms an enabled policy targets All users, includes the Service Management API app, and enforces an MFA grant control.

Risk

Without MFA on the Service Management API, attackers with stolen credentials can use Azure CLI, PowerShell, or the Resource Manager API to modify infrastructure, escalate privileges, and exfiltrate data. This directly impacts confidentiality, integrity, and availability of all Azure resources managed through the API.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks entra_conditional_access_policy_require_mfa_for_management_api

Recommendation

  1. From the Azure Admin Portal dashboard, open Microsoft Entra ID. 2. Click Security in the Entra ID blade. 3. Click Conditional Access in the Security blade. 4. Click Policies in the Conditional Access blade. 5. Click + New policy. 6. Enter a name for the policy. 7. Click the blue text under Users. 8. Under Include, select All users. 9. Under Exclude, check Users and groups. 10. Select users or groups to be exempted from this policy (e.g. break-glass emergency accounts, and non-interactive service accounts) then click the Select button. 11. Click the blue text under Target Resources. 12. Under Include, click the Select apps radio button. 13. Click the blue text under Select. 14. Check the box next to Windows Azure Service Management APIs then click the Select button. 15. Click the blue text under Grant. 16. Under Grant access check the box for Require multifactor authentication then click the Select button. 17. Before creating, set Enable policy to Report-only. 18. Click Create. After testing the policy in report-only mode, update the Enable policy setting from Report-only to On.

Remediation

Terraform

resource "azuread_conditional_access_policy" "<example_resource_name>" {
  display_name = "<example_resource_name>"
  state        = "enabled"

  conditions {
    users {
      included_users = ["All"]
      excluded_users = ["<break_glass_account_id>"]
    }
    applications {
      included_applications = ["797f4846-ba00-4fd7-ba43-dac1f8f63013"]  # Critical: Windows Azure Service Management API
    }
  }

  grant_controls {
    operator          = "OR"
    built_in_controls = ["mfa"]  # Critical: requires MFA
  }
}

Other

1Sign in to the Microsoft Entra admin center
2Go to Protection > Conditional Access > Policies
3Click + New policy and enter a name
4Under Users > Include, select All users
5Under Exclude, check Users and groups and select break-glass / non-interactive service accounts
6Under Target resources > Include, click Select apps, then select Windows Azure Service Management API
7Under Grant, select Grant access and check Require multifactor authentication
8Set Enable policy to Report-only, click Create
9After testing, change Enable policy from Report-only to On

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.config import WINDOWS_AZURE_SERVICE_MANAGEMENT_API
from prowler.providers.azure.services.entra.entra_client import entra_client


class entra_conditional_access_policy_require_mfa_for_management_api(Check):
    def execute(self) -> Check_Report_Azure:
        findings = []

        for (
            tenant_name,
            conditional_access_policies,
        ) in entra_client.conditional_access_policy.items():
            for policy in conditional_access_policies.values():
                if (
                    policy.state == "enabled"
                    and "All" in policy.users["include"]
                    and WINDOWS_AZURE_SERVICE_MANAGEMENT_API
                    in policy.target_resources["include"]
                    and any(
                        "mfa" in access_control.lower()
                        for access_control in policy.access_controls["grant"]
                    )
                ):
                    report = Check_Report_Azure(
                        metadata=self.metadata(), resource=policy
                    )
                    report.subscription = f"Tenant: {tenant_name}"
                    report.status = "PASS"
                    report.status_extended = (
                        "Conditional Access Policy requires MFA for management API."
                    )
                    break
            else:
                report = Check_Report_Azure(
                    metadata=self.metadata(),
                    resource=conditional_access_policies,
                )
                report.subscription = f"Tenant: {tenant_name}"
                report.resource_name = "Conditional Access Policy"
                report.resource_id = "Conditional Access Policy"
                report.status = "FAIL"
                report.status_extended = (
                    "Conditional Access Policy does not require MFA for management API."
                )

            findings.append(report)

        return findings