Back to Checks
m365

Conditional Access Policy enforces MFA for Azure Management API access

entra_conditional_access_policy_require_mfa_for_management_api
Service: entraSeverity: high
OfficialBuilt-inVerified
Categories:identity-accesse3
Resource Type:NotDefined

Microsoft Entra Conditional Access is verified to have at least one enabled policy that requires multifactor authentication for the Windows Azure Service Management API, covering Azure Portal, CLI, PowerShell, and IaC tools.

Risk

Without MFA on Azure management endpoints, compromised credentials allow control-plane access. Attackers can modify configurations, create or delete resources, extract secrets, and pivot laterally, compromising confidentiality, integrity, and availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler m365 --checks entra_conditional_access_policy_require_mfa_for_management_api

Recommendation

Enforce MFA via Conditional Access for the Windows Azure Service Management API scoped to all users. Prefer phishing-resistant methods, apply least privilege, and monitor sign-ins for anomalous activity. Only exclude dedicated break-glass accounts.

Remediation

Other

1In the Microsoft Entra admin center, go to Protection > Conditional Access > Policies.
2Click New policy.
3Under Users, select Include > All users.
4Under Target resources, select Include > Select resources > choose "Windows Azure Service Management API".
5Under Grant, select Grant access > check Require multifactor authentication > Select.
6Set Enable policy to On and click Create.

Check Code

from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.entra.entra_client import entra_client
from prowler.providers.m365.services.entra.entra_service import (
    ConditionalAccessGrantControl,
    ConditionalAccessPolicyState,
)

# Windows Azure Service Management API application ID
AZURE_MANAGEMENT_API_APP_ID = "797f4846-ba00-4fd7-ba43-dac1f8f63013"


class entra_conditional_access_policy_require_mfa_for_management_api(Check):
    """Check if at least one enabled Conditional Access policy requires MFA for Azure Management API.

    This check verifies that at least one enabled Conditional Access policy
    requires multifactor authentication (MFA) for the Windows Azure Service
    Management API (appId: 797f4846-ba00-4fd7-ba43-dac1f8f63013), which covers
    Azure Portal, Azure CLI, Azure PowerShell, and IaC tools.

    - PASS: At least one enabled CA policy requires MFA for Azure Management API.
    - FAIL: No enabled CA policy enforces MFA for Azure Management API access.
    """

    def execute(self) -> list[CheckReportM365]:
        """Execute the check logic.

        Returns:
            A list of reports containing the result of the check.
        """
        findings = []
        report = CheckReportM365(
            metadata=self.metadata(),
            resource={},
            resource_name="Conditional Access Policies",
            resource_id="conditionalAccessPolicies",
        )
        report.status = "FAIL"
        report.status_extended = (
            "No Conditional Access Policy requires MFA for Azure Management API."
        )

        for policy in entra_client.conditional_access_policies.values():
            if policy.state == ConditionalAccessPolicyState.DISABLED:
                continue

            if not policy.conditions.application_conditions:
                continue

            if (
                AZURE_MANAGEMENT_API_APP_ID
                not in policy.conditions.application_conditions.included_applications
                and "All"
                not in policy.conditions.application_conditions.included_applications
            ):
                continue

            if "All" not in policy.conditions.user_conditions.included_users:
                continue

            if (
                ConditionalAccessGrantControl.MFA
                not in policy.grant_controls.built_in_controls
            ):
                continue

            report = CheckReportM365(
                metadata=self.metadata(),
                resource=policy,
                resource_name=policy.display_name,
                resource_id=policy.id,
            )

            if policy.state == ConditionalAccessPolicyState.ENABLED_FOR_REPORTING:
                report.status = "FAIL"
                report.status_extended = f"Conditional Access Policy {policy.display_name} targets Azure Management API with MFA but is only in report-only mode."
            else:
                report.status = "PASS"
                report.status_extended = f"Conditional Access Policy {policy.display_name} requires MFA for Azure Management API."
                break

        findings.append(report)
        return findings