OCI Monitoring Should Have Password Spray Detection Alarm
More Info:
Detect rapid failed logins followed immediately by a success. This pattern strongly indicates a successful password spraying or credential stuffing attack against an identity account.
Risk Level
High
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
- 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
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Using Console
Below is a practical way to meet the “password spray detection” requirement using only OCI native services via the Console, with security best-practice in mind:
Because OCI Monitoring alarms are metric-based, and password-spray is a security pattern, not a numeric metric, the normal and supported approach is:
- Use Cloud Guard to detect password spray.
- Attach Notifications so your SOC/SRE gets alerted (email, Slack, PagerDuty, etc.).
1. Make sure Cloud Guard is enabled
- Sign in to the OCI Console.
- Open the navigation menu → Identity & Security → Cloud Guard.
- If Cloud Guard is not enabled:
- Click Enable Cloud Guard.
- Choose a compartment where you want Cloud Guard configuration stored.
- Choose Reporting Region (usually your home region).
- Click Enable.
2. Confirm / enable the Password Spray detector
- Still in Cloud Guard, go to Configuration → Detector Recipes.
- Find the Managed Detector Recipe for Identity (for example, something like:
OCI Activity Detector Recipeor similar, depending on tenancy naming). - Click the recipe name.
- Search in the Detectors list for Password Spray (e.g., “Password Spray Attack” or similar wording).
- Ensure:
- The detector is Enabled.
- The Risk Level is set appropriately (e.g., High).
- If needed, click Edit:
- Turn Enabled on.
- Save changes.
If you are using a cloned/custom recipe attached to your Cloud Guard target, edit the cloned recipe, not the managed one.
3. Attach the detector recipe to a Cloud Guard target
- In Cloud Guard, go to Targets.
- Either:
- Edit an existing target, or
- Click Create Target to cover the tenancy or a specific compartment.
- In the target:
- Under Detector Recipes, make sure the Identity/Activity Detector Recipe (the one with Password Spray) is attached.
- Click Save changes.
At this point, Cloud Guard will generate problems whenever a password spray pattern is detected.
4. Configure Notifications for Password Spray problems
4.1 Create a Notifications topic
- Open the navigation menu → Developer Services → Notifications (or Application Integration → Notifications depending on your console layout).
- Click Create Topic.
- Name it something like:
password-spray-alerts. - Click Create.
4.2 Add subscriptions
- Click on your new topic.
- Under Subscriptions, click Create Subscription.
- Choose protocol, for example:
- Email → provide the email address(es).
- Or HTTPS, Slack via Webhook, PagerDuty, etc.
- Click Create.
- For emails, open your inbox and confirm the subscription.
5. Connect Cloud Guard to Notifications (for password spray)
You can notify for all High-severity problems (which should include Password Spray) or explicitly for that problem type if using filtering downstream.
- In Cloud Guard, go to Configuration → Responder Recipes (if you want auto-responses) or Configuration → Events depending on your console version.
- Simpler route: use Events Service to watch Cloud Guard problems and forward to Notifications.
5.1 Create an Event rule for Cloud Guard Password Spray
-
Go to navigation menu → Observability & Management → Events Service → Rules.
-
Click Create Rule.
-
Name:
cloudguard-password-spray-alert. -
Rule Conditions:
- Set Event Type:
com.oraclecloud.cloudguard.createproblemor similar Cloud Guard problem event. - Add a filter in the Additional Condition (JSON) to match Password Spray problem type, e.g. (pattern may vary by tenancy):
{"data.additionalDetails.problemRecommendation": {"contains": "password spray"}}If your tenancy uses a specific problem type key (e.g.,
data.additionalDetails.problemType), filter on that instead. - Set Event Type:
-
Actions:
- Select Notifications.
- Choose the topic
password-spray-alerts.
-
Click Create Rule.
Now, when Cloud Guard creates a Password Spray problem, Events Service will push a message to Notifications, which will send email/Slack/etc.
6. (Optional) Expose as a Monitoring Alarm
If your policy or tooling explicitly requires an OCI Monitoring Alarm object, you can:
- Use a small external process (Function, script, SIEM) that:
- Reads Cloud Guard problems (via Events or Cloud Guard API).
- Writes a custom metric to OCI Monitoring when a Password Spray problem appears (e.g., metric
security.password_spray_detected = 1).
- Then, in the Console:
- Go to Observability & Management → Monitoring → Alarms → Create alarm.
- Choose the custom metric namespace.
- Set a query such as:
security.password_spray_detected[5m].sum() > 0
- Point the alarm to the same Notifications topic.
This last piece requires some glue code, since OCI Monitoring itself cannot directly parse Cloud Guard events.
Summary:
Using only Console, the supported way is: Cloud Guard Password Spray detector → Events Rule → Notifications. If you must have a “Monitoring Alarm” object, add a custom-metric writer in between and create an alarm on that metric.
Using CLI
Below is one way to remediate this using OCI CLI by wiring a Cloud Guard “Password Spray” problem to an OCI Monitoring alarm and a Notification topic.
1. Prerequisites
- OCI CLI installed and configured (
oci setup configdone). - You know:
- Your compartment OCID (e.g.
ocid1.compartment.oc1..xxxxx) - Your region (e.g.
us-ashburn-1) - Your tenancy OCID if needed (
ocid1.tenancy.oc1..xxxxx)
- Your compartment OCID (e.g.
Set env vars for convenience (optional):
export COMPARTMENT_OCID="ocid1.compartment.oc1..xxxx"
export REGION="us-ashburn-1"
oci setup repair-file-permissions
2. Enable Cloud Guard and the Password Spray Detector
- Enable Cloud Guard at tenancy level (if not already enabled):
oci cloud-guard cloud-guard-configuration update \
--status ENABLED \
--region $REGION
- List available detector recipes and find the one including password-spray logic (often a managed detector recipe for IAM):
oci cloud-guard detector-recipe list \
--compartment-id $COMPARTMENT_OCID \
--all
Look for something like OCI Managed Detector Recipe that has IAM-related rules. Get its OCID, e.g.:
export DETECTOR_RECIPE_OCID="ocid1.cloudguarddetectorrecipe.oc1..xxxx"
- List detector rules in that recipe and verify the “Password Spray” rule is enabled:
oci cloud-guard detector-recipe list-detector-rules \
--detector-recipe-id $DETECTOR_RECIPE_OCID \
--all \
--output table
Find a rule whose name/description indicates “Password Spray” (e.g. Password Spray in IAM). Note its rule ID:
export PASSWORD_SPRAY_RULE_ID="ocid1.cloudguarddetectorrule.oc1..xxxx"
- Ensure the rule is enabled:
oci cloud-guard detector-recipe update-detector-rule \
--detector-recipe-id $DETECTOR_RECIPE_OCID \
--detector-rule-id $PASSWORD_SPRAY_RULE_ID \
--detector-rule-details '{"isEnabled": true}'
Cloud Guard will now create a Problem any time a password-spray pattern is detected. These problems are exposed as metrics in Monitoring under the oci_cloud_guard namespace.
3. Create a Notification Topic and Subscription
- Create a Notifications topic:
oci ons topic create \
--compartment-id $COMPARTMENT_OCID \
--name "PasswordSprayAlarmTopic" \
--description "Alert topic for Password Spray Cloud Guard problems" \
--region $REGION
Capture the topic OCID from output:
export TOPIC_OCID="ocid1.onstopic.oc1..xxxx"
- Create an email subscription to that topic:
oci ons subscription create \
--topic-id $TOPIC_OCID \
--protocol EMAIL \
--endpoint "security-team@example.com" \
--region $REGION
Confirm the subscription via the email that’s sent.
4. Create the Monitoring Alarm for Password Spray Problems
Cloud Guard exposes problem metrics roughly in the namespace oci_cloud_guard. A common pattern is:
- Namespace:
oci_cloud_guard - Metric:
problems_count - Dimension filters: e.g.
problemType = "PASSWORD_SPRAY"(name may vary; adjust to actual value returned by Cloud Guard in your tenancy).
- Test metric availability (optional):
oci monitoring metric-data summarize-metrics-data \
--compartment-id $COMPARTMENT_OCID \
--query-text 'oci_cloud_guard, metric=problems_count[5m].sum()' \
--namespace oci_cloud_guard \
--region $REGION
- Create the alarm:
Adjust the metric query if your exact dimension keys/values differ. The example below fires if at least one password-spray problem appears in the last 5 minutes.
oci monitoring alarm create \
--compartment-id $COMPARTMENT_OCID \
--display-name "Password Spray Detection Alarm" \
--namespace "oci_cloud_guard" \
--query-text 'oci_cloud_guard, metric=problems_count[5m].sum() > 0 {problemType = "PASSWORD_SPRAY"}' \
--severity "CRITICAL" \
--body "Password Spray detection triggered by Cloud Guard." \
--destinations "[\"$TOPIC_OCID\"]" \
--is-enabled true \
--resolution "5m" \
--pending-duration "PT0M" \
--metric-compartment-id $COMPARTMENT_OCID \
--metric-compartment-id-in-subtree true \
--region $REGION
Key fields you may need to adjust:
problemType = "PASSWORD_SPRAY"-
Use the actual value from your Cloud Guard problems. If unsure, inspect a Password Spray problem:
oci cloud-guard problem list \--compartment-id $COMPARTMENT_OCID \--all \--region $REGION \--output json | jq '.data[] | {id, problemType, detectorRuleName}'Then update the filter in
query-textto match e.g.{problemType = "PASSWORD_SPRAY_IN_IAM"}if that’s what you see.
-
5. Validate
- Confirm alarm exists and is enabled:
oci monitoring alarm list \
--compartment-id $COMPARTMENT_OCID \
--region $REGION \
--display-name "Password Spray Detection Alarm"
- Trigger (or wait for) a test password-spray event (or temporarily lower threshold) and confirm:
- A Cloud Guard Problem is created.
- The alarm state changes to FIRING.
- An email is received from the Notifications topic.
If you share the exact problemType and metric layout from your tenancy, I can refine the --query-text to match precisely.
Using Python
Below is a practical way to remediate this in OCI using Monitoring + Alarms via Python:
Goal:
Have an OCI Monitoring Alarm that fires when a “password spray” pattern is detected, using Python/OCI SDK.
Because OCI doesn’t provide a built‑in “password spray” metric, you’ll typically:
- Detect the pattern from logs (e.g., Audit/IDCS logs).
- Push a custom metric to OCI Monitoring when detected.
- Create an Alarm on that custom metric.
1. Prerequisites
- Python 3.x
ociPython SDK:pip install oci- An OCI config file (
~/.oci/config) with a profile that has access to:- Monitoring (metrics + alarms)
- Logs or Audit (to read login failures if you’re doing detection in Python)
- A target compartment OCID where you will:
- Publish custom metric
- Create the alarm
2. Decide Password Spray Detection Logic
One simple heuristic (you can improve as needed):
- Same IP address
- Multiple user login failures (e.g., ≥5) within a short time window (e.g., 5 minutes)
- Against different usernames
You can implement this logic outside OCI (e.g., in a Python script or OCI Function) that:
- Periodically pulls login failure events from:
- OCI Audit or
- Logging or
- IDCS logs (if federated)
- Groups them by source IP and time window.
- If the threshold is exceeded, push a metric value
1(or count) to OCI Monitoring.
Below I assume you have some way of identifying a password-spray condition in Python (e.g., a function is_password_spray_detected()).
3. Push a Custom Metric to OCI Monitoring (Python)
Namespace: security_password_spray
Metric name: password_spray_detected
Dimension example: {"source": "audit-checker"}
import oci
import datetime
# Load OCI config
config = oci.config.from_file("~/.oci/config", "DEFAULT")
monitoring_client = oci.monitoring.MonitoringClient(config)
# Your target compartment OCID
COMPARTMENT_ID = "ocid1.compartment.oc1..xxxx"
def publish_password_spray_metric(value: float):
"""
value > 0 means password spray detected in this interval.
"""
now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
metric_data = oci.monitoring.models.MetricDataDetails(
namespace="security_password_spray",
resource_group=None,
name="password_spray_detected",
dimensions={"source": "audit-checker"},
datapoints=[
oci.monitoring.models.Datapoint(
timestamp=now,
value=value,
count=1
)
],
metadata={}
)
post_details = oci.monitoring.models.PostMetricDataDetails(
metric_data=[metric_data]
)
resp = monitoring_client.post_metric_data(
post_metric_data_details=post_details,
compartment_id=COMPARTMENT_ID
)
# Optionally check resp for failures
# Example usage after your detection logic:
password_spray_detected = True # replace with real detection
if password_spray_detected:
publish_password_spray_metric(1.0)
else:
publish_password_spray_metric(0.0)
You’d normally run this script regularly (cron, OCI Function, container, etc.).
4. Create the Alarm on the Custom Metric (Python)
Alarm logic: if password_spray_detected sum over any 5‑minute window is ≥ 1, trigger alarm.
import oci
config = oci.config.from_file("~/.oci/config", "DEFAULT")
monitoring_client = oci.monitoring.MonitoringClient(config)
COMPARTMENT_ID = "ocid1.compartment.oc1..xxxx"
# Notification topic for alerts (e.g., email)
NOTIFICATION_TOPIC_OCID = "ocid1.onstopic.oc1..xxxx"
alarm_query = (
"security_password_spray.metric[1m].sum() "
"where metricName = 'password_spray_detected' "
"and source = 'audit-checker'"
)
alarm_details = oci.monitoring.models.CreateAlarmDetails(
display_name="Password Spray Detection Alarm",
compartment_id=COMPARTMENT_ID,
namespace="security_password_spray",
query=alarm_query,
severity="CRITICAL", # or "ERROR", "WARN"
destinations=[NOTIFICATION_TOPIC_OCID],
is_enabled=True,
# Condition: fire when sum over 5 min >= 1
# This is encoded in the query's time window + evaluation,
# or you can use `resolution` and `pending_duration`.
# Typical pattern:
pending_duration="PT0M", # 0 minutes delay
body="Password spray behavior detected.",
metric_compartment_id=COMPARTMENT_ID,
metric_compartment_id_in_subtree=False,
repeat_notification_duration="PT15M" # suppress repeated alerts for 15 min
)
response = monitoring_client.create_alarm(
create_alarm_details=alarm_details
)
print("Alarm OCID:", response.data.id)
Adjust the query syntax based on the Monitoring query language version you use. A common pattern:
security_password_spray.password_spray_detected[5m].sum() > 0If using
metric[interval].sum(), ensure it matches your SDK/region Monitoring capabilities.
5. Wire Detection + Metric Publishing
Your overall flow:
- Script or Function runs every N minutes.
- It reads login failure logs (Audit/IDCS/Logging).
- Applies password-spray logic.
- If detected, sends metric value
1, otherwise0. - Alarm continuously evaluates the metric and sends notifications.
6. Quick Checklist
- Audit/IDCS log source accessible from Python
- Password-spray detection logic implemented
- Custom metric posting working (visible in OCI Console → Monitoring → Metrics)
- Alarm created and enabled (visible in OCI Console → Monitoring → Alarms)
- Notification topic configured with email / PagerDuty / etc.
If you share how you currently store/receive login failures (Audit vs IDCS vs custom logs), I can give a minimal working detection example in Python tailored to that source.
Using Terraform
# This specific pattern-based detection (rapid failed logins immediately followed by a success)
# cannot be configured on oci_monitoring_alarm, because OCI Monitoring alarms operate on metrics
# and do not support event/log correlation in the way this check requires.
# You must instead build the detection on top of IAM / Audit / Identity Domain logs (e.g. via
# Logging Search / Logging Analytics or a Service Connector to custom metrics), then create an
# oci_monitoring_alarm on that derived metric. That log-query/correlation layer is not exposed
# as a Terraform argument on oci_monitoring_alarm today, so the finding cannot be fully fixed
# *on this resource type* from Terraform.
# Console outline (manual):
# 1. Identify the log source that records authentication attempts (Audit logs or identity domain logs).
# 2. In Logging / Logging Analytics, create a query that:
# - counts multiple failed login attempts for a principal over a short period, and
# - checks for a subsequent success for the same principal/IP in that window.
# 3. Either:
# - create a Logging/Logging Analytics alert directly, or
# - push the correlated result to a custom metric and then alarm on that metric.
# 4. If you do expose a custom metric called, for example, "PasswordSprayDetected" in namespace
# "security_custom", *then* you can manage the Monitoring alarm itself in Terraform as below:
resource "oci_monitoring_alarm" "password_spray_alarm" {
compartment_id = "OCID_OF_COMPARTMENT"
display_name = "Password Spray Detection Alarm"
is_enabled = true
severity = "CRITICAL"
# Namespace and metric name must match the custom metric emitted by your log/correlation pipeline
namespace = "security_custom"
# Honour your required threshold; for example, alarm when >= 1 detection in 5 minutes
query = "PasswordSprayDetected[5m].sum() >= 1"
destinations = [
"OCID_OF_ONS_TOPIC", # replace with an existing Notifications topic OCID
]
pending_duration = "PT1M"
body = "Password spray or credential stuffing activity detected. Investigate immediately."
resolution = "5m"
repeat_notification_duration = "PT30M"
}
# This Terraform only manages the alarm on a metric that already exists.
# The core detection logic (failed logins followed by success) must still be implemented
# in Logging / Logging Analytics or a log-to-metric pipeline outside this resource type.
# Verification:
# terraform plan should show:
# - 1 to add: oci_monitoring_alarm.password_spray_alarm