> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Root Account Should Have MFA and External ID Set

### More Info:

This rule identifies IAM roles that do not require multi-factor authentication (MFA) or external ID for assumed roles. Roles without MFA or external ID can pose security risks, as they may allow unauthorized access or increase the attack surface for potential breaches. Enforcing MFA and external ID requirements adds an additional layer of security to IAM roles and helps prevent unauthorized access.

### Risk Level

High

### Address

Security

### Compliance Standards

CBP

### Triage and Remediation

<Tabs>
  <Tab title="Prevention">
    ### How to Prevent

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To prevent the misconfiguration where the root account should have Multi-Factor Authentication (MFA) and an external ID set in AWS Identity and Access Management (IAM) using the AWS Management Console, follow these steps:

        1. **Enable MFA for the Root Account:**
           * Sign in to the AWS Management Console using your root account credentials.
           * Navigate to the **IAM** dashboard.
           * In the left navigation pane, select **Dashboard**.
           * Under **Security Status**, find the section labeled **Activate MFA on your root account** and click on **Manage MFA**.
           * Follow the on-screen instructions to enable MFA for the root account. You can choose between a virtual MFA device, a U2F security key, or other supported MFA devices.

        2. **Create an External ID for Cross-Account Access:**
           * Go to the **IAM** dashboard.
           * In the left navigation pane, select **Roles**.
           * Click on **Create role**.
           * Select **Another AWS account** as the type of trusted entity.
           * Enter the Account ID of the external account that will assume this role.
           * In the **Options** section, enter a unique **External ID**. This ID should be shared with the external account that will assume the role.
           * Click **Next: Permissions** to attach the necessary policies and complete the role creation process.

        3. **Review and Update IAM Policies:**
           * In the IAM dashboard, navigate to **Policies** in the left navigation pane.
           * Review existing policies to ensure they do not grant excessive permissions to the root account.
           * Update policies as necessary to follow the principle of least privilege.

        4. **Monitor and Audit IAM Activities:**
           * Enable AWS CloudTrail to log all API calls made in your AWS account.
           * Regularly review CloudTrail logs to monitor activities performed by the root account.
           * Set up AWS Config rules to continuously monitor and alert on any changes to the root account's MFA status or IAM roles.

        By following these steps, you can ensure that the root account in your AWS environment is secured with MFA and that an external ID is set for cross-account access, thereby reducing the risk of unauthorized access.
      </Accordion>

      <Accordion title="Using CLI">
        To prevent the misconfiguration where the root account should have Multi-Factor Authentication (MFA) and an External ID set in AWS Identity and Access Management (IAM) using AWS CLI, follow these steps:

        1. **Enable MFA on the Root Account:**
           * First, list the MFA devices associated with the root account to ensure none are already configured:
             ```sh theme={null}
             aws iam list-mfa-devices --user-name root
             ```
           * If no MFA devices are listed, you can enable MFA by creating a virtual MFA device and associating it with the root account. First, create the virtual MFA device:
             ```sh theme={null}
             aws iam create-virtual-mfa-device --virtual-mfa-device-name root-account-mfa --outfile /path/to/root-account-mfa.png
             ```
           * Then, enable the MFA device for the root account. You will need the authentication codes from the virtual MFA device:
             ```sh theme={null}
             aws iam enable-mfa-device --user-name root --serial-number arn:aws:iam::account-id:mfa/root-account-mfa --authentication-code1 123456 --authentication-code2 654321
             ```

        2. **Set an External ID for IAM Roles:**
           * Identify the IAM role that requires an external ID. List the roles to find the specific role:
             ```sh theme={null}
             aws iam list-roles
             ```
           * Update the trust policy of the IAM role to include an external ID. First, get the current trust policy:
             ```sh theme={null}
             aws iam get-role --role-name YourRoleName
             ```
           * Modify the trust policy JSON to include the `sts:ExternalId` condition. Here is an example of a trust policy with an external ID:
             ```json theme={null}
             {
               "Version": "2012-10-17",
               "Statement": [
                 {
                   "Effect": "Allow",
                   "Principal": {
                     "AWS": "arn:aws:iam::account-id:root"
                   },
                   "Action": "sts:AssumeRole",
                   "Condition": {
                     "StringEquals": {
                       "sts:ExternalId": "YourExternalID"
                     }
                   }
                 }
               ]
             }
             ```
           * Update the role with the modified trust policy:
             ```sh theme={null}
             aws iam update-assume-role-policy --role-name YourRoleName --policy-document file://path/to/modified-trust-policy.json
             ```

        3. **Verify MFA and External ID Configuration:**
           * Verify that the MFA device is enabled for the root account:
             ```sh theme={null}
             aws iam list-mfa-devices --user-name root
             ```
           * Verify the trust policy of the IAM role to ensure the external ID is set correctly:
             ```sh theme={null}
             aws iam get-role --role-name YourRoleName
             ```

        4. **Automate Checks Using AWS CLI Scripts:**
           * Create a script to periodically check and ensure that MFA is enabled and the external ID is set. Here is a simple example in Bash:
             ```sh theme={null}
             #!/bin/bash

             # Check MFA for root account
             MFA_DEVICES=$(aws iam list-mfa-devices --user-name root)
             if [ -z "$MFA_DEVICES" ]; then
               echo "MFA is not enabled for the root account."
             else
               echo "MFA is enabled for the root account."
             fi

             # Check External ID for a specific role
             ROLE_NAME="YourRoleName"
             TRUST_POLICY=$(aws iam get-role --role-name $ROLE_NAME)
             if echo $TRUST_POLICY | grep -q "sts:ExternalId"; then
               echo "External ID is set for the role $ROLE_NAME."
             else
               echo "External ID is not set for the role $ROLE_NAME."
             fi
             ```

        By following these steps, you can ensure that the root account has MFA enabled and that IAM roles have an external ID set, thereby preventing the misconfiguration using AWS CLI.
      </Accordion>

      <Accordion title="Using Python">
        To prevent the misconfiguration where the root account should have Multi-Factor Authentication (MFA) and an External ID set in IAM using Python scripts, you can follow these steps:

        ### 1. **Install Required Libraries**

        Ensure you have the necessary libraries installed. You will need `boto3` for AWS, `azure-identity` and `azure-mgmt-resource` for Azure, and `google-auth` and `google-api-python-client` for GCP.

        ```bash theme={null}
        pip install boto3 azure-identity azure-mgmt-resource google-auth google-api-python-client
        ```

        ### 2. **AWS: Enforce MFA on Root Account**

        ```python theme={null}
        import boto3

        def enforce_mfa_on_root():
            iam_client = boto3.client('iam')
            
            # List MFA devices for the root account
            mfa_devices = iam_client.list_mfa_devices(UserName='root')
            
            if not mfa_devices['MFADevices']:
                print("Root account does not have MFA enabled. Please enable MFA.")
            else:
                print("Root account has MFA enabled.")

        enforce_mfa_on_root()
        ```

        ### 3. **Azure: Enforce MFA on Root Account**

        Azure does not have a direct equivalent of a "root" account, but you can enforce MFA for all users in the directory.

        ```python theme={null}
        from azure.identity import DefaultAzureCredential
        from azure.mgmt.resource import ResourceManagementClient

        def enforce_mfa_on_root():
            credential = DefaultAzureCredential()
            client = ResourceManagementClient(credential, '<subscription_id>')
            
            # This is a placeholder for enforcing MFA. Azure AD Conditional Access policies should be used.
            print("Ensure that Conditional Access policies enforce MFA for all users.")

        enforce_mfa_on_root()
        ```

        ### 4. **GCP: Enforce MFA on Root Account**

        GCP also does not have a direct equivalent of a "root" account, but you can enforce MFA for all users in the organization.

        ```python theme={null}
        from google.oauth2 import service_account
        from googleapiclient.discovery import build

        def enforce_mfa_on_root():
            credentials = service_account.Credentials.from_service_account_file('path/to/your/service-account-file.json')
            service = build('admin', 'directory_v1', credentials=credentials)
            
            # This is a placeholder for enforcing MFA. GCP Identity Platform should be used.
            print("Ensure that Identity Platform enforces MFA for all users.")

        enforce_mfa_on_root()
        ```

        ### Summary

        1. **Install Required Libraries**: Ensure you have the necessary Python libraries installed.
        2. **AWS**: Use `boto3` to check and enforce MFA on the root account.
        3. **Azure**: Use `azure-identity` and `azure-mgmt-resource` to ensure Conditional Access policies enforce MFA.
        4. **GCP**: Use `google-auth` and `google-api-python-client` to ensure Identity Platform enforces MFA.

        These scripts provide a basic framework to check and enforce MFA on root accounts or equivalent in AWS, Azure, and GCP. For a complete solution, you would need to integrate these checks into your CI/CD pipeline or monitoring system.
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Cause">
    ### Check Cause

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        1. Sign in to the AWS Management Console as a root user or an IAM user.
        2. In the navigation pane, choose "Users". If the AWS account root user is signed in, the navigation pane is not available. In that case, choose "Dashboard" and then choose "Manage Security Credentials".
        3. In the "User" section, find the user that you want to check for MFA. In the "Security Credentials" column, look for a checkmark in the MFA column. If there's a checkmark, the user has MFA enabled. If there's no checkmark, the user doesn't have MFA enabled.
        4. To check for External ID, navigate to the IAM role that you want to check. Under the "Trust relationships" tab, click on "Edit trust relationship". In the policy document, look for "sts:ExternalId". If it's present, then the External ID is set. If it's not present, then the External ID is not set.
      </Accordion>

      <Accordion title="Using CLI">
        1. First, you need to install and configure AWS CLI on your local machine. You can do this by following the instructions provided by AWS. Once you have AWS CLI installed and configured, you can proceed to the next steps.

        2. To check if the root account has MFA enabled, you can use the following command:

           ```
           aws iam get-account-summary
           ```

           This command will return a JSON object that contains information about the account. Look for the "AccountMFAEnabled" field in the output. If the value of this field is 1, then MFA is enabled for the root account. If the value is 0, then MFA is not enabled.

        3. To check if the root account has an external ID set, you can use the following command:

           ```
           aws iam list-roles
           ```

           This command will return a list of all roles in the account. For each role, check the "AssumeRolePolicyDocument" field in the output. If the policy document contains a "sts:ExternalId" condition, then the role has an external ID set.

        4. If you want to automate these checks, you can write a Python script that uses the Boto3 library to interact with the AWS API. The script would use the `get_account_summary` and `list_roles` methods of the `IAM` client to perform the same checks as the CLI commands above.
      </Accordion>

      <Accordion title="Using Python">
        1. AWS SDK for Python (Boto3) can be used to interact with AWS services. To check if the root account has MFA enabled, you can use the IAM client in Boto3. First, you need to import Boto3 and create an IAM client:

        ```python theme={null}
        import boto3
        iam = boto3.client('iam')
        ```

        2. Then, you can use the `get_account_summary` method to get information about the account. This method returns a dictionary with various account attributes. The `AccountMFAEnabled` attribute indicates whether MFA is enabled for the root account:

        ```python theme={null}
        response = iam.get_account_summary()
        if response['SummaryMap']['AccountMFAEnabled'] == 1:
            print("MFA is enabled for the root account.")
        else:
            print("MFA is not enabled for the root account.")
        ```

        3. To check if the root account has an external ID set, you can use the `list_roles` method to get a list of all IAM roles in the account. Then, you can iterate over the roles and check the `AssumeRolePolicyDocument` attribute for each role. If the `sts:ExternalId` condition is present in the policy document, it means that the role requires an external ID for access:

        ```python theme={null}
        roles = iam.list_roles()['Roles']
        for role in roles:
            policy_document = role['AssumeRolePolicyDocument']
            if 'sts:ExternalId' in str(policy_document):
                print(f"Role {role['RoleName']} requires an external ID.")
        ```

        4. Note that the above script only checks if any role in the account requires an external ID. It does not check if the root account specifically has an external ID set. This is because the root account does not have an associated IAM role and therefore does not have an `AssumeRolePolicyDocument`. The external ID is typically used in a cross-account role scenario, where one AWS account assumes a role in another account. In this case, the external ID is set in the trusting account (the account that owns the role), not in the trusted account (the account that assumes the role).
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate the misconfiguration in AWS IAM where the root account should have MFA and External ID set, follow these steps using the AWS Management Console:

        1. **Enable Multi-Factor Authentication (MFA) for the Root Account**:
           * Log in to the AWS Management Console using the root account credentials.
           * Navigate to the IAM service.
           * In the navigation pane, click on "Users".
           * Click on the root account username.
           * In the "Security credentials" tab, locate the "Assigned MFA device" section and click on "Manage".
           * Follow the prompts to set up MFA for the root account. You can choose to use a virtual MFA device or a hardware MFA device.
           * Once MFA is enabled, make sure to complete the MFA setup process.

        2. **Set an External ID for the Root Account**:
           * While still in the IAM Management Console, click on the root account username.
           * In the "Permissions" tab, click on the "Add inline policy" button.
           * Select the JSON tab to provide a custom policy.
           * Enter a policy document similar to the following, replacing `YOUR_EXTERNAL_ID` with your desired external ID:
           ```
           {
               "Version": "2012-10-17",
               "Statement": [
                   {
                       "Effect": "Allow",
                       "Action": "*",
                       "Resource": "*",
                       "Condition": {
                           "StringEquals": {
                               "sts:ExternalId": "YOUR_EXTERNAL_ID"
                           }
                       }
                   }
               ]
           }
           ```
           * Click on Review policy, provide a name for the policy, and click on "Create policy".

        3. **Test the External ID**:
           * To test the External ID, you can try to assume a role that requires the External ID. If the External ID is set correctly, the assumption of the role should succeed.

        By following these steps, you will have successfully remediated the misconfiguration in AWS IAM where the root account should have MFA and an External ID set.

        #
      </Accordion>

      <Accordion title="Using CLI">
        To remediate the misconfiguration of the root account not having MFA and External ID set in AWS IAM using AWS CLI, follow these steps:

        1. **Enable MFA for Root Account**:
           * Run the following AWS CLI command to enable MFA for the root account:
             ```
             aws iam enable-mfa-device --user-name <root_account_username> --serial-number arn:aws:iam::<account_id>:mfa/root-account-mfa
             ```
             Replace `<root_account_username>` with the root account's username and `<account_id>` with your AWS account ID.

        2. **Set External ID for Root Account**:
           * Generate a random external ID using a tool like `openssl`:
             ```
             openssl rand -hex 32
             ```
           * Copy the generated External ID.

        3. **Attach the Policy to the Root Account**:
           * Run the following AWS CLI command to attach the `IAMFullAccess` policy to the root account with the External ID:
             ```
             aws iam attach-user-policy --user-name <root_account_username> --policy-arn arn:aws:iam::aws:policy/IAMFullAccess --policy-inputs '{"ExternalId":"<generated_external_id>"}'
             ```
             Replace `<root_account_username>` with the root account's username and `<generated_external_id>` with the External ID you generated in step 2.

        4. **Verify Configuration**:
           * To verify that MFA and External ID are set for the root account, run the following AWS CLI commands:
             * Check MFA status:
               ```
               aws iam list-mfa-devices --user-name <root_account_username>
               ```
             * Check attached policies with External ID:
               ```
               aws iam list-attached-user-policies --user-name <root_account_username>
               ```

        By following these steps, you can remediate the misconfiguration of the root account not having MFA and External ID set in AWS IAM using AWS CLI.
      </Accordion>

      <Accordion title="Using Python">
        To remediate the misconfiguration in AWS IAM where the root account should have MFA and External ID set, you can use the AWS SDK for Python (Boto3) to automate the process. Here are the step-by-step instructions to remediate this issue:

        1. **Install Boto3**:
           If you haven't installed Boto3 yet, you can install it using pip:
           ```
           pip install boto3
           ```

        2. **Create a Python script**:
           Create a Python script (e.g., `remediate_root_account_mfa.py`) and import the necessary libraries:
           ```python theme={null}
           import boto3
           ```

        3. **Enable MFA for the root account**:
           You can use the following code snippet to enable MFA for the root account:
           ```python theme={null}
           iam_client = boto3.client('iam')
           iam_client.enable_mfa_device(UserName='root', SerialNumber='arn:aws:iam::aws:policy/IAMUser')
           ```

        4. **Set External ID for the root account**:
           You can use the following code snippet to set an External ID for the root account:
           ```python theme={null}
           account_id = boto3.client('sts').get_caller_identity().get('Account')
           external_id = 'your_external_id_here'

           iam_client.create_account_alias(AccountAlias=external_id)
           ```

        5. **Run the Python script**:
           Execute the Python script using the command:
           ```
           python remediate_root_account_mfa.py
           ```

        By following these steps, you can remediate the misconfiguration in AWS IAM where the root account should have MFA and External ID set using Python and Boto3.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
