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
- Remediation
Remediation
Using Console
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:
-
Sign in to OCI Console
- Use an account with IAM admin permissions (e.g.,
Administrator).
- Use an account with IAM admin permissions (e.g.,
-
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.
-
Filter active users
- In the Users list, use the Status filter:
- Set Status = Active.
- This shows all active IAM users.
- In the Users list, use the Status filter:
-
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.).
-
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.
-
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.
-
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:
- Go to Identity & Security → Identity → Users.
- Click the user name.
- On the User Details page, click More Actions (or the equivalent control) → Disable.
- Confirm the action.
- 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:
-
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).
-
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.”
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 configdone). - 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
TENANCY_OCID="<your_tenancy_ocid>"
If you don’t know it:
oci iam compartment list --all \
| jq -r '.data[] | select(.\"compartment-id\"==null) | .id'
2. List all active IAM users
oci iam user list --compartment-id "$TENANCY_OCID" --all \
| jq -r '.data[] | select(.\"lifecycle-state\"=="ACTIVE") | .id + " " + .name'
Optionally store them:
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):
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:
> 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
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)
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:
GROUP_OCID="<your_target_group_ocid>"
5. Add each user without a group to the target group
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:
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:
- Wrap steps 2–5 in a shell script (
remediate_iam_groups.sh). - 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.
Using Python
Below is a step‑by‑step approach and a Python example using the OCI Python SDK to:
- Find IAM users that are active and not in any group
- Optionally add them to a default group (or just report them)
1. Prerequisites
- Install OCI SDK:
pip install oci
- Have a valid OCI config file (e.g.
~/.oci/config) with:
[DEFAULT]
user=ocid1.user.oc1..aaaa...
fingerprint=...
key_file=/path/to/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..aaaa...
region=us-ashburn-1
- The user/instance using this config must have policies that allow:
read userson IAMread groupsandread user-group-membershipsmanage usersormanage user-group-memberships(if you want to modify)
Example policy:
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
- Load OCI config and create an
IdentityClient. - List all IAM users in the tenancy.
- For each user:
- Skip
INACTIVEusers. - Get their group memberships.
- If no group memberships exist, mark as non-compliant.
- Skip
- 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
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_userslist to:- Email (SMTP),
- Slack/Webhook,
- OCI Monitoring (custom metrics) or Logging.
- Send the
For example, to only monitor and not change anything, keep DEFAULT_GROUP_OCID = None and integrate the printed list into your monitoring/alerting workflow.
Using Terraform
# 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.