Back to Checks
aws

Root account has MFA enabled

iam_root_mfa_enabled
Service: iamSeverity: critical
OfficialBuilt-inVerified
Categories:identity-access
Resource Type:AwsIamUser

AWS root user with active credentials is assessed for MFA activation. The evaluation considers whether the root identity has a password or access keys and whether MFA is enabled.

If centralized root access is enabled in Organizations, the presence of individual root credentials is also noted.

Risk

Without MFA, compromise of the root password or access keys can lead to full account takeover. An attacker with root can disable protections, steal or delete data, change billing, and create persistent admins, undermining confidentiality, integrity, and availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks iam_root_mfa_enabled

Recommendation

Enable MFA for the root user, preferably hardware-based or a dedicated, managed device. Remove root access keys and avoid using root for daily tasks. Apply least privilege with IAM Identity Center for admins, and use Organizations to centralize root access and eliminate long-lived root credentials.

Remediation

Other

1Sign in to the AWS Management Console as the root user (choose "Sign in as root user" and enter the account email)
2Open the account menu (top right) and click "Security credentials"
3In "Multi-factor authentication (MFA)", choose "Assign MFA device" (or "Activate MFA")
4Select "Authenticator app" and click "Next"
5Scan the QR code with your authenticator app and enter two consecutive MFA codes
6Click "Add MFA" (or "Assign MFA") to complete

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client


class iam_root_mfa_enabled(Check):
    def execute(self) -> Check_Report_AWS:
        findings = []

        if iam_client.credential_report:
            for user in iam_client.credential_report:
                if user["user"] == "<root_account>":
                    password_enabled = user["password_enabled"] == "true"
                    access_key_1_active = user["access_key_1_active"] == "true"
                    access_key_2_active = user["access_key_2_active"] == "true"

                    # Only report if root actually has credentials
                    if password_enabled or access_key_1_active or access_key_2_active:
                        report = Check_Report_AWS(
                            metadata=self.metadata(), resource=user
                        )
                        report.region = iam_client.region
                        report.resource_id = user["user"]
                        report.resource_arn = user["arn"]

                        # Check if organization manages root credentials
                        org_managed = (
                            iam_client.organization_features is not None
                            and "RootCredentialsManagement"
                            in iam_client.organization_features
                        )

                        if user["mfa_active"] == "false":
                            report.status = "FAIL"
                            if org_managed:
                                report.status_extended = (
                                    "Root account has credentials without MFA "
                                    "despite organizational root management being enabled."
                                )
                            else:
                                report.status_extended = (
                                    "MFA is not enabled for root account."
                                )
                        else:
                            report.status = "PASS"
                            if org_managed:
                                report.status_extended = (
                                    "Root account has credentials with MFA enabled. "
                                    "Consider removing individual root credentials since organizational "
                                    "root management is active."
                                )
                            else:
                                report.status_extended = (
                                    "MFA is enabled for root account."
                                )
                        findings.append(report)

        return findings