> ## 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 Monitoring Should Have Access Denied Enumeration Alarm Configured

### More Info:

Detect high frequencies of Unauthorized API errors. This behavior maps to attackers or compromised scripts attempting to enumerate permissions and discover accessible resources

### 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
* 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 SP 800-171
* NYDFS 23 NYCRR 500
* SOC2
* 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 the steps to configure an **Access Denied Enumeration** alarm with **OCI Monitoring** using only the **OCI Console**. The idea is:

        * Use **Audit logs** as source
        * Use **Service Connector** to turn “access denied” events into a **custom metric**
        * Create an **Alarm** on that custom metric

        ***

        ## 1. Confirm Audit Logs Are Enabled

        Audit is on by default, but verify:

        1. In the OCI Console, open the **Navigation menu**.
        2. Go to **Identity & Security → Audit**.
        3. Select your **tenancy / compartment**.
        4. Confirm you can see recent audit events.\
           If not, check compartment/region filters.

        ***

        ## 2. Create (or Use) a Log for Audit Events

        You need the Audit events to be in **Logging** so Service Connector can use them.

        1. Go to **Logging → Logs**.
        2. Click **Create log**.
        3. Choose:
           * **Log Group**: select or create (e.g., `security-log-group`).
           * **Log Name**: e.g., `audit-access-log`.
           * **Log Source**: choose **Service logs → Audit** (or equivalent, depending on region/console updates).
        4. Save/enable the log.

        Make sure the log receives **Audit** events (you should see entries after a few minutes).

        ***

        ## 3. Create a Service Connector to Produce a Custom Metric

        1. Go to **Observability & Management → Service Connector Hub**.
        2. Click **Create service connector**.

        **A. Basic Info**

        * Name: e.g., `access-denied-metric-connector`.
        * Compartment: choose the security/monitoring compartment.

        **B. Source**

        * Source type: **Logging**.
        * Log Groups: select the **log group** used for Audit (e.g., `security-log-group`).
        * Logs: select your **Audit log** (e.g., `audit-access-log`).

        **C. Define Log Filter (only “access denied” events)**

        In the log filter, use a query that selects denied events, for example (adjust names as per your environment):

        ```text theme={null}
        data.responseStatus = "FAILURE"
        and
        (
          data.errorCode = "NotAuthorizedOrNotFound"
          or data.errorCode = "NotAuthorized"
          or data.responseMessage like "%NotAuthorized%"
          or data.responseMessage like "%AccessDenied%"
        )
        ```

        (Use whatever fields you actually see in your Audit records; click on a log entry and check its JSON.)

        **D. Target**

        * Target type: **Monitoring (Metric)**.
        * Metric namespace: e.g., `custom_security`.
        * Metric name: e.g., `access_denied_count`.
        * Metric unit: e.g., `count`.

        **E. Metric Dimensions (recommended)**

        Add dimensions like:

        * `principal` → `data.identity.userName` (or `data.identity.principalName`).
        * `sourceIp` → `data.request.clientIp`.
        * `service` → `data.request.serviceName`.
        * `operation` → `data.request.action`.

        (Use “Add dimension” and map them to the appropriate JSON fields via the UI.)

        **F. Metric Value**

        * Value expression: `1` (each matching log = 1 event).
        * Aggregation: **Sum**.

        3. Review and **Create** the Service Connector.
        4. Make sure it’s **Enabled** and wait a few minutes; generate a few denied actions (e.g., deliberately try something you don’t have permission for) and confirm metrics later.

        ***

        ## 4. Validate the Custom Metric in Monitoring

        1. Go to **Observability & Management → Monitoring → Metrics explorer**.
        2. Namespace: select `custom_security`.
        3. Metric name: select `access_denied_count`.
        4. Time period: last 1 hour.
        5. You should see data points if the Service Connector is working and access-denied events occurred.

        ***

        ## 5. Create an Alarm on Access Denied Enumeration

        1. Go to **Observability & Management → Alarms**.
        2. Click **Create alarm**.

        **A. Basic Details**

        * Name: e.g., `Access-Denied-Enumeration-Alarm`.
        * Compartment: choose appropriate (same where metric is visible).
        * Severity: e.g., **Critical** or **Warning** depending on policy.

        **B. Alarm Query**

        Example queries targeting enumeration behavior (lots of denies in a short time):

        **Simple total count across tenancy:**

        ```text theme={null}
        custom_security, metricName = "access_denied_count"[5m].sum() > 20
        ```

        This triggers when more than 20 denied events occur in 5 minutes.

        **Per principal (better for detecting brute-force / enumeration):**

        ```text theme={null}
        custom_security, metricName = "access_denied_count"
          {principal = "*"}[5m].sum() > 10
        ```

        Adjust thresholds and window to your policy (e.g., 10 denies in 5 minutes per principal).

        **C. Trigger Rule & Window**

        * Statistic: **Sum**.
        * Interval: e.g., **1 minute**.
        * Trigger delay: e.g., **1 evaluation period** (or as desired).

        **D. Notifications**

        1. Under **Notification destinations**, select or create a **Notification Topic** (OCI Notifications).

        2. If creating a new topic:
           * Go to **Application Integration → Notifications → Topics** (or use the inline option).
           * Create topic (e.g., `security-alerts-topic`).
           * Subscribe an **Email**, **Slack/HTTPS**, or **PagerDuty** endpoint.
           * Confirm the subscription by clicking the link in the confirmation email.

        3. Back in the alarm, select this topic as the destination.

        **E. Enable Alarm**

        * Ensure **Alarm state** is set to **Enabled**.
        * Click **Create alarm**.

        ***

        ## 6. Test the Alarm

        1. Generate several intentional access-denied events (e.g., use an IAM user with minimal privileges and attempt multiple unauthorized operations).
        2. Wait for:
           * The audit logs to capture events.
           * The Service Connector to convert them into metrics (usually within a couple of minutes).
           * The alarm to evaluate and potentially fire.
        3. Confirm you receive a **notification** and the alarm status changes to **FIRING** in the console.

        ***

        If you share your current log sample (an example Audit log JSON) and your preferred threshold (e.g., “more than X denied requests in Y minutes per principal”), I can give an exact filter expression and alarm query tailored to your tenancy.
      </Accordion>

      <Accordion title="Using CLI">
        Below is a practical way to remediate this using OCI Monitoring + OCI CLI: create an alarm on a metric that tracks access‑denied (“AuthorizationFailure”) activity.

        Because Monitoring works on **metrics**, you need either:

        * A **custom metric** that counts access‑denied events from Audit logs, or
        * An existing metric from your logging/ SIEM pipeline that already does this.

        The CLI part is the same once the metric exists.

        ***

        ## 1. Prerequisites

        1. **OCI CLI installed and configured**

        ```bash theme={null}
        oci iam user whoami
        ```

        2. **Notification Topic (for alerts)**
           * Create a topic if you don’t have one:

        ```bash theme={null}
        oci ons topic create \
          --name "security-alerts-topic" \
          --compartment-id <COMPARTMENT_OCID> \
          --description "Security alerts (access denied enumeration)"
        ```

        * Note the returned **topic OCID**, e.g.:\
          `ocid1.onstopic.oc1..aaaa...`

        3. **Metric that counts access-denied events**

        Example (common pattern):

        * Namespace: `security_audit`
        * Metric name: `access_denied_count`
        * Dimension: maybe `errorType = "AuthorizationFailure"`

        (If you don’t already publish such a metric, you must set up a Service Connector from Audit logs ⇒ Functions/Logging ⇒ custom metric first; that setup is separate from Monitoring and not covered in detail here.)

        ***

        ## 2. Decide alarm logic

        Typical query (example):

        * Trigger when there are **≥ 10 access‑denied events in 5 minutes**:

        ```text theme={null}
        security_audit.access_denied_count[5m]{errorType = "AuthorizationFailure"}.sum() >= 10
        ```

        Adjust the namespace/metric/dimension and threshold to match your environment and policy.

        ***

        ## 3. Create the alarm using OCI CLI

        Replace:

        * `<ALARM_COMPARTMENT_OCID>` – where the alarm resource lives
        * `<METRIC_COMPARTMENT_OCID>` – where the metric is emitted
        * `<TOPIC_OCID>` – your Notifications topic OCID
        * Adjust `--query-text` to your real metric namespace/name/dimensions

        ```bash theme={null}
        oci monitoring alarm create \
          --compartment-id <ALARM_COMPARTMENT_OCID> \
          --display-name "Access Denied Enumeration Alarm" \
          --metric-compartment-id <METRIC_COMPARTMENT_OCID> \
          --metric-compartment-id-in-subtree true \
          --severity CRITICAL \
          --is-enabled true \
          --destinations '["<TOPIC_OCID>"]' \
          --namespace "security_audit" \
          --query-text 'security_audit.access_denied_count[5m]{errorType = "AuthorizationFailure"}.sum() >= 10' \
          --resolution "1m" \
          --body "Alarm when repeated access-denied events (AuthorizationFailure) are detected, indicating possible enumeration activity." \
          --pending-duration "PT5M"
        ```

        Notes:

        * `--pending-duration "PT5M"`: alarm must remain in breach 5 minutes before firing (tune as needed).
        * `--resolution "1m"`: evaluate the metric every minute.

        If your metric is defined without `namespace` in the query (older/other style), omit `--namespace` and use:

        ```bash theme={null}
        --query-text 'access_denied_count[5m]{errorType = "AuthorizationFailure"}.sum() >= 10'
        ```

        ***

        ## 4. Verify the alarm

        List alarms:

        ```bash theme={null}
        oci monitoring alarm list \
          --compartment-id <ALARM_COMPARTMENT_OCID> \
          --all
        ```

        Get full details:

        ```bash theme={null}
        oci monitoring alarm get --alarm-id <ALARM_OCID>
        ```

        Test by generating a few controlled “access denied” events (or by temporarily lowering the threshold) and confirm a notification is sent to your configured subscription.

        ***

        If you tell me:

        * the exact **namespace**, **metric name**, and **dimensions** you use for access-denied counts,\
          I can give you a copy‑paste‑ready `oci monitoring alarm create` command tailored to your setup.
      </Accordion>

      <Accordion title="Using Python">
        Below is a concrete way to remediate this by **creating an OCI Monitoring Alarm (Access Denied / Enumeration)** using **Python + OCI SDK**.

        ***

        ## 1. Prerequisites

        1. Install OCI Python SDK:

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

        2. Make sure you have an OCI config file (usually `~/.oci/config`) with:

        * Tenancy OCID
        * User OCID
        * API key
        * Region
        * Key fingerprint

        3. IAM policy in the target compartment/tenancy (for the principal you are using):

        ```text theme={null}
        Allow group <your-group> to manage alarms in compartment <your-compartment-name>
        Allow group <your-group> to use metrics in compartment <your-compartment-name>
        Allow group <your-group> to use ons-topics in compartment <your-compartment-name>
        ```

        (If you use OCI Notifications to send email/SMS, you also need permission to manage/use topics.)

        ***

        ## 2. Choose Metric & Threshold (Access Denied Enumeration)

        Use the **Identity AuthFailure metric** (example – you can adjust):

        * **Namespace**: `oci_iam`
        * **Metric name**: `AuthFailure`
        * **Dimension**: `errorCode = "NotAuthorizedOrNotFound"` (typical for access denied)
        * **Example threshold**: more than 20 denied attempts in 5 minutes

        **Monitoring query expression (MQL):**

        ```text theme={null}
        AuthFailure[5m]{errorCode = "NotAuthorizedOrNotFound"}.sum() > 20
        ```

        Adjust values to your environment (namespace/metric/dimensions can be verified in OCI Console → Observability & Management → Metrics Explorer).

        ***

        ## 3. Python Code to Create the Alarm

        This example:

        * Creates an **alarm** named `AccessDeniedEnumerationAlarm`
        * Triggers when denied auth failures exceed the threshold
        * Sends notifications to an existing **OCI Notifications topic** (`topic_id`)

        ```python theme={null}
        import oci
        from oci.monitoring.models import CreateAlarmDetails

        # ---------------- CONFIG ----------------
        config = oci.config.from_file("~/.oci/config", "DEFAULT")

        compartment_id = "ocid1.compartment.oc1..xxxxxxxx"  # target compartment
        topic_id = "ocid1.onstopic.oc1..yyyyyyyy"           # existing OCI Notifications topic

        # Monitoring alarm settings
        alarm_display_name = "AccessDeniedEnumerationAlarm"
        alarm_metric_namespace = "oci_iam"
        alarm_metric_query = 'AuthFailure[5m]{errorCode = "NotAuthorizedOrNotFound"}.sum() > 20'
        alarm_severity = "CRITICAL"
        alarm_is_enabled = True
        alarm_message_format = "ONS_OPTIMIZED"
        alarm_repeat_notification_duration = "PT15M"  # repeat every 15 minutes while in alarm

        # ---------------- CLIENT ----------------
        monitoring_client = oci.monitoring.MonitoringClient(config)

        # ---------------- CREATE ALARM ----------------
        create_alarm_details = CreateAlarmDetails(
            display_name=alarm_display_name,
            compartment_id=compartment_id,
            is_enabled=alarm_is_enabled,
            # Monitoring query
            query=alarm_metric_query,
            # Where metrics live
            namespace=alarm_metric_namespace,
            # Notification destinations
            destinations=[topic_id],
            # Alarm severity
            severity=alarm_severity,
            # Human-readable description
            description="Alarm for detection of potential access denied enumeration (AuthFailure NotAuthorizedOrNotFound).",
            # Notification message format
            message_format=alarm_message_format,
            # How often to repeat notifications while in alarm (ISO 8601 duration)
            repeat_notification_duration=alarm_repeat_notification_duration,
        )

        response = monitoring_client.create_alarm(create_alarm_details)
        alarm = response.data

        print("Alarm created:")
        print("  OCID:        ", alarm.id)
        print("  Display name:", alarm.display_name)
        print("  Query:       ", alarm.query)
        print("  Namespace:   ", alarm.namespace)
        ```

        ***

        ## 4. Validate the Alarm

        1. In OCI Console:
           * Observability & Management → **Alarms**
           * Check that `AccessDeniedEnumerationAlarm` exists and is in the correct compartment.
           * Verify the query, namespace, and destination topic.

        2. Generate test events (or temporarily lower threshold) to verify the alarm changes to **FIRING** and sends notifications.

        ***

        If you can share the exact metric/namespace you want to use (e.g., console logins, specific service, or audit-derived metrics), I can adapt the query and code snippet precisely to that metric.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "oci_monitoring_alarm" "access_denied_enumeration" {
          # OCID of the compartment in which to create the alarm
          compartment_id = "COMPARTMENT_OCID"

          # Human‑readable name for the alarm
          display_name = "AccessDenied Enumeration – Unauthorized API Errors"

          # Metric query that detects high‑frequency unauthorized API errors.
          # Replace METRIC_QUERY_FOR_UNAUTHORIZED_ERRORS with the exact query you
          # already use or have validated in the OCI Console Monitoring query editor.
          #
          # Example pattern (do NOT use blindly; validate in Console first):
          #   "ApiErrors[5m]{errorCode = 'NotAuthorizedOrNotFound'}.sum() > 50"
          #
          query = "METRIC_QUERY_FOR_UNAUTHORIZED_ERRORS"

          # Alarm severity: "CRITICAL", "ERROR", "WARNING", "INFO"
          severity = "CRITICAL"

          # OCIDs of Notification topics that should receive the alarm notifications
          destinations = [
            "NOTIFICATION_TOPIC_OCID",
          ]

          # Enable the alarm
          is_enabled = true

          # How often the alarm should repeat if the condition remains true
          # (ISO 8601 duration format, e.g., "PT15M" = 15 minutes)
          repeat_notification_duration = "PT15M"

          # Optional free‑form and defined tags
          freeform_tags = {
            "NAME"        = "AccessDeniedEnumerationAlarm"
            "ENVIRONMENT" = "PRODUCTION"
          }
        }
        ```

        Substitute:

        * `COMPARTMENT_OCID` with the OCID of the compartment where you want the alarm.
        * `NOTIFICATION_TOPIC_OCID` with the OCID of the OCI Notifications topic that should receive alarm notifications.
        * `METRIC_QUERY_FOR_UNAUTHORIZED_ERRORS` with the exact Monitoring query that counts unauthorized / access‑denied API errors at the threshold you require (build and validate this in the Monitoring > Metrics console, then paste the working expression here).

        This change updates/creates an `oci_monitoring_alarm` in place and does not force replacement of other resources.

        After editing, `terraform plan` should show either:

        * `+ create` of one `oci_monitoring_alarm` if it’s new, or
        * `~ update in-place` on the existing `oci_monitoring_alarm` with the `query`, `display_name`, `severity`, `destinations`, or `is_enabled` arguments changing as configured.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
