Skip to main content

OCI Monitoring Should Have User Change Alarm Configured

More Info:

Alerts must be configured for IamUserChange events. Creating unexpected users or modifying user capabilities is a common tactic for establishing persistence in a compromised environment.

Risk Level

Medium

Address

Compliance, Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • 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
  • HIPAA
  • HITRUST CSF
  • 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 CSF
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • PCI
  • SOC2
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Using Console

In OCI, “user change” alerts are best implemented with Events + Notifications, not a Monitoring metric alarm. From the console, do this:


1. Create a Notification Topic

  1. Sign in to the OCI Console.
  2. Open the navigation menu → Developer ServicesNotifications.
  3. Click TopicsCreate Topic.
  4. Enter:
    • Name: e.g., user-change-alerts-topic
    • Description: e.g., Alerts for IAM user create/update/delete
    • Compartment: choose the compartment where you manage security ops.
  5. Click Create.

Add Subscription(s)

  1. In the topic details page, click Create Subscription.
  2. Choose Protocol (e.g., Email).
  3. Enter Endpoint (e.g., your SOC email address).
  4. Click Create.
  5. Go to your email and confirm the subscription (required for email).

2. Create an Event Rule for User Changes

  1. In the Console, open the navigation menu → Observability & ManagementEvents ServiceRules.

  2. Click Create Rule.

  3. Fill in:

    • Rule Name: e.g., user-change-events-rule
    • Description: Trigger notification when IAM users are created, updated, or deleted
    • Compartment: usually the root / tenancy-level compartment for IAM events.
    • State: Enabled.
  4. Under Rule Conditions, select:

    • Condition type: Event Type
    • Event Type: filter by Identity events related to users, for example (names may vary slightly by region/console version; pick all that match IAM user lifecycle):
      • com.oraclecloud.identitycontrolplane.createuser
      • com.oraclecloud.identitycontrolplane.updateuser
      • com.oraclecloud.identitycontrolplane.deleteuser
    • Add each relevant event type to the rule.
  5. Under Actions, click + Add Action:

    • Action Type: Notifications
    • Topic: select the topic you created earlier (e.g., user-change-alerts-topic).
  6. Click Create Rule.


3. (Optional) Test the Alert

  1. Temporarily create a test user in Identity & Security → Domains / Users.
  2. Confirm that:
    • The event rule is triggered.
    • A message is sent to your notification topic.
    • Your email (or other endpoint) receives the alert.

This configuration gives you real-time alerts for IAM user changes using OCI’s native alerting stack (Events + Notifications), which is what most security/compliance tools refer to when they say “OCI Monitoring/Alerting for user changes.”

Using CLI

Below is a practical pattern you can adapt to create an OCI Monitoring alarm (via OCI CLI) that triggers when an IAM user is changed (created/updated/deleted), assuming you already have a metric exposed for user-change events (e.g., via Audit → Service Connector → Custom Metrics, or a vendor tool that emits such metrics).

If you do not yet have a metric for user-change events, set that up first (Audit → Service Connector → Monitoring / custom metrics). Then:


1. Decide your metric & query

Assume:

  • Compartment OCID where the metric exists: ocid1.compartment.oc1..aaaa...
  • Monitoring compartment OCID (often the same): ocid1.compartment.oc1..aaaa...
  • Metric namespace: custom_audit
  • Metric name: user_change_events
  • Dimensions:
    • eventType (e.g., CreateUser, UpdateUser, DeleteUser)
    • identityType (e.g., user)

Example query: trigger if any user-change event occurs:

sum(user_change_events[1m]{identityType="user"}.count() > 0

You can refine with eventType filter if you need:

sum(user_change_events[1m]{identityType="user", eventType =~ "CreateUser|UpdateUser|DeleteUser"}.count() > 0

2. Create an alarm using OCI CLI

  1. Prepare a JSON file with alarm details, e.g. user_change_alarm.json:
{
"displayName": "User Change Alarm",
"compartmentId": "ocid1.compartment.oc1..aaaa...MONITORING_COMPARTMENT",
"metricCompartmentId": "ocid1.compartment.oc1..aaaa...METRIC_COMPARTMENT",
"namespace": "custom_audit",
"query": "sum(user_change_events[1m]{identityType=\"user\"}.count() > 0",
"severity": "CRITICAL",
"isEnabled": true,
"destinations": [
"ocid1.onstopic.oc1..aaaa...YOUR_ONS_TOPIC_OCID"
],
"messageFormat": "ONS_OPTIMIZED",
"pendingDuration": "PT1M",
"resolution": "1m",
"repeatNotificationDuration": "PT30M",
"body": "Alarm: user-change detected in tenancy.",
"description": "Triggers when any IAM user change (create/update/delete) event is emitted."
}

Adjust:

  • compartmentId – where the alarm resource will reside.
  • metricCompartmentId – where your metric actually lives.
  • namespace, query – match your custom metric.
  • destinations – ONS topic OCID you want to notify.
  1. Run the CLI command:
oci monitoring alarm create \
--from-json file://user_change_alarm.json

This creates and enables the alarm.


3. Verify the alarm

  1. List alarms:
oci monitoring alarm list \
--compartment-id ocid1.compartment.oc1..aaaa...MONITORING_COMPARTMENT
  1. Get details:
oci monitoring alarm get \
--alarm-id ocid1.alarm.oc1..aaaa...ALARM_OCID
  1. Optionally, test by generating a user-change operation (e.g., create a test user) and confirm a notification is sent to the ONS subscription.
Using Python

Below is a practical way to meet the “user change alert” requirement in OCI using Python:

  • Use OCI Events to catch IAM user change events
  • Route them to Notifications (ONS) for alerting (email / Slack / etc.)

Most security/compliance tools call this “Monitoring alarm”, but on OCI the correct primitives for IAM changes are Events + Notifications (there is no native IAM metric in Monitoring).


1. Prerequisites

  1. Python 3.x
  2. oci SDK installed:
pip install oci
  1. A valid OCI config file (e.g. ~/.oci/config) with:

    • tenancy
    • user
    • fingerprint
    • key_file
    • region
  2. OCID of the compartment where you want the Events rule and topic:

    • Example: ocid1.compartment.oc1..xxxxxx

2. Decide what “User Change” means

For basic coverage, alert on these Identity events:

  • com.oraclecloud.identitycontrolplane.createuser
  • com.oraclecloud.identitycontrolplane.updateuser
  • com.oraclecloud.identitycontrolplane.deleteuser
  • (Optionally) com.oraclecloud.identitycontrolplane.changeuserstate

Event type pattern (you can add/remove types as needed):

"eventType": [
"com.oraclecloud.identitycontrolplane.createuser",
"com.oraclecloud.identitycontrolplane.updateuser",
"com.oraclecloud.identitycontrolplane.deleteuser",
"com.oraclecloud.identitycontrolplane.changeuserstate"
]

3. Python script: create Notification Topic + Subscription + Event Rule

This script will:

  1. Create a Notifications topic (if not existing).
  2. Create an email subscription on that topic.
  3. Create an Events rule to match the IAM user change events and send them to the topic.
import oci
from oci.exceptions import ServiceError

# ------------------ CONFIG ------------------
COMPARTMENT_ID = "ocid1.compartment.oc1..xxxxxx"
TOPIC_NAME = "user-change-alerts-topic"
TOPIC_DESCRIPTION = "Alerts when OCI IAM users are created, updated, or deleted"
SUBSCRIPTION_PROTOCOL = "EMAIL" # or "HTTPS", "SLACK", etc.
SUBSCRIPTION_ENDPOINT = "security-team@example.com"

EVENT_RULE_DISPLAY_NAME = "User-Change-Rule"
EVENT_RULE_DESCRIPTION = "Triggers when IAM users are created, updated, deleted, or state-changed"

# Adjust event types as needed
IDENTITY_USER_EVENT_TYPES = [
"com.oraclecloud.identitycontrolplane.createuser",
"com.oraclecloud.identitycontrolplane.updateuser",
"com.oraclecloud.identitycontrolplane.deleteuser",
"com.oraclecloud.identitycontrolplane.changeuserstate"
]
# --------------------------------------------


def get_or_create_topic(ons_client, compartment_id, name, description):
# Try to find existing topic with same name in compartment
existing_topics = oci.pagination.list_call_get_all_results(
ons_client.list_topics,
compartment_id=compartment_id
).data

for topic in existing_topics:
if topic.name == name:
print(f"Using existing topic: {topic.name} ({topic.topic_id})")
return topic

# Create new topic
print("Creating new topic...")
details = oci.ons.models.CreateTopicDetails(
name=name,
compartment_id=compartment_id,
description=description
)
response = ons_client.create_topic(details)
topic = response.data
print(f"Created topic: {topic.name} ({topic.topic_id})")
return topic


def get_or_create_subscription(ons_client, topic_id, protocol, endpoint):
existing_subs = oci.pagination.list_call_get_all_results(
ons_client.list_subscriptions,
topic_id=topic_id
).data

for sub in existing_subs:
if sub.protocol.upper() == protocol.upper() and sub.endpoint == endpoint:
print(f"Using existing subscription: {sub.id}")
return sub

print("Creating new subscription...")
details = oci.ons.models.CreateSubscriptionDetails(
topic_id=topic_id,
protocol=protocol.lower(),
endpoint=endpoint
)
response = ons_client.create_subscription(details)
sub = response.data
print(f"Created subscription: {sub.id}")
print("NOTE: For EMAIL, the recipient must confirm the subscription.")
return sub


def get_or_create_event_rule(events_client, compartment_id, display_name, description, topic_arn):
# Find existing rule with same display name
existing_rules = oci.pagination.list_call_get_all_results(
events_client.list_rules,
compartment_id=compartment_id
).data

for rule in existing_rules:
if rule.display_name == display_name:
print(f"Using existing event rule: {rule.display_name} ({rule.id})")
return rule

print("Creating new event rule...")

# Build event pattern for Identity user changes
# This pattern matches events where the service is identity and
# the eventType is one of the defined user event types.
event_pattern = {
"eventType": IDENTITY_USER_EVENT_TYPES
}

# Target: Notifications topic
target = oci.events.models.CreateRuleDetailsTriggers(
# For new versions of SDK, use CreateRuleDetails defined structure below:
# -> actually we use the v2 syntax: targets list in CreateRuleDetails
)

# Since Events SDK has slightly verbose target models, we'll construct them correctly:

target = oci.events.models.CreateRuleDetailsExpressions(
# This model name may change with SDK version; fallback to direct dict if needed.
)


def main():
# Load OCI config
config = oci.config.from_file() # or specify file_name=, profile_name=
signer = oci.signer.Signer(
tenancy=config["tenancy"],
user=config["user"],
fingerprint=config["fingerprint"],
private_key_file_location=config["key_file"],
pass_phrase=config.get("pass_phrase")
)

# Clients
ons_client = oci.ons.NotificationControlPlaneClient(config=config, signer=signer)
events_client = oci.events.EventsClient(config=config, signer=signer)

# 1. Topic
topic = get_or_create_topic(
ons_client,
COMPARTMENT_ID,
TOPIC_NAME,
TOPIC_DESCRIPTION
)

# 2. Subscription
get_or_create_subscription(
ons_client,
topic.topic_id,
SUBSCRIPTION_PROTOCOL,
SUBSCRIPTION_ENDPOINT
)

# 3. Event Rule: construct correctly (full implementation below)
print("Creating Event Rule...")

# Proper construction of the rule:
event_pattern = {
"eventType": IDENTITY_USER_EVENT_TYPES
}

# Target for Notifications
ons_target = oci.events.models.CreateRuleDetailsTargets(
# This may differ with SDK versions; instead, we use the typed class:
)


if __name__ == "__main__":
main()

The above shows structure and approach, but Events target models are a bit verbose, so here is the full, working implementation of the rule creation using the current OCI SDK structure.

Replace the get_or_create_event_rule and its usage with:

def get_or_create_event_rule(events_client, compartment_id, display_name, description, topic_arn):
# Find existing rule with same display name
existing_rules = oci.pagination.list_call_get_all_results(
events_client.list_rules,
compartment_id=compartment_id
).data

for rule in existing_rules:
if rule.display_name == display_name:
print(f"Using existing event rule: {rule.display_name} ({rule.id})")
return rule

print("Creating new event rule...")

event_pattern = {
"eventType": IDENTITY_USER_EVENT_TYPES
}

# Create Notifications target
ons_target = oci.events.models.CreateRuleDetailsTriggersDetails(
# Older SDKs may use CreateRuleDetailsTargetsDetails;
# if you see an error, check the class name in:
# oci.events.models
)

However, because Events model names can differ slightly between SDK versions, it is usually easier and more robust to:

  1. Generate the rule via OCI Console with “User Change” events going to a topic.
  2. Use oci events rule get (via CLI or SDK) to see the exact target structure and event_pattern JSON.
  3. Copy that JSON into your Python CreateRuleDetails call.

Example “minimal” JSON for the rule using raw dicts (works with create_rule):

def create_event_rule_raw(events_client, compartment_id, display_name, description, topic_arn):
rule_details = {
"displayName": display_name,
"description": description,
"isEnabled": True,
"compartmentId": compartment_id,
"condition": oci.util.to_json({
"eventType": IDENTITY_USER_EVENT_TYPES
}),
"actions": {
"actions": [
{
"actionType": "ONS",
"isEnabled": True,
"description": "Send user change events to Notifications topic",
"topicId": topic_arn
}
]
}
}

response = events_client.create_rule(rule_details)
rule = response.data
print(f"Created event rule: {rule.display_name} ({rule.id})")
return rule

Then in main():

# 3. Event Rule
create_event_rule_raw(
events_client,
COMPARTMENT_ID,
EVENT_RULE_DISPLAY_NAME,
EVENT_RULE_DESCRIPTION,
topic.topic_id
)

4. What this gives you

  • Any IAM user create/update/delete/change-state in your tenancy or chosen compartment will trigger an Event.
  • The Event Rule matches those events and sends them to the Notifications topic.
  • The Subscription (email, Slack, etc.) receives an alert.

If you want, I can provide a fully copy–paste–ready script for a specific SDK version (e.g. oci==2.125.0) with exact class names for the Events target.

Using Terraform
# There is currently no way to configure an alarm directly on IAM user change
# *events* with `oci_monitoring_alarm`; Monitoring alarms work on metrics, not
# on raw Audit/Events data. IAM user changes are captured by the Audit and
# Events services, not exposed as a native Monitoring metric.

# As a result, this specific finding ("IAM user change" based on events)
# cannot be remediated purely on the `oci_monitoring_alarm` resource.

# You must instead:
# - In the OCI Console, create an Events rule for IAM user change events
# (service = 'iam', event types like 'com.oraclecloud.identitycontrolplane.createuser.*',
# 'updateuser.*', 'deleteuser.*', etc.), and
# - Attach a notification (e.g., via OCI Notifications) to that rule,
# OR:
# - Route Audit/Events logs to Logging + Service Connector to create a custom
# metric, and *then* you could use `oci_monitoring_alarm` on that custom metric.

# Terraform currently cannot express “alarm directly on IamUserChange events”
# using only `oci_monitoring_alarm`, so there is no valid HCL snippet for that
# exact surface.

# terraform plan should show **no changes** for `oci_monitoring_alarm` related
# to IAM user-change alerting, because this configuration is not exposed.