> ## 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 Active Users Should Be Members Of At Least One Group

### More Info:

Active IAM users should be members of at least one group. Users without group membership cannot receive group-based permissions, suggesting orphaned or misconfigured accounts.

### Risk Level

Medium

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* AWS Startup Security Baseline
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* Cloudanix Best Practice
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are console-based steps to (a) identify active IAM users not in any group, and (b) remediate them so every *active* user is in at least one group (or is disabled if not needed).

        ***

        ## 1. Identify active users without any groups

        OCI Console does not have a single built‑in filter for “users with no groups,” so you have to inspect users and their group memberships:

        1. **Sign in to OCI Console**
           * Use an account with IAM admin permissions (e.g., `Administrator`).

        2. **Go to IAM Users**
           * Open the hamburger menu (☰) → **Identity & Security** → **Identity** → **Users** (or **Domains** → *your domain* → **Users**, if you use IAM Domains).
           * Ensure you are looking at the correct **Identity Domain** if domains are enabled.

        3. **Filter active users**
           * In the Users list, use the **Status** filter:
             * Set **Status** = **Active**.
           * This shows all active IAM users.

        4. **Check group membership per user**
           * Click a user name to open the **User Details** page.
           * In the user details, go to the **Groups** tab/section.
           * If no groups are listed, this user is **active but not in any group**.
           * Make a list of such users (e.g., export to CSV if available in your tenancy, or track manually).

        Repeat for all active users.

        ***

        ## 2. Decide remediation per user

        For each active user with no groups, decide:

        * **Should this user remain active and have access?**
          * If **yes**: assign at least one appropriate group.
          * If **no (unused / test / ex-employee)**: disable the account.

        ***

        ## 3. Add user to an appropriate group (preferred remediation)

        You should generally have predefined groups mapped to policies (e.g., `Administrators`, `Developers`, `ReadOnly`, etc.).

        1. **Identify the right group**
           * Go to **Identity & Security** → **Identity** → **Groups**.
           * Review group purpose and policies to choose the one that matches the user’s job role.

        2. **Add the user to the group**
           * Still in **Groups**, click the target group.
           * Go to the **Members** tab.
           * Click **Add User to Group**.
           * Search for the user by name.
           * Select the user and click **Add**.

        3. **Verify**
           * Go back to **Identity & Security** → **Identity** → **Users**.
           * Click the user → **Groups** tab and confirm the group is now listed.

        Repeat for all active users that must remain active.

        ***

        ## 4. Disable users that should not have access

        For active users who should no longer have access:

        1. Go to **Identity & Security** → **Identity** → **Users**.
        2. Click the user name.
        3. On the **User Details** page, click **More Actions** (or the equivalent control) → **Disable**.
        4. Confirm the action.
        5. Status should change to **Inactive**.

        This removes them from the “active users” population, satisfying the requirement.

        ***

        ## 5. Ongoing monitoring using OCI IAM / Security services

        To monitor this continuously via OCI:

        1. **Cloud Guard (if available in your tenancy)**
           * Go to **Security** → **Cloud Guard**.
           * Ensure it is **Enabled** in the relevant compartments/tenancy.
           * In **Detector Recipes**, look for IAM-related detectors (e.g., “IAM user has no group membership” or similar; naming can change).
           * Enable / configure detector rules that flag users without group membership.
           * Optionally, create a **Responder Rule** to:
             * Notify (e.g., via Notifications / Email), or
             * Auto-remediate (e.g., disable user or add to a default group, depending on your policy).

        2. **Notifications**
           * Use **Notifications** (Events + Notifications Service) to send alerts to email/Slack when such findings occur.

        ***

        **Summary remediation actions in Console:**

        * For each **active** user with **no groups**:
          * Either: **Add to at least one appropriate group** (User → Groups → Add to Group or Group → Members → Add User).
          * Or: **Disable the user** if not required.

        This brings IAM into compliance with “OCI IAM active users should be members of at least one group.”
      </Accordion>

      <Accordion title="Using CLI">
        Below are concise, step‑by‑step OCI CLI instructions to find active IAM users that are not in any group and add them to at least one group.

        Assumptions:

        * You have OCI CLI installed and configured (`oci setup config` done).
        * You know (or can create) the target group(s) to which users should belong.
        * You have permissions to manage IAM users and groups.

        ***

        ### 1. Get your tenancy OCID

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

        If you don’t know it:

        ```bash theme={null}
        oci iam compartment list --all \
          | jq -r '.data[] | select(.\"compartment-id\"==null) | .id'
        ```

        ***

        ### 2. List all active IAM users

        ```bash theme={null}
        oci iam user list --compartment-id "$TENANCY_OCID" --all \
          | jq -r '.data[] | select(.\"lifecycle-state\"=="ACTIVE") | .id + " " + .name'
        ```

        Optionally store them:

        ```bash theme={null}
        oci iam user list --compartment-id "$TENANCY_OCID" --all \
          | jq -r '.data[] | select(.\"lifecycle-state\"=="ACTIVE") | .id' > active_users.txt
        ```

        ***

        ### 3. Find users that are NOT members of any group

        Run this one‑liner (requires `jq` and `xargs`):

        ```bash theme={null}
        while read -r USER_OCID; do
          GROUP_COUNT=$(oci iam group list --all \
            | jq --arg USER "$USER_OCID" '[.data[] | select(.\"group-id\" as $gid | .) as $g
              | .] | length' 2>/dev/null)

          # Better way: check user-group memberships directly:
          MEMBERSHIPS=$(oci iam user group-membership list \
            --user-id "$USER_OCID" --all \
            | jq '.data | length')

          if [ "$MEMBERSHIPS" -eq 0 ]; then
            echo "$USER_OCID"
          fi
        done < active_users.txt > users_without_groups.txt
        ```

        Simpler version for each user individually:

        ```bash theme={null}
        > users_without_groups.txt
        while read -r USER_OCID; do
          COUNT=$(oci iam user group-membership list \
            --user-id "$USER_OCID" --all \
            | jq '.data | length')
          if [ "$COUNT" -eq 0 ]; then
            echo "$USER_OCID" >> users_without_groups.txt
          fi
        done < active_users.txt
        ```

        Now `users_without_groups.txt` contains all active users with no group memberships.

        ***

        ### 4. Choose or create the remediation group

        #### 4.1. List existing groups

        ```bash theme={null}
        oci iam group list --compartment-id "$TENANCY_OCID" --all \
          | jq -r '.data[] | .name + " " + .id'
        ```

        Note the group OCID you want to use, or create one.

        #### 4.2. Create a new group (optional)

        ```bash theme={null}
        GROUP_NAME="default-user-group"
        GROUP_DESC="Default group for users without any group"
        GROUP_OCID=$(oci iam group create \
          --compartment-id "$TENANCY_OCID" \
          --name "$GROUP_NAME" \
          --description "$GROUP_DESC" \
          --query 'data.id' --raw-output)
        ```

        If using an existing group, just set:

        ```bash theme={null}
        GROUP_OCID="<your_target_group_ocid>"
        ```

        ***

        ### 5. Add each user without a group to the target group

        ```bash theme={null}
        while read -r USER_OCID; do
          echo "Adding $USER_OCID to group $GROUP_OCID"
          oci iam group add-user \
            --group-id "$GROUP_OCID" \
            --user-id "$USER_OCID"
        done < users_without_groups.txt
        ```

        ***

        ### 6. Verify remediation

        Re‑run the membership check for a sample user:

        ```bash theme={null}
        SAMPLE_USER_OCID=$(head -n1 users_without_groups.txt)

        oci iam user group-membership list \
          --user-id "$SAMPLE_USER_OCID" --all \
          | jq -r '.data[] | .\"group-id\"'
        ```

        It should now show at least one group ID (the group you added them to).

        ***

        ### Automating for Monitoring

        To keep the control enforced continuously:

        1. Wrap steps 2–5 in a shell script (`remediate_iam_groups.sh`).
        2. Run it periodically using:
           * OCI Logging + Functions + Events, or
           * A cron job on a bastion host (if allowed).

        This will ensure active users without groups are automatically detected and added to your chosen default group.
      </Accordion>

      <Accordion title="Using Python">
        Below is a step‑by‑step approach and a Python example using the OCI Python SDK to:

        1. Find IAM users that are **active** and **not in any group**
        2. Optionally **add** them to a default group (or just report them)

        ***

        ## 1. Prerequisites

        1. Install OCI SDK:

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

        2. Have a valid OCI config file (e.g. `~/.oci/config`) with:

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

        3. The user/instance using this config must have policies that allow:
           * `read users` on IAM
           * `read groups` and `read user-group-memberships`
           * `manage users` or `manage user-group-memberships` (if you want to modify)

        Example policy:

        ```text theme={null}
        Allow group SecurityAdmins to manage users in tenancy
        Allow group SecurityAdmins to manage groups in tenancy
        Allow group SecurityAdmins to manage user-group-memberships in tenancy
        ```

        ***

        ## 2. High-Level Logic

        1. Load OCI config and create an `IdentityClient`.
        2. List all IAM users in the tenancy.
        3. For each user:
           * Skip `INACTIVE` users.
           * Get their group memberships.
           * If no group memberships exist, mark as **non-compliant**.
        4. For non-compliant users, either:
           * Just log/print them, or
           * Add them to a chosen default group (e.g. `ocid1.group.oc1..xxxx`).

        ***

        ## 3. Python Script Example

        ```python theme={null}
        import oci

        # CONFIG
        PROFILE = "DEFAULT"           # profile name in ~/.oci/config
        DEFAULT_GROUP_OCID = None     # e.g. "ocid1.group.oc1..xxxx"; set to None to only report

        def main():
            # Load config and create Identity client
            config = oci.config.from_file("~/.oci/config", PROFILE)
            identity_client = oci.identity.IdentityClient(config)

            tenancy_ocid = config["tenancy"]

            # 1. List all users in tenancy
            users = oci.pagination.list_call_get_all_results(
                identity_client.list_users,
                compartment_id=tenancy_ocid
            ).data

            print(f"Total users found: {len(users)}")

            # Get all groups (optional: for validation/printing)
            groups = oci.pagination.list_call_get_all_results(
                identity_client.list_groups,
                compartment_id=tenancy_ocid
            ).data
            group_map = {g.id: g.name for g in groups}

            non_compliant_users = []

            for user in users:
                # Skip inactive users
                if user.lifecycle_state != "ACTIVE":
                    continue

                # 2. List group memberships for this user
                memberships = oci.pagination.list_call_get_all_results(
                    identity_client.list_user_group_memberships,
                    tenancy_ocid,
                    user_id=user.id
                ).data

                if not memberships:
                    non_compliant_users.append(user)

            # Report
            print("\nUsers that are ACTIVE and not in any group:")
            for u in non_compliant_users:
                print(f" - {u.name} ({u.id})")

            # 3. Optional: Remediate by adding to default group
            if DEFAULT_GROUP_OCID:
                print(f"\nRemediating: adding users to default group: {DEFAULT_GROUP_OCID}")
                for u in non_compliant_users:
                    create_membership = oci.identity.models.AddUserToGroupDetails(
                        user_id=u.id,
                        group_id=DEFAULT_GROUP_OCID
                    )
                    try:
                        identity_client.add_user_to_group(create_membership)
                        print(f"Added user {u.name} ({u.id}) to group {DEFAULT_GROUP_OCID}")
                    except Exception as e:
                        print(f"Failed to add user {u.name} ({u.id}) to group: {e}")
            else:
                print("\nNo DEFAULT_GROUP_OCID set; only reporting non-compliant users.")

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

        ***

        ## 4. How to Use for Monitoring

        * Run this script periodically via:
          * OCI Functions + Events / Scheduled invocation, or
          * A cron job on a bastion/automation server.
        * Instead of adding to a group automatically, you can:
          * Send the `non_compliant_users` list to:
            * Email (SMTP),
            * Slack/Webhook,
            * OCI Monitoring (custom metrics) or Logging.

        For example, to *only monitor* and not change anything, keep `DEFAULT_GROUP_OCID = None` and integrate the printed list into your monitoring/alerting workflow.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Existing IAM user
        resource "oci_identity_user" "MONITORED_USER" {
          # Replace with your user details
          compartment_id = "TENANCY_OCID"
          name           = "IAM_USER_NAME"
          description    = "DESCRIPTION_OF_USER"
          # Ensure user is active (do not set 'inactive_status')
        }

        # Existing IAM group that should grant permissions to the user
        resource "oci_identity_group" "TARGET_GROUP" {
          compartment_id = "TENANCY_OCID"
          name           = "GROUP_NAME"
          description    = "DESCRIPTION_OF_GROUP"
        }

        # Fix: ensure the active IAM user is a member of at least one group
        resource "oci_identity_user_group_membership" "MONITORED_USER_GROUP_MEMBERSHIP" {
          compartment_id = "TENANCY_OCID"          # Usually your tenancy OCID
          user_id        = oci_identity_user.MONITORED_USER.id
          group_id       = oci_identity_group.TARGET_GROUP.id
        }
        ```

        This change does not replace the user; it only adds a user–group membership association.

        For verification, `terraform plan` should show creation of one `oci_identity_user_group_membership` resource with the specified `user_id` and `group_id`, and no destructive changes to the user.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
