OCI Monitoring Should Have Brute Force Detection Alarm
More Info:
Identify rapid, sustained bursts of IdentityAuthFailure from a single source. Prompt detection of brute force attacks allows automated blocking before credentials can be cracked
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 straightforward way to implement brute‑force detection via OCI Monitoring + Alarms using the OCI Console. The idea is:
- Use Audit logs (failed logins)
- Pipe them through a Service Connector to a custom Monitoring metric
- Create an Alarm on that metric when failures exceed a threshold in a short time
Prerequisites
-
You have permissions to:
- Read Audit logs
- Create Service Connectors
- Create Metrics in Monitoring
- Create Alarms
-
Audit is enabled (it is on by default for all tenancies).
Step 1 – Identify Failed Login Events in Audit
-
In the OCI Console, go to Observability & Management → Logging → Log Explorer.
-
In the Log Group filter, choose:
- Compartment: root (or tenancy-level compartment)
- Log Source:
audit
-
Use a basic search filter to see failed authentication events, for example:
data.eventName = "Authenticate" AND data.responseCode != "200"or (depending on audit event format):
data.responseType = "FAILURE" -
Confirm that you see failed login events (console logins / API auth failures).
You’ll reuse this filter (or a refined one) in the Service Connector.
Step 2 – Create a Custom Metric via Service Connector
-
Go to Observability & Management → Service Connector Hub → Service Connectors.
-
Click Create service connector.
-
Basic details:
- Name:
brute-force-login-metric-sc - Compartment: choose appropriate security/operations compartment.
- Name:
-
Source:
- Source type: Logging
- Log group: choose the Audit log group for the tenancy.
- Logs: select the Audit log.
-
Filter:
-
Use the same filter you tested in Log Explorer, e.g.:
data.eventName = "Authenticate" AND data.responseCode != "200"
-
-
Task:
- Task type: Logging Analytics / Monitoring → select Monitoring (Create custom metric).
-
Metric configuration:
- Namespace:
security_bruteforce(or another name, but note it). - Metric name:
failed_login_attempts - Dimensions (examples – key/value from log fields):
user→data.requestPrincipalNamesource_ip→data.clientIPregion→data.region
- Value: set to
1(each event = one failed attempt). - Unit:
count.
- Namespace:
-
Leave aggregation default (count or sum).
-
Click Create.
After a few minutes, failed login events will start to appear as a metric.
Step 3 – Verify the Custom Metric
- Go to Observability & Management → Monitoring → Metrics Explorer.
- In Compartment, select the compartment where the Service Connector writes metrics.
- In Metric namespace, choose
security_bruteforce(or your chosen namespace). - For Metric, choose
failed_login_attempts. - Set a time window (e.g., last 1 hour).
- You should see data points when failures occur.
If no data appears, wait a few minutes and then re‑test a failed login (e.g., intentionally try a wrong password once or twice) and re‑check.
Step 4 – Create the Brute Force Detection Alarm
-
Go to Observability & Management → Monitoring → Alarms.
-
Click Create alarm.
-
Alarm basic info:
- Name:
Brute-Force Login Detection - Compartment: same as metric.
- Status: Enabled.
- Name:
-
Metric selection:
- Metric namespace:
security_bruteforce - Metric name:
failed_login_attempts - Statistic: Sum.
- Interval: e.g., 5 minutes.
- Dimensions: choose how to group:
- To detect per user: group by
user - To detect per IP: group by
source_ip
- To detect per user: group by
- Metric namespace:
-
Alarm condition (example):
- Operator:
Greater than - Threshold:
5 - So:
Sum(failed_login_attempts)[5m] > 5
→ triggers if > 5 failed logins from same user/IP in 5 minutes.
- Operator:
-
Notifications:
- If you don’t have one, first create a Notification topic:
- Go to Developer Services → Notifications (ONS), create topic (e.g.,
security-alerts), and subscribe an email or HTTPS endpoint.
- Go to Developer Services → Notifications (ONS), create topic (e.g.,
- Back in the alarm creation:
- Notification destination: pick that Topic.
- If you don’t have one, first create a Notification topic:
-
Alarm severity:
- Set to Critical or Error.
-
(Optional) Repeat notifications: enable if you want recurring alerts while condition persists.
-
Click Create alarm.
Step 5 – Test the Alarm
- Intentionally perform several failed logins from the same user or IP to exceed the threshold in the chosen interval.
- Wait a few minutes:
- Confirm in Metrics Explorer that
failed_login_attemptsincreased. - Confirm in Alarms that alarm state goes to FIRING.
- Check that a notification (email/endpoint) is received.
- Confirm in Metrics Explorer that
Operational Tips
- Tune threshold and interval to reduce noise (e.g., 5 attempts in 5 minutes vs. 10 in 10 minutes).
- You can create multiple alarms, e.g.:
- One per user dimension
- One per source_ip dimension.
- Restrict access to the metrics and alarms to security/ops admins only.
If you share your current audit event format (sample JSON), I can give you an exact filter and dimension mapping to use in the Service Connector.
Using CLI
Below is one practical way to satisfy “OCI Monitoring should have Brute Force Detection Alarm configured” using OCI Monitoring + Logging, controlled entirely via OCI CLI.
Because OCI has no built‑in “Brute Force” metric, the usual pattern is:
- Use Logging to collect authentication failures (e.g., Identity, IAM, or OS/Auth logs).
- Use a Service Connector to push those logs into a custom Monitoring metric.
- Create an OCI Monitoring alarm on that custom metric via OCI CLI.
If you already have the custom metric in place, you can skip to Step 3.
Prerequisites
- OCI CLI installed and configured (
~/.oci/config). - Tenancy and compartment OCIDs handy.
- IAM permissions to:
- Read logs
- Manage service-connectors
- Manage metrics / alarms
- Use notification topics (ONS)
Step 1 – (If needed) Route “failed login” logs into a custom metric
-
Identify the log(s) that contain authentication failures
For example, IDCS or IAM logs in a compartment:oci logging log-group list \--compartment-id <COMPARTMENT_OCID>Then:
oci logging log list \--log-group-id <LOG_GROUP_OCID> -
Create a Service Connector that:
- Source: Logging
- Target: Monitoring (Metrics)
- Filter: only failed login / auth events
- Metric: e.g., namespace
security_auth, namefailed_login_count
Example minimal JSON config for the task (save as
sc-task.json):{"kind": "logRuleTaskDetails","logSource": {"kind": "ocic","logGroupId": "<LOG_GROUP_OCID>","logId": "<LOG_OCID>"},"metricExtraction": {"metricNamespace": "security_auth","metricName": "failed_login_count","dimensions": {"user": "$.data.additionalDetails.userName","sourceip": "$.data.additionalDetails.sourceIp"},"value": "1","unit": "count","filter": "$[?(@.data.eventName == 'LoginFailure')]"}}Create the Service Connector:
oci sch service-connector create \--compartment-id <COMPARTMENT_OCID> \--display-name "FailedLoginToMetric" \--source '{"kind":"logging","logSources":[{"kind":"log","logGroupId":"<LOG_GROUP_OCID>","logId":"<LOG_OCID>"}]}' \--target '{"kind":"monitoring"}' \--tasks file://sc-task.json \--is-enabled trueAdjust the JSON paths (
eventName,userName, etc.) to match your log schema.
Wait ~5–10 minutes and confirm metrics are arriving:
oci monitoring metric-data summarize-metrics-data \
--compartment-id <COMPARTMENT_OCID> \
--namespace-name security_auth \
--query-text "failed_login_count[5m].sum()"
Step 2 – Decide your Brute Force detection rule
Example brute-force detection heuristic:
- If failed_login_count sum over 5 minutes > 10
(either per user/IP or aggregated)
Metric query examples (Monitoring query language):
-
All failed logins:
failed_login_count[5m].sum() -
Per IP:
failed_login_count[5m].groupby('sourceip').sum()
Pick one based on how you want to detect brute force.
Step 3 – Create a Notification Topic (if you don’t have one)
oci ons topic create \
--compartment-id <COMPARTMENT_OCID> \
--name "BruteForceAlarmTopic" \
--description "Alarm for brute force detection"
Take note of the topic-id from the output.
Optionally subscribe an email:
oci ons subscription create \
--topic-id <TOPIC_OCID> \
--protocol EMAIL \
--endpoint you@example.com
Step 4 – Create the Brute Force Detection Alarm via OCI CLI
-
Build the alarm body JSON (
alarm-body.json):{"displayName": "BruteForceDetectionAlarm","compartmentId": "<COMPARTMENT_OCID>","metricCompartmentId": "<COMPARTMENT_OCID>","metricCompartmentIdInSubtree": true,"namespace": "security_auth","query": "failed_login_count[5m].sum()","severity": "CRITICAL","destinations": ["<TOPIC_OCID>"],"isEnabled": true,"repeatNotificationDuration": "PT15M","pendingDuration": "PT5M","body": "Potential brute force login attack detected (failed_login_count > 10 in 5 minutes).","resolution": "PT1M","messageFormat": "PRETTY_JSON","triggerDelay": "PT0M","supression": null,"isNotificationsPerMetricDimensionEnabled": false,"overrideAlarmState": "OK","rule": "failed_login_count[5m].sum() > 10"}Notes:
queryandruleare both required:ruleis the Boolean condition;querydefines the metric selection.- Adjust the threshold
> 10and windows5mto your policy.
-
Create the alarm:
oci monitoring alarm create \--from-json file://alarm-body.json -
Verify:
oci monitoring alarm get --alarm-id <ALARM_OCID>
Step 5 – (Optional) Brute Force per IP or per User
If you want the alarm to fire when any IP exceeds a threshold:
In alarm-body.json, use:
"query": "failed_login_count[5m].groupby('sourceip').sum()",
"rule": "failed_login_count[5m].groupby('sourceip').sum() > 10",
"isNotificationsPerMetricDimensionEnabled": true
Then each offending IP will generate its own alarm notification.
Step 6 – Test the Alarm
- Generate some failed login attempts (in a test account).
- Wait for the metric to ingest and meet your threshold.
- Confirm notifications from the alarm topic.
If you share:
- Where your authentication logs are (IDCS, IAM, OS logs, etc.)
- How you want to define “brute force” (failed attempts, time window, by IP or user),
I can give you an exact oci command + JSON tailored to your environment.
Using Python
Below is a practical way to remediate this by creating an OCI Monitoring Alarm (using Python + OCI SDK) that fires when a “brute force–like” pattern of failed authentications is detected.
Because “brute force detection” isn’t a single built‑in metric in OCI, you usually do this in two stages:
- Produce a metric that represents failed login attempts (e.g., from IAM logs, OS logs, or WAF logs).
- Create a Monitoring alarm on that metric with a condition that indicates brute force behavior.
I’ll focus on the Monitoring/Alerting part in Python and show where the metric comes from.
1. Prerequisites
-
Install OCI SDK for Python:
pip install oci -
Configure OCI CLI credentials (used by the SDK):
oci setup configThis creates
~/.oci/configwith:[DEFAULT]user=ocid1.user.oc1..fingerprint=...key_file=~/.oci/oci_api_key.pemtenancy=ocid1.tenancy.oc1..region=us-ashburn-1 -
Identify:
- Compartment OCID where:
- Your metric is emitted.
- You want the alarm created.
- Notification topic OCID (OCI Notifications) where alerts will be sent.
- Compartment OCID where:
2. Ensure You Have a Metric for Failed Logins
You must have (or create) a metric that reflects failed logins, for example:
- From IAM auth logs → send to Logging, then:
- Use Logging Analytics or Service Connector Hub to transform into a custom metric.
- Or from:
- WAF logs (for web login brute force),
- OS-level auth logs (e.g., SSH) shipped via OCI Logging Agent → then to a custom metric.
Assume for the example:
- Metric namespace:
custom_security - Metric name:
failed_login_count - Dimension:
source(e.g.,ssh,web, etc.)
You must replace these with the actual namespace/name/dimensions you created.
3. Decide a Brute Force Threshold
Example logic (tune for your environment):
- “Trigger if
failed_login_count≥ 20 in 5 minutes”
4. Build the Monitoring Query
OCI Monitoring uses a query language like:
metric[<namespace>].<metric_name>[<interval] {dimension filters}.statistic operator value
Example brute force style query (replace values as needed):
metric[custom_security].failed_login_count[5m]{source = "ssh"}.sum() >= 20
custom_security– your metric namespace.failed_login_count– your metric.[5m]– window for evaluation.{source = "ssh"}– optional filter..sum()– sum of failed logins.>= 20– threshold.
5. Python Code: Create the Alarm
import oci
from oci.monitoring.models import (
CreateAlarmDetails
)
# --- CONFIGURATION ---
# OCI config profile
CONFIG_PROFILE = "DEFAULT"
# Compartment where the metric and alarm live
COMPARTMENT_OCID = "ocid1.compartment.oc1..xxxx"
# Notification topic OCID (OCI Notifications)
TOPIC_OCID = "ocid1.onstopic.oc1..xxxx"
# Alarm name and description
ALARM_DISPLAY_NAME = "Brute Force Login Detection Alarm"
ALARM_DESCRIPTION = (
"Triggers when failed login attempts indicate possible brute force attack."
)
# Monitoring query – ADJUST THESE TO MATCH YOUR METRIC
# Example for custom metric:
# namespace: custom_security
# metric: failed_login_count
# dimension: source = "ssh"
ALARM_QUERY = 'metric[custom_security].failed_login_count[5m]{source = "ssh"}.sum() >= 20'
# Severity: CRITICAL | ERROR | WARNING | INFO
SEVERITY = "CRITICAL"
# Notification content
ALERT_MESSAGE = "Possible brute force attack detected - high rate of failed logins."
ALERT_BODY = (
"The alarm for failed login attempts has fired, indicating possible brute force "
"activity on the monitored resources. Please investigate the source(s) of failed "
"logins (SSH, web application, IAM, etc.)."
)
# --- CREATE ALARM ---
def create_bruteforce_alarm():
# Load config and create client
config = oci.config.from_file(profile_name=CONFIG_PROFILE)
monitoring_client = oci.monitoring.MonitoringClient(config)
# Define alarm details
alarm_details = CreateAlarmDetails(
display_name=ALARM_DISPLAY_NAME,
compartment_id=COMPARTMENT_OCID,
metric_compartment_id=COMPARTMENT_OCID,
namespace="custom_security", # Must equal your metric namespace
query=ALARM_QUERY,
severity=SEVERITY,
body=ALERT_BODY,
message_format="TEXT", # or "JSON"
is_enabled=True,
# Notifications
destinations=[TOPIC_OCID],
# Optional: treat missing data
# MISSING = treat as missing, BREACHING = treat as breaching, NOT_BREACHING
pending_duration="PT0M", # ISO 8601. 0 means trigger as soon as condition met.
repeat_notification_interval="PT15M", # re-notify every 15 mins while in alarm
is_notifications_per_metric_dimension_enabled=False,
# Alarm description
freeform_tags={
"purpose": "security",
"type": "brute_force_detection"
},
defined_tags={}
)
# Call create_alarm
response = monitoring_client.create_alarm(create_alarm_details=alarm_details)
print("Alarm created:")
print(" OCID: ", response.data.id)
print(" Name: ", response.data.display_name)
print(" Query: ", response.data.query)
print(" Destinations:", response.data.destinations)
if __name__ == "__main__":
create_bruteforce_alarm()
Things you must adapt:
COMPARTMENT_OCIDTOPIC_OCIDnamespaceandALARM_QUERY:namespace="custom_security"- Query string with correct metric name + dimensions.
- Threshold numbers and time window to fit your environment.
6. (Optional) Enforce Organization‑wide
If this is part of a security control, you can:
- Turn this into a reusable script or Terraform module.
- Run it as part of CI/CD for each compartment/region.
- Periodically verify via script: list alarms and ensure the brute force one exists and is enabled.
If you share how your failed login signal is generated (IAM logs, WAF, Linux auth logs, etc.), I can give a concrete metric namespace/name and a more precise query.
Using Terraform
resource "oci_monitoring_alarm" "identity_bruteforce_detection" {
# OCI compartment OCID where you want the alarm to live
compartment_id = "OCID_OF_COMPARTMENT_FOR_ALARM"
display_name = "identity-bruteforce-detection"
is_enabled = true
severity = "CRITICAL"
# Topic to notify when suspected brute-force is detected
destinations = [
"OCID_OF_OCI_NOTIFICATIONS_TOPIC"
]
# Adjust this tenancy/compartment filter and threshold to match your environment and policy
# - Replace IDENTITY_COMPARTMENT_OCID with the compartment/tenancy you want to watch
# - Replace sourceIpAddress with the correct dimension key for the metric in your tenancy
# - Replace 10 and 5 with the burst size and duration you consider "brute force"
#
# This example:
# - Watches IdentityAuthFailure every 1 minute
# - Groups by source IP address
# - Triggers if any single IP has >10 failures per minute
# - For at least 5 consecutive minutes
metric_compartment_id = "IDENTITY_COMPARTMENT_OCID"
namespace = "oci_identity"
query = "IdentityAuthFailure[1m]{compartmentId = \"IDENTITY_COMPARTMENT_OCID\"}.grouping('sourceIpAddress').sum() > 10"
resolution = "1m"
pending_duration = "PT5M" # ISO-8601: alarm must remain in breach 5 minutes before firing
message_format = "TEXT"
body = "Potential brute-force activity detected: rapid, sustained IdentityAuthFailure events from a single source IP."
# Optional: suppress duplicate notifications for the same ongoing incident
repeat_notification_duration = "PT30M" # re-notify at most every 30 minutes while still in ALARM
# Optional tags
freeform_tags = {
OWNER = "SECURITY_TEAM"
PURPOSE = "Brute-force detection on identity auth failures"
ENVIRONMENT = "PRODUCTION"
}
}
This change updates/creates the oci_monitoring_alarm in place and does not force replacement of other resources; only this alarm resource is added/updated.
Verification: terraform plan should show one oci_monitoring_alarm.identity_bruteforce_detection to add (or to update if it already exists), with the query, pending_duration, and related arguments matching the brute-force detection threshold you require.