Back to Checks
m365

Multifactor authentication is enforced for all users

entra_users_mfa_enabled
Service: entraSeverity: critical
OfficialBuilt-inVerified
Categories:identity-accesse3
Resource Type:NotDefined

Microsoft Entra Conditional Access has an enforced policy requiring multifactor authentication for All users across All cloud apps (not just report-only).

Risk

Lacking an enforced, tenant-wide MFA mandate enables single-factor sign-ins to M365 apps. Stolen or sprayed passwords can yield access, leading to data exfiltration, unauthorized changes, and outages. Report-only or scoped policies leave gaps that undermine confidentiality, integrity, and availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler m365 --checks entra_users_mfa_enabled

Recommendation

Enforce a Conditional Access policy requiring MFA for All users and All cloud apps. Exclude only break-glass accounts, favor phishing-resistant or authenticator methods, and avoid long-term report-only. Monitor sign-ins, review coverage regularly, and apply least privilege and zero trust to minimize exceptions.

Remediation

Terraform

resource "azuread_conditional_access_policy" "<example_resource_name>" {
  display_name = "<example_resource_name>"
  state        = "enabled" # Critical: enforce policy (not report-only)

  conditions {
    users {
      included_users = ["All"] # Critical: target all users
    }
    applications {
      included_applications = ["All"] # Critical: target all cloud apps/resources
    }
  }

  grant_controls {
    built_in_controls = ["mfa"] # Critical: require multifactor authentication
  }
}

Other

1Sign in to Microsoft Entra admin center (https://entra.microsoft.com)
2Go to Protection > Conditional Access > Policies > Create new policy
3Users: Include > All users (do not add exclusions)
4Target resources: Resources (cloud apps) > Include > All resources (no exclusions)
5Access controls: Grant > Grant access > check Require multifactor authentication > Select
6Enable policy: On
7Create

Check Code

from typing import List

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,
)


class entra_users_mfa_enabled(Check):
    """
    Ensure multifactor authentication is enabled for all users.

    This check verifies that at least one Conditional Access Policy in Microsoft Entra, which is in an enabled state,
    requires multifactor authentication for all users.

    The check fails if no enabled policy is found that requires MFA for all users.
    """

    def execute(self) -> List[CheckReportM365]:
        """
        Execute the admin MFA requirement check for all users.

        Iterates over the Conditional Access Policies retrieved from the Entra client and generates a report
        indicating whether MFA is enforced for users in all users.

        Returns:
            List[CheckReportM365]: A list containing a single report with 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 enforces MFA for all users."
        )

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

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

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

            if (
                ConditionalAccessGrantControl.MFA
                in policy.grant_controls.built_in_controls
            ):
                report = CheckReportM365(
                    metadata=self.metadata(),
                    resource=entra_client.conditional_access_policies,
                    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}' reports MFA requirement for all users but does not enforce it."
                else:
                    report.status = "PASS"
                    report.status_extended = f"Conditional Access Policy '{policy.display_name}' enforces MFA for all users."
                    break

        findings.append(report)
        return findings