Multifactor authentication is enforced for all users
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 Cloudprowler m365 --checks entra_users_mfa_enabledRecommendation
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
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