Back to Checks
azure

Privileged user has multi-factor authentication enabled

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

Microsoft Entra privileged accounts are expected to use multifactor authentication. This evaluates users assigned to elevated directory roles and confirms they have multiple authentication methods registered for sign-in.

Risk

Without MFA, privileged accounts face phishing, password spraying, and credential reuse risks. Compromise can grant tenant-wide admin control to alter roles, create backdoors, exfiltrate data, and weaken defenses, impacting confidentiality, integrity, and availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks entra_privileged_user_has_mfa

Recommendation

Enforce MFA for all privileged roles via Conditional Access or security defaults. Prefer phishing-resistant methods (FIDO2, passkeys, Authenticator push) over SMS/voice. Require registration before granting privileges, block legacy/basic auth, and apply least privilege with protected break-glass accounts.

Remediation

CLI

az rest --method post --url https://graph.microsoft.com/v1.0/users/<example_resource_id>/authentication/phoneMethods --body '{"phoneNumber":"+10000000000","phoneType":"mobile"}'

Terraform

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

  conditions {
    users {
      included_roles = ["<example_role_template_id>"]  # Critical: targets privileged role(s)
    }
    applications {
      included_applications = ["All"]
    }
  }

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

Other

1Sign in to Microsoft Entra admin center
2Go to Identity > Protection > Conditional Access > + New policy
3Name the policy
4Under Users > Select users and groups > Directory roles, select the privileged roles to protect
5Under Target resources (or Cloud apps), select All cloud apps
6Under Grant, select Grant access and check Require multifactor authentication
7Set Enable policy to On and click Create
8Have each privileged user go to https://myaccount.microsoft.com/security-info and add at least one MFA method (e.g., Microsoft Authenticator or phone) to complete registration

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.entra.entra_client import entra_client
from prowler.providers.azure.services.entra.lib.user_privileges import (
    is_privileged_user,
)


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

        for tenant_domain, users in entra_client.users.items():
            if tenant_domain in entra_client.users_retrieval_errors:
                report = Check_Report_Azure(metadata=self.metadata(), resource={})
                report.subscription = f"Tenant: {tenant_domain}"
                report.resource_name = tenant_domain
                report.resource_id = entra_client.tenant_ids[0]
                report.status = "MANUAL"
                report.status_extended = (
                    f"Cannot evaluate MFA for the tenant's privileged users for tenant {tenant_domain}: "
                    f"Microsoft Graph did not return the tenant's users "
                    f"({entra_client.users_retrieval_errors[tenant_domain]}). "
                    f"Retry the scan or review the tenant's users manually."
                )
                findings.append(report)
                continue

            for user_domain_name, user in users.items():
                if is_privileged_user(
                    user, entra_client.directory_roles[tenant_domain]
                ):
                    report = Check_Report_Azure(metadata=self.metadata(), resource=user)
                    report.subscription = f"Tenant: {tenant_domain}"
                    report.status = "FAIL"
                    report.status_extended = (
                        f"Privileged user {user.name} does not have MFA."
                    )

                    if user.is_mfa_capable:
                        report.status = "PASS"
                        report.status_extended = f"Privileged user {user.name} has MFA."

                    findings.append(report)

        return findings