> ## 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 Console Users Should Have MFA Enforced

### More Info:

MFA should be enforced for every user with console login capability. Console access without MFA is vulnerable to phishing and credential-stuffing 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 step‑by‑step instructions to **remediate “OCI IAM Console Users Should Have MFA Enforced” using the OCI Console**, so that it is actually enforced (not just optional) and visible to IAM monitoring/Cloud Guard.

        ***

        ## 1. Identify the Identity Domain Used for Console Logins

        1. Sign in to the **OCI Console** as a tenancy admin.
        2. Open the navigation menu → **Identity & Security** → **Identity Domains**.
        3. Locate the identity domain(s) where your console users exist (often named *Default*, or similar).
        4. Click the target identity domain name to manage its settings.

        ***

        ## 2. Configure MFA Factors in the Identity Domain

        1. Inside the identity domain, go to **Security** → **Multi-Factor Authentication** (or **Security → Factors**, depending on version).
        2. Under **Available Factors**, ensure at least one of these is **Enabled**:
           * **Time-based One-Time Password (TOTP)** (e.g., Google Authenticator, Microsoft Authenticator)
           * **Email OTP** or **SMS OTP** (if allowed by your policy)
        3. Save any changes.

        This defines what MFA methods users can register.

        ***

        ## 3. Enforce MFA via Sign-On Policy

        You now make MFA **mandatory** for interactive console access.

        1. In the same identity domain, go to **Security** → **Sign-on Policies**.
        2. Either **edit** the existing default sign-on policy or **create a new policy**:
           * Click **Create Sign-on Policy** (if creating new).
           * Name it (e.g., `Require-MFA-For-Console`).
        3. Add a **Rule** (or edit an existing rule) that matches **all interactive console users**, for example:
           * Conditions:
             * **Client Type**: *Browser* (or *All* if you want broad coverage).
             * **IP Range / Network Perimeter**: as required (or leave broad for all).
             * **User Group**: choose groups that represent console users (e.g., `Administrators`, `OCI-Console-Users`) or **All users** if every human user must have MFA.
           * Actions / Access:
             * Set **Require multi-factor authentication** = **Yes** (or choose the specific factor set if prompted).
        4. Ensure **rule order** is correct:
           * Rules are evaluated top-down. Place the **MFA-required rule** above any rules that might allow access without MFA.
        5. Save the sign-on policy and make sure it is **Active**.

        This step is what actually fixes the “MFA not enforced” finding.

        ***

        ## 4. Require Existing Users to Register MFA

        Enforcement will prompt users, but you can also verify/assist:

        1. In the identity domain, go to **Users**.
        2. Pick a user → check **Security** / **Multifactor Authentication** or **Factors** tab:
           * Confirm if they already have an enrolled factor (e.g., TOTP).
        3. If not enrolled:
           * Tell users to sign in to the **OCI Console**.
           * On next sign-in, due to the new sign-on policy, they’ll be guided to register MFA (e.g., scan QR code with an authenticator app).
        4. For critical/admin users, you can test:
           * Log in as that user (or with a test user in same groups) to verify you’re forced to set up MFA and use it.

        ***

        ## 5. Confirm with OCI IAM Monitoring / Cloud Guard

        If the finding came from **Cloud Guard** or **Security Advisor**, verify remediation:

        1. Go to **Identity & Security** → **Cloud Guard**.
        2. Under **Detected Problems** (or **Targets → Problems**):
           * Filter by resource type **IAM**, or by the specific problem name (e.g., *OCI IAM Console Users Should Have MFA Enforced*).
        3. After the new sign-on policy has been active and users start registering MFA, let Cloud Guard re-evaluate (or manually **Recalculate** / **Re-evaluate** if available).
        4. Confirm the problem status moves to **Resolved** or **No problems** for IAM console MFA.

        ***

        ## 6. Optional: Tighten for Admin / Privileged Groups

        If you want extra assurance:

        1. Create a **separate sign-on policy** specifically targeting:
           * Admin groups: `Administrators`, `SecurityAdmins`, `NetworkAdmins`, etc.
        2. For these rules:
           * Always require MFA (no exceptions by IP or network).
        3. Place these rules at the **top** in the sign-on policy order.

        ***

        **Summary of Remediation via Console:**

        * Enable at least one MFA factor in the identity domain.
        * Create or edit a **Sign-On Policy** to **require MFA** for console access for all (or all human) IAM users.
        * Ensure rule ordering enforces MFA, and confirm via user login test.
        * Verify in **Cloud Guard / IAM Monitoring** that the “MFA enforced” check is now passing.
      </Accordion>

      <Accordion title="Using CLI">
        In OCI you can **monitor** MFA status with the CLI, but you **cannot actually “turn on” or enroll MFA for a user via CLI** – users must self-enroll, and enforcement is done via Identity Domain / sign‑on policies.

        Below are the practical steps:

        ***

        ## 1. Prerequisites

        * OCI CLI installed and configured with a tenancy‑admin or security‑admin–level profile:

        ```bash theme={null}
        oci setup config
        ```

        * Know your:
          * Tenancy OCID: `ocid1.tenancy.oc1....`
          * Home region (for IAM operations): e.g. `us-phoenix-1`

        Export region/profile for convenience:

        ```bash theme={null}
        export OCI_CLI_REGION=us-phoenix-1
        export OCI_CLI_PROFILE=DEFAULT
        ```

        ***

        ## 2. List all IAM users and check MFA status

        The user object includes a flag for MFA activation (in classic IAM tenants it’s `is_mfa_activated` or similar; in identity domains it’s exposed through identity‑domains APIs).

        ### 2.1 Get all users (classic IAM)

        ```bash theme={null}
        oci iam user list \
          --all \
          --query "data[].{name:\"name\", ocid:\"id\", mfa:\"is-mfa-activated\"}" \
          --output table
        ```

        To see only users without MFA:

        ```bash theme={null}
        oci iam user list \
          --all \
          --query "data[?\"is-mfa-activated\"==\`false\`].{name:\"name\", ocid:\"id\"}" \
          --output table
        ```

        If you are using **Identity Domains**, use the identity‑domains service:

        ```bash theme={null}
        oci identity-domains user list \
          --identity-domain-id <identity_domain_ocid> \
          --all
        ```

        (Then filter the returned JSON on the MFA factor attributes, which differ by domain config.)

        ***

        ## 3. Create a monitoring script

        You can schedule a simple script (OCI DevOps, Functions, or external CI) to fail compliance if any user lacks MFA.

        Example (bash, classic IAM):

        ```bash theme={null}
        #!/usr/bin/env bash
        set -euo pipefail

        NON_MFA_USERS=$(oci iam user list --all \
          --query "data[?\"is-mfa-activated\"==\`false\`].name" \
          --raw-output)

        if [ -n "$NON_MFA_USERS" ]; then
          echo "Users without MFA:"
          echo "$NON_MFA_USERS"
          exit 1   # mark as non-compliant
        else
          echo "All users have MFA enabled."
        fi
        ```

        ***

        ## 4. Enforce MFA (remediation)

        **This part cannot be done directly via OCI CLI at per‑user level.** You remediate by:

        1. **Enforcing MFA via Identity Domain sign‑on policies** (Console):
           * Go to: Identity & Security → Domains → select your domain.
           * Security → Sign-on policies.
           * Edit or create a policy that requires MFA for:
             * “OCI Console access” (or equivalent app),
             * All users or targeted groups.
           * Set conditions (e.g., all networks) and require at least one MFA factor.

        2. **Communicating to users**:
           * Notify the non‑MFA users identified by the script to log in and complete MFA enrollment.
           * Optionally, set a deadline and then:
             * Disable users who haven’t enrolled MFA:

               ```bash theme={null}
               oci iam user update \
                 --user-id <user_ocid> \
                 --force --defined-tags '{}' \
                 --freeform-tags '{}' \
                 --lifecycle-state INACTIVE
               ```

               (Use carefully; you’re disabling the account.)

        ***

        ## 5. Optional: Wire into OCI Cloud Guard / Security Zones

        * Enable **Cloud Guard** with a detector recipe that includes the “MFA not enabled for IAM users” rule (if present for your tenancy).
        * You can then use responder recipes, or a Function triggered by events, to:
          * Run the CLI monitoring script,
          * Create incidents or send notifications for non‑MFA users.

        ***

        Summary:

        * Use **OCI CLI** to **monitor** MFA status and detect non‑compliant console users.
        * Use **Identity Domain sign‑on policies** (via Console or IAM APIs if/when available) to **enforce** MFA globally.
        * Users must self‑register MFA; you can optionally disable non-compliant accounts via CLI as a hard remediation step.
      </Accordion>

      <Accordion title="Using Python">
        Below is a practical way to **monitor and flag OCI IAM console users who do not have MFA configured**, using Python and the OCI SDK.

        > Note: MFA is enforced via **IAM security policies / identity domain authentication policies**, not user-by-user. What you can do with Python is:
        >
        > * Detect users without MFA
        > * Push that info into logs/metrics, send notifications, or use it as an input for governance.

        ***

        ## 1. Prerequisites

        1. Install OCI Python SDK:

        ```bash theme={null}
        pip install oci
        ```

        2. Configure your OCI credentials (one of):
           * `~/.oci/config` (via `oci setup config`), or
           * Instance principal / resource principal if running on OCI compute / functions.

        Your config file might look like:

        ```ini theme={null}
        [DEFAULT]
        user=ocid1.user.oc1..aaaa...
        fingerprint=xx:xx:xx:...
        key_file=/path/to/private_key.pem
        tenancy=ocid1.tenancy.oc1..aaaa...
        region=us-ashburn-1
        ```

        ***

        ## 2. Python Script: List Users Without MFA

        This example:

        * Lists all users in your tenancy
        * For each user, checks if any TOTP MFA devices exist
        * Prints and optionally sends them to Monitoring or Notifications

        ```python theme={null}
        import oci
        from oci.config import from_file

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

        def list_all_users(identity_client, tenancy_ocid):
            users = []
            list_users_response = oci.pagination.list_call_get_all_results(
                identity_client.list_users,
                compartment_id=tenancy_ocid
            )
            for user in list_users_response.data:
                # Only consider active, non-deleted users
                if user.lifecycle_state == "ACTIVE":
                    users.append(user)
            return users

        def user_has_mfa(identity_client, user_id):
            # If this returns 0 devices, user has no TOTP MFA devices.
            devices = oci.pagination.list_call_get_all_results(
                identity_client.list_mfa_totp_devices,
                user_id=user_id
            )
            return len(devices.data) > 0

        def main():
            identity_client, tenancy_ocid = get_identity_client()

            users = list_all_users(identity_client, tenancy_ocid)

            users_without_mfa = []
            for user in users:
                if not user_has_mfa(identity_client, user.id):
                    users_without_mfa.append(user)

            print("Users without MFA configured (TOTP):")
            for user in users_without_mfa:
                print(f"- {user.name} ({user.id})")

            # Optional: here you can integrate with Monitoring / Notifications:
            #   - Push a custom metric
            #   - Send to OCI Logging
            #   - Publish to an OCI Notifications (ONS) topic
            #
            # Example stub:
            # send_metric_to_monitoring(len(users_without_mfa))
            # send_list_to_notifications(users_without_mfa)

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

        ***

        ## 3. (Optional) Push a Custom Metric to OCI Monitoring

        This lets you create an alarm such as “if number of non-MFA users > 0, send alert”.

        ```python theme={null}
        import oci
        from datetime import datetime, timezone

        def send_metric_to_monitoring(non_mfa_count, namespace="security_custom", compartment_ocid=None):
            config = oci.config.from_file()
            monitoring_client = oci.monitoring.MonitoringClient(config)

            if not compartment_ocid:
                compartment_ocid = config["tenancy"]

            metric_data = oci.monitoring.models.MetricDataDetails(
                namespace=namespace,
                compartment_id=compartment_ocid,
                name="non_mfa_users_count",
                dimensions={"tenancy": compartment_ocid},
                datapoints=[
                    oci.monitoring.models.Datapoint(
                        timestamp=datetime.now(timezone.utc),
                        value=float(non_mfa_count)
                    )
                ],
                metadata={}
            )

            post_metric_data_details = oci.monitoring.models.PostMetricDataDetails(
                metric_data=[metric_data]
            )

            monitoring_client.post_metric_data(post_metric_data_details)
        ```

        Call `send_metric_to_monitoring(len(users_without_mfa))` from `main()` after you compute the list.

        Then in the OCI Console:

        1. Go to **Monitoring → Metrics**.
        2. Select namespace `security_custom`.
        3. Create an alarm on `non_mfa_users_count > 0` for some periods.
        4. Attach an **Alarm Destination** (Notifications topic → email/Slack/etc.).

        ***

        ## 4. (Optional) Send a Notification with List of Non-MFA Users

        ```python theme={null}
        def send_list_to_notifications(users_without_mfa, topic_ocid):
            config = oci.config.from_file()
            ons_client = oci.ons.NotificationDataPlaneClient(config)

            body_lines = ["Users without MFA:"]
            for user in users_without_mfa:
                body_lines.append(f"- {user.name} ({user.id})")
            body = "\n".join(body_lines)

            ons_client.publish_message(
                topic_id=topic_ocid,
                message_details=oci.ons.models.MessageDetails(
                    title="OCI IAM: Users without MFA",
                    body=body
                )
            )
        ```

        Call `send_list_to_notifications(users_without_mfa, "<topic_ocid>")`.

        ***

        ## 5. Automate the Monitoring

        * Run this script on:
          * A VM with `cron`
          * OCI DevOps build job
          * As an OCI Function with a **cron Events** rule (converted to Functions runtime)

        ***

        ## 6. Enforcing MFA (Separate from Monitoring)

        To actually **enforce** MFA (beyond monitoring):

        * Classic IAM:
          * Configure MFA in your **Identity Provider / Console sign-on policy** (if using identity domains, use Authentication Policies and Rules).
          * Make MFA mandatory for interactive login to the Console.

        * Identity Domains (recommended):
          * Create an **Authentication Policy** that requires MFA for console access (or all access).
          * Optionally enforce MFA enrollment at first login.

        Python can help you monitor and report, but the enforcement switch is done via console / IAM/ID domain configuration, not per-user scripting.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # There is currently no Terraform argument on oci_identity_user (or any other
        # OCI IAM/Identity resource) that “enforces MFA” for a user or for all console
        # users; MFA enrollment/enforcement is managed via IAM security/authentication
        # settings and per‑user device activation in the Console.

        # You can model users:
        resource "oci_identity_user" "example_user" {
          compartment_id = var.TENANCY_OCID
          name           = "EXAMPLE_USER_NAME"
          description    = "Example IAM console user"
          email          = "EXAMPLE_USER_EMAIL"
        }

        # But enforcing MFA for that user (or globally) must be done outside Terraform:
        # – In the OCI Console, under Identity & Security → (Identity Domain / Security)
        #   → Authentication settings, configure policies that require MFA for console logins.
        # – For each user, register and activate an MFA device (TOTP/SMS/etc.) via the console UI.

        # Because the provider does not expose an “MFA required” switch, Terraform cannot
        # remediate this specific finding on the oci-identitymanagement-iam-user surface.

        # Verification in Terraform:
        # `terraform plan` will show no changes related to MFA enforcement, because the
        # setting is not represented in the Terraform state.
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
