> ## 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.

# OCI IAM Users Should Have MFA Enabled

### More Info:

All active IAM users should have Multi-Factor Authentication (MFA) enabled. MFA significantly reduces the risk of account compromise from phishing, credential stuffing, and password reuse attacks.

### Risk Level

High

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* AWS Startup Security Baseline
* AWS Well Architected Framework
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS AWS
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* Cloudanix Best Practice
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* GDPR
* HIPAA
* ISO 27001
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* PCI
* Reserve Bank of India (RBI) Master Direction – Information Technology Framework
* SOC2
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are concise, console-based steps to remediate “OCI IAM Users Should Have MFA Enabled” by enforcing MFA for users, so that any IAM Monitoring/Cloud Guard detector for non‑MFA users will clear.

        > Note: OCI now uses **Identity Domains** for IAM. Steps differ slightly for “local users” (older model) vs identity-domain users. I’ll outline both; use the one that matches what you see in your console.

        ***

        ## 1. For Identity Domains (Most Current Tenancies)

        ### A. Enroll Users in MFA

        1. Sign in to the **OCI Console** as an administrator.
        2. Open the **Navigation menu** → **Identity & Security** → **Domains**.
        3. Click the **Identity Domain** where your users reside (often the default domain).
        4. In the domain left menu, go to **User Management** → **Users**.
        5. Click a user you want to remediate.
        6. Scroll to or open the **Security** / **Multi-Factor Authentication** section:
           * If “MFA Devices” or “Factors” are present, ensure at least one factor is configured (e.g., TOTP/Authenticator app, SMS if available).
           * If not configured, inform the user to:
             * Sign in to OCI.
             * Click their **user avatar (top right)** → **Profile**.
             * Under **Multi-Factor Authentication**, click **Add Device** or similar.
             * Register an **authenticator app** (Google Authenticator, Microsoft Authenticator, etc.) following the QR code + 6‑digit code steps.

        > Users must complete this themselves; you can only enforce MFA and, in some cases, reset MFA.

        ***

        ### B. Enforce MFA with Sign‑On Policy (Tenancy‑Wide / Group‑Based)

        1. Still in the **Identity Domain**, in the left menu go to **Security** → **Sign-on Policies**.
        2. Either:
           * Edit the **Default Sign-on Policy**, or
           * Click **Create sign-on policy** to make a new one (recommended if you want gradual rollout).
        3. In the policy:
           * Add a **Rule** (or edit an existing one) that applies to:
             * **Users**: all users, or target a specific **Group** (e.g., admins) using conditions.
           * In the **Actions** section, set **Prompt for second factor (MFA)** = **Required**.
           * Optionally, configure:
             * **Conditions** like IP range, device, network, etc. if you want conditional MFA.
        4. Click **Save** or **Create** and ensure the policy is **Enabled**.
        5. Test with a non‑admin test account:
           * Log out, log in with the test user.
           * Confirm that, after password, the user is required to set up or use MFA.

        Once MFA is enforced, any IAM Monitoring / Cloud Guard detectors for “user without MFA” will begin to show these users as compliant once they complete enrollment.

        ***

        ## 2. For Older “Local Users” (No Identity Domains UI)

        If your tenancy still shows **Identity → Users** directly, use these steps:

        ### A. Enroll MFA for Local Users

        1. In the **OCI Console**, click your **user avatar (top right)** → **User Settings**.
        2. Under **Multi-Factor Authentication**, click **Enable Multi-Factor Authentication** or **Add Device**.
        3. Follow the prompts to set up:
           * An **authenticator app** (scan QR code, enter 6‑digit code).
        4. Each local user must repeat these steps for their own account.

        > Admins cannot completely finish MFA setup on behalf of users; users must scan and confirm.

        ### B. Monitor / Enforce (Cloud Guard / IAM Monitoring)

        To support the “OCI IAM Users Should Have MFA Enabled” rule:

        1. Go to **Navigation menu** → **Identity & Security** → **Cloud Guard**.
        2. Ensure Cloud Guard is **Enabled** in your region.
        3. Open your **Detector Recipe** (or create one) and verify that:
           * The relevant detector for **IAM user without MFA** (names vary; look under IAM / Authentication) is **Enabled** and **Attached** to your target (tenancy / compartment).
        4. For any flagged user in **Cloud Guard → Problems**:
           * Notify the user to follow the MFA enablement steps above.
           * After they enable MFA and re‑authenticate, the problem will eventually move to **Resolved** state.

        ***

        ## 3. Quick Checklist

        * [ ] MFA enrollment instructions sent to all affected users.
        * [ ] Identity Domain **Sign-on Policy** created/updated to require MFA.
        * [ ] Policy tested with a non‑admin test user.
        * [ ] Cloud Guard / IAM Monitoring detector recipe enabled for “Users without MFA”.
        * [ ] Confirm that previously flagged users show as compliant after MFA enrollment.

        If you tell me whether your tenancy uses Identity Domains (you see “Domains” in the menu) or only “Identity → Users”, I can give you an even more exact click‑path for your specific layout.
      </Accordion>

      <Accordion title="Using CLI">
        Below is how you can remediate **“OCI IAM Users Should Have MFA Enabled”** using **OCI CLI**, focused on *monitoring and identifying* non‑MFA users (which is what Cloud Guard / IAM monitoring rules usually need).

        Enabling MFA itself always requires a user interaction (scanning QR / entering OTP), so you **cannot fully enable MFA purely by CLI**; you can only prepare and enforce it and monitor which users are non‑compliant.

        ***

        ## 1. Prerequisites

        * OCI CLI installed and configured (`oci setup config` done).
        * Permissions to:
          * `inspect`/`read` users in the tenancy.
          * `inspect`/`read` MFA devices (for non–identity-domain IAM).
          * Or `read` identity domains and users (for identity domains).

        Run once to confirm region and tenancy:

        ```bash theme={null}
        oci iam compartment list --all
        ```

        If this returns compartments, CLI is working.

        ***

        ## 2. Detect IAM Users Without MFA (Traditional “local IAM” Tenancy)

        ### 2.1. List all IAM users

        ```bash theme={null}
        TENANCY_OCID="<your_tenancy_ocid>"

        oci iam user list \
          --compartment-id "$TENANCY_OCID" \
          --all \
          --query "data[].{name:\"name\", id:\"id\", lifecycle_state:\"lifecycle-state\"}" \
          --output table
        ```

        Filter for active users only:

        ```bash theme={null}
        oci iam user list \
          --compartment-id "$TENANCY_OCID" \
          --all \
          --query "data[?\"lifecycle-state\"=='ACTIVE'].{name:\"name\", id:\"id\"}" \
          --output json > users.json
        ```

        ### 2.2. For each user, check whether a TOTP MFA device exists

        ```bash theme={null}
        jq -r '.[].id' users.json | while read USER_OCID; do
          MFA_COUNT=$(oci iam mfa-totp-device list \
            --user-id "$USER_OCID" \
            --query "data | length(@)" \
            --output json)

          if [ "$MFA_COUNT" -eq 0 ]; then
            USER_NAME=$(oci iam user get --user-id "$USER_OCID" \
              --query "data.name" --raw-output)
            echo "User WITHOUT MFA: $USER_NAME ($USER_OCID)"
          fi
        done
        ```

        This gives you a list of IAM users that do **not** have an MFA TOTP device associated.

        You can store that list:

        ```bash theme={null}
        jq -r '.[].id' users.json | while read USER_OCID; do
          MFA_COUNT=$(oci iam mfa-totp-device list \
            --user-id "$USER_OCID" \
            --query "data | length(@)" \
            --output json)

          if [ "$MFA_COUNT" -eq 0 ]; then
            USER_NAME=$(oci iam user get --user-id "$USER_OCID" \
              --query "data.name" --raw-output)
            echo "{\"userName\":\"$USER_NAME\",\"userId\":\"$USER_OCID\"}" >> users_without_mfa.jsonl
          fi
        done
        ```

        ***

        ## 3. Detect Users Without MFA in an Identity Domain

        If your tenancy uses **identity domains** (recommended modern setup):

        ### 3.1. List identity domains

        ```bash theme={null}
        oci iam identity-domain list \
          --compartment-id "$TENANCY_OCID" \
          --all \
          --query "data[].{name:\"display-name\", id:\"id\"}" \
          --output table
        ```

        Pick the domain id:

        ```bash theme={null}
        DOMAIN_OCID="<your_identity_domain_ocid>"
        ```

        ### 3.2. List users in the identity domain

        ```bash theme={null}
        oci iam identity-domain user list \
          --identity-domain-id "$DOMAIN_OCID" \
          --all \
          --query "resources[?active==true].{id:id, userName:userName}" \
          --output json > domain_users.json
        ```

        ### 3.3. Check MFA factor enrollment per user

        In identity domains, MFA status is reflected in `urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User` or factor-related attributes. A simple way is to fetch per user:

        ```bash theme={null}
        jq -r '.[].id' domain_users.json | while read USER_ID; do
          USER_JSON=$(oci iam identity-domain user get \
            --identity-domain-id "$DOMAIN_OCID" \
            --user-id "$USER_ID" \
            --output json)

          MFA_ENABLED=$(echo "$USER_JSON" | \
            jq -r '.["urn:ietf:params:scim:schemas:oracle:idcs:extension:user:User"].mfaEnabled // false')

          if [ "$MFA_ENABLED" != "true" ]; then
            USER_NAME=$(echo "$USER_JSON" | jq -r '.userName')
            echo "User WITHOUT MFA: $USER_NAME ($USER_ID)"
          fi
        done
        ```

        (If `mfaEnabled` is not present in your domain, you may need to inspect the `idcs` extension schema for factors like `mfaFactors`/`devices` and adapt the `jq` filter.)

        ***

        ## 4. Enforce MFA Requirement via Policies (Preventive Control)

        You cannot “flip” MFA on for a user via CLI, but you can **enforce** that interactive sign‑ins use MFA:

        ### 4.1. For identity domains – enable MFA requirement on sign‑on policy

        1. Identify the sign‑on policy:

        ```bash theme={null}
        oci iam identity-domain security-setting list \
          --identity-domain-id "$DOMAIN_OCID" \
          --all \
          --output json
        ```

        Look for `mfaSettings` or similar. If your domain has specific sign-on policies, list them:

        ```bash theme={null}
        oci iam identity-domain sign-on-policy list \
          --identity-domain-id "$DOMAIN_OCID" \
          --all \
          --output json
        ```

        2. Update the sign-on policy to require MFA (example only – structure can vary):

        ```bash theme={null}
        SIGNON_POLICY_ID="<sign_on_policy_id>"

        oci iam identity-domain sign-on-policy update \
          --identity-domain-id "$DOMAIN_OCID" \
          --sign-on-policy-id "$SIGNON_POLICY_ID" \
          --from-json '{
            "schemas":["urn:ietf:params:scim:schemas:oracle:idcs:SignOnPolicy"],
            "rules":[
              {
                "name":"Require MFA",
                "condition":"true",
                "actions":[ { "type":"MFA", "require":"true" } ]
              }
            ]
          }'
        ```

        Adjust JSON to match your existing rules rather than overwriting blindly.

        ***

        ## 5. Link This to “OCI IAM Monitoring” (Cloud Guard / Security Zones)

        In Cloud Guard or IAM Security posture checks:

        1. Use the above **CLI scripts** in a scheduled job (e.g. OCI Functions, OCI DevOps, or an external system) to:
           * Generate a list of users without MFA.
           * Push metrics to OCI Monitoring / logs to Logging or send notifications via Notifications service.

        2. Create **alarms** or Cloud Guard custom detectors that trigger on:
           * Logs (e.g. “user\_without\_mfa” entries).
           * Or a metric you emit (e.g. `iam.non_mfa_users.count`).

        This lets “IAM Monitoring” show non‑MFA users and raise alerts, and your sign‑on policy enforces MFA for future logins.

        ***

        If you share whether you’re using **classic IAM** or **identity domains**, I can adjust the exact CLI and `jq` filters to match your environment.
      </Accordion>

      <Accordion title="Using Python">
        Below is a step‑by‑step approach to **detect and remediate IAM users without MFA in OCI, using Python**.

        ***

        ## 1. Prerequisites

        1. Install OCI Python SDK:
           ```bash theme={null}
           pip install oci
           ```

        2. Configure OCI CLI credentials (SDK uses the same config):
           ```bash theme={null}
           oci setup config
           ```
           Note the **tenancy\_ocid**, **user\_ocid**, **fingerprint**, **key\_file**, and **region**.

        3. The user/instance you use for this script must have IAM permissions like:
           ```text theme={null}
           Allow group <group_name> to manage users in tenancy
           ```

        ***

        ## 2. What You Can Do via API

        For each IAM user:

        * Inspect MFA status via `user.capabilities.mfa_activated`.
        * Allow/force the ability to use MFA via `can_use_mfa` (but the user must still enroll using an authenticator).

        So remediation is:

        1. Detect users with `mfa_activated == False`.
        2. Ensure `can_use_mfa == True` for them.
        3. Optionally: notify or disable users who still don’t enroll after a grace period.

        ***

        ## 3. Basic Python Script – Detect & Enable MFA Capability

        This script:

        * Lists all users in the tenancy.
        * Filters to those that are ACTIVE and **do not have MFA activated**.
        * Sets `can_use_mfa = True` for those users.

        ```python theme={null}
        import oci

        def get_identity_client(config_profile="DEFAULT"):
            config = oci.config.from_file("~/.oci/config", config_profile)
            return oci.identity.IdentityClient(config), config["tenancy"]

        def list_all_users(identity_client, tenancy_ocid):
            users = []
            response = identity_client.list_users(tenancy_ocid, limit=1000)
            users.extend(response.data)
            while response.has_next_page:
                response = identity_client.list_users(
                    tenancy_ocid,
                    limit=1000,
                    page=response.next_page
                )
                users.extend(response.data)
            return users

        def remediate_mfa(identity_client, users, dry_run=True):
            for user in users:
                # Only ACTIVE users
                if user.lifecycle_state != "ACTIVE":
                    continue

                caps = user.capabilities
                mfa_activated = getattr(caps, "mfa_activated", None)
                can_use_mfa = getattr(caps, "can_use_mfa", None)

                # Skip if MFA is already active
                if mfa_activated:
                    continue

                # If can_use_mfa is already True, user just hasn’t enrolled
                if can_use_mfa:
                    print(f"[INFO] {user.name} can use MFA but has not activated it yet.")
                    continue

                print(f"[REMEDIATE] Enabling MFA capability for user: {user.name} ({user.id})")

                if not dry_run:
                    update_details = oci.identity.models.UpdateUserCapabilitiesDetails(
                        can_use_mfa=True
                    )
                    identity_client.update_user_capabilities(
                        user_id=user.id,
                        update_user_capabilities_details=update_details
                    )

        def main():
            identity_client, tenancy_ocid = get_identity_client("DEFAULT")
            users = list_all_users(identity_client, tenancy_ocid)

            # 1) DRY RUN – see what would change
            print("=== DRY RUN: users that will be updated ===")
            remediate_mfa(identity_client, users, dry_run=True)

            # 2) REAL RUN – uncomment when ready
            # print("=== REAL RUN: applying changes ===")
            # remediate_mfa(identity_client, users, dry_run=False)

        if __name__ == "__main__":
            main()
        ```

        ***

        ## 4. Turn This Into “Monitoring”

        ### Option A – Cron / Scheduled Job

        1. Put this script on a bastion host or CI runner.

        2. Run periodically via cron, e.g.:

           ```bash theme={null}
           crontab -e
           ```

           ```cron theme={null}
           # Run every hour
           0 * * * * /usr/bin/python3 /path/to/oci_mfa_remediation.py >> /var/log/oci_mfa.log 2>&1
           ```

        3. Keep `dry_run=True` if you only want monitoring and logging, or `False` for auto‑remediation.

        ### Option B – Log / Notification Integration

        Extend the script to:

        * Send an email/Slack message when users without MFA are found.
        * Or write JSON output to a file/stream that another system ingests.

        Example (very minimal) JSON print for SIEM ingestion:

        ```python theme={null}
        import json

        def report_non_mfa_users(users):
            report = []
            for user in users:
                if user.lifecycle_state == "ACTIVE" and not user.capabilities.mfa_activated:
                    report.append({
                        "user_name": user.name,
                        "user_ocid": user.id,
                        "can_use_mfa": user.capabilities.can_use_mfa
                    })
            print(json.dumps(report, indent=2))

        # Call this in main() after listing users
        ```

        ***

        ## 5. Recommended Policy Approach (Optional)

        For stricter enforcement:

        * Use IAM policies and conditional access (in identity domains) to require MFA for console access.
        * Combine with the script above to ensure `can_use_mfa=True` for all users and then disable or quarantine users who don’t enroll in MFA after some time.

        If you tell me whether you want pure **monitoring** (no changes) or full **auto‑remediation** (change users + possibly disable non‑compliant), I can adapt the script precisely.
      </Accordion>

      <Accordion title="Using Terraform">
        Terraform cannot enable or enforce MFA on an `oci_identity_user`; MFA enrollment in OCI is a per-user, interactive operation that is not exposed as an argument on `oci_identity_user` or any related Terraform resource.

        To remediate, you must:

        * In the OCI Console, go to **Identity & Security → Users → \[TARGET\_USER]**.
        * Use **Multi-Factor Authentication** (or **Manage MFA**) to enroll an MFA device for that user and complete the second‑factor setup flow.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
