> ## 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 IAM Policies Should Not Grant All Resources Access To Any User

### More Info:

IAM policies should follow the principle of least privilege. Policies granting any-user access to manage all-resources create an excessive attack surface and violate security best practices.

### Risk Level

Critical

### Address

Compliance, Security

### Compliance Standards

* APRA CPS 234 (Australia)
* 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are step‑by‑step remediation instructions using the **OCI Console** to fix IAM policies that grant **all-resources** access, specifically for Monitoring–related access.

        ***

        ### 1. Locate Overly Permissive IAM Policies

        1. Sign in to the **OCI Console**.
        2. Open the **Navigation menu** → **Identity & Security** → **Identity** → **Policies**.
        3. Check both:
           * The **tenancy (root) compartment**.
           * Any **subcompartments** where Monitoring is used.
        4. In each compartment’s **Policies** page:
           * Open each policy and look for statements containing:
             * `all-resources`
             * `resource-type all-resources`
             * `inspect all-resources in tenancy`
             * `read all-resources in compartment <name>`
             * `manage all-resources in compartment <name>`
           * Also look for broad wildcards in tags or conditions (e.g., no condition narrowing users/groups).

        Those are the misconfigurations you must replace with least‑privilege, Monitoring‑specific statements.

        ***

        ### 2. Determine the Actual Need for Monitoring

        For each policy with `all-resources`, determine what the user/group is **actually supposed to do** with Monitoring. Common needs:

        * View metrics and alarms:
          * `inspect metrics-family`
          * `read metrics-family`
          * `inspect alarms`
          * `read alarms`
        * Create or modify alarms/metrics:
          * `manage metrics-family`
          * `manage alarms`

        Scope these either at:

        * The **tenancy** (if absolutely necessary), or
        * A **specific compartment** where Monitoring resources live.

        ***

        ### 3. Replace “all-resources” with Monitoring‑Scoped Verbs/Resources

        For each offending policy:

        1. Open the policy in the console.

        2. Click **Edit Policy**.

        3. Replace any broad lines like:

           ```text theme={null}
           Allow group MonitoringAdmins to manage all-resources in tenancy
           ```

           with more specific monitoring‑related rules, for example:

           **View only:**

           ```text theme={null}
           Allow group MonitoringAdmins to inspect metrics-family in tenancy
           Allow group MonitoringAdmins to read metrics-family in tenancy
           Allow group MonitoringAdmins to inspect alarms in tenancy
           Allow group MonitoringAdmins to read alarms in tenancy
           ```

           **Full management (Monitoring only):**

           ```text theme={null}
           Allow group MonitoringAdmins to manage metrics-family in tenancy
           Allow group MonitoringAdmins to manage alarms in tenancy
           ```

           Prefer compartment scoping where possible:

           ```text theme={null}
           Allow group MonitoringAdmins to manage metrics-family in compartment <monitoring-compartment>
           Allow group MonitoringAdmins to manage alarms in compartment <monitoring-compartment>
           ```

        4. If the group also legitimately needs access to other services, add **separate, specific** statements for those service resource-types instead of using `all-resources`.

        5. Click **Save Changes**.

        ***

        ### 4. Remove Any Residual “all-resources” Access

        * Ensure there are **no remaining** statements like:
          * `inspect all-resources in tenancy`
          * `read all-resources in tenancy`
          * `manage all-resources in tenancy`
          * or the same at compartment scope.
        * If a user/group needs broad view across services, consider:
          * `inspect <service>-family` per service instead of `all-resources`.

        ***

        ### 5. Validate Access

        1. Use a **test user** (or ask an actual user from the group) to:
           * Navigate to **Observability & Management** → **Monitoring**.
           * Confirm:
             * They can perform required Monitoring actions (view/create/edit alarms, view metrics).
             * They **cannot** perform unrelated actions (e.g., manage Compute, Networking, IAM) that the previous `all-resources` policy allowed.
        2. If some actions fail that should succeed, add only the **minimal extra permissions** needed.

        ***

        ### 6. (Optional) Use Cloud Guard / Security Advisor

        If you’re using OCI **Cloud Guard** or **Security Advisor**:

        1. Go to **Navigation menu** → **Identity & Security** → **Cloud Guard** (or **Security Advisor**).
        2. Review findings related to:
           * “IAM policies granting access to all-resources” or similar.
        3. Verify that the updated policies clear those findings after your changes propagate.

        ***

        If you paste a specific policy statement you’re remediating, I can give you the exact replacement lines for Monitoring.
      </Accordion>

      <Accordion title="Using CLI">
        Below is a practical, CLI‑only approach to find and fix OCI IAM policies that wrongly grant `all-resources` and then replace them with least-privilege for IAM/Monitoring use cases.

        ***

        ## 1. Prerequisites

        Make sure:

        * OCI CLI is installed and configured (`oci setup config`).
        * You know your **tenancy OCID**.
        * You have access to **list and update policies**.

        ***

        ## 2. Identify Policies Granting `all-resources`

        ### 2.1. List all policies in the tenancy

        ```bash theme={null}
        TENANCY_OCID="<your_tenancy_ocid>"

        oci iam policy list \
          --compartment-id "$TENANCY_OCID" \
          --all \
          --output table
        ```

        If you have policies in sub‑compartments only, repeat for those `compartment-id`s.

        ### 2.2. Filter policies whose statements contain `all-resources`

        ```bash theme={null}
        oci iam policy list \
          --compartment-id "$TENANCY_OCID" \
          --all \
          --query "data[?contains(to_string(statements), 'all-resources')].[name,id,statements]" \
          --output table
        ```

        Note the **policy name** and **OCID** for each one you must fix.

        ***

        ## 3. Inspect Each Problematic Policy

        Pick a policy OCID from the previous step:

        ```bash theme={null}
        POLICY_OCID="<policy_ocid>"

        oci iam policy get \
          --policy-id "$POLICY_OCID" \
          --query "data.{name:name,compartmentId:compartment-id,statements:statements}" \
          --output json
        ```

        Look for statements like:

        ```text theme={null}
        Allow group <group-name> to manage all-resources in tenancy
        Allow dynamic-group <dg-name> to read all-resources in compartment <compartment-name>
        ```

        ***

        ## 4. Design Least-Privilege Replacement

        For **IAM monitoring / security monitoring** (typical “read-only” or “events/logs” access), replace `all-resources` with specific resource-types and verbs.

        Common examples (adapt to your use case):

        ### 4.1. Read-only IAM & Security Posture

        ```text theme={null}
        Allow group iam-monitors to read users in tenancy
        Allow group iam-monitors to read groups in tenancy
        Allow group iam-monitors to read policies in tenancy
        Allow group iam-monitors to read compartments in tenancy
        Allow group iam-monitors to read tag-namespaces in tenancy
        Allow group iam-monitors to read cloud-guard-family in tenancy
        Allow group iam-monitors to read security-zone-family in tenancy
        ```

        ### 4.2. Monitoring / Logging / Events in a compartment

        ```text theme={null}
        Allow group iam-monitors to read metrics in compartment <compartment-name>
        Allow group iam-monitors to read alarms in compartment <compartment-name>
        Allow group iam-monitors to read log-groups in compartment <compartment-name>
        Allow group iam-monitors to read logs in compartment <compartment-name>
        Allow group iam-monitors to read events in compartment <compartment-name>
        ```

        Replace `<group-name>` and `<compartment-name>` accordingly, and **only include what is actually needed**.

        ***

        ## 5. Update the Policy Using OCI CLI

        You will:

        1. Build a new JSON array of statements.
        2. Use `oci iam policy update` to replace the existing statements.

        ### 5.1. Create a file with the new statements

        Create `policy-statements.json`:

        ```json theme={null}
        [
          "Allow group iam-monitors to read users in tenancy",
          "Allow group iam-monitors to read groups in tenancy",
          "Allow group iam-monitors to read policies in tenancy",
          "Allow group iam-monitors to read compartments in tenancy",
          "Allow group iam-monitors to read metrics in compartment my-monitoring-compartment",
          "Allow group iam-monitors to read alarms in compartment my-monitoring-compartment",
          "Allow group iam-monitors to read log-groups in compartment my-monitoring-compartment",
          "Allow group iam-monitors to read logs in compartment my-monitoring-compartment"
        ]
        ```

        Adjust to your actual requirements.

        ### 5.2. (Optional) Backup the current policy

        ```bash theme={null}
        oci iam policy get \
          --policy-id "$POLICY_OCID" \
          --output json > "${POLICY_OCID}_backup.json"
        ```

        ### 5.3. Update the policy

        ```bash theme={null}
        oci iam policy update \
          --policy-id "$POLICY_OCID" \
          --statements file://policy-statements.json \
          --force
        ```

        ***

        ## 6. Validate the Remediation

        ### 6.1. Confirm the new statements

        ```bash theme={null}
        oci iam policy get \
          --policy-id "$POLICY_OCID" \
          --query "data.statements" \
          --output json
        ```

        Ensure there is **no** `all-resources` present:

        ```bash theme={null}
        oci iam policy get \
          --policy-id "$POLICY_OCID" \
          --query "data.statements[?contains(@, 'all-resources')]" \
          --output json
        ```

        This should return `[]`.

        ### 6.2. Re-scan for any remaining `all-resources` policies

        ```bash theme={null}
        oci iam policy list \
          --compartment-id "$TENANCY_OCID" \
          --all \
          --query "data[?contains(to_string(statements), 'all-resources')].[name,id]" \
          --output table
        ```

        Repeat Steps 3–5 for any remaining policies.

        ***

        ## 7. (Optional) Automate Continuous Checking

        You can periodically run a script that:

        1. Lists all policies in the tenancy and sub‑compartments.
        2. Flags any containing `all-resources`.
        3. Sends an alert (e.g., to your monitoring system).

        Skeleton example:

        ```bash theme={null}
        TENANCY_OCID="<your_tenancy_ocid>"

        oci iam policy list \
          --compartment-id "$TENANCY_OCID" \
          --all \
          --query "data[?contains(to_string(statements), 'all-resources')].[name,id,statements]" \
          --output json
        ```

        Use this output as input to your monitoring pipeline.

        ***

        If you share one current policy statement you’re using for IAM Monitoring, I can translate it into a concrete least‑privilege `policy-statements.json` ready to apply via CLI.
      </Accordion>

      <Accordion title="Using Python">
        Below is a practical way to **detect and remediate** “all-resources” IAM policies in OCI using Python and the OCI SDK.

        ***

        ## 1. What you’re remediating

        Bad pattern (overly broad policy examples):

        ```text theme={null}
        Allow group MyAdmins to manage all-resources in tenancy
        Allow group Devs to read all-resources in tenancy
        Allow dynamic-group all_functions to use all-resources in compartment MyCompartment
        ```

        You want to:

        1. **Identify** such policies.
        2. **Decide** what the correct least-privilege policies should be.
        3. **Programmatically update** or flag them using Python.

        ***

        ## 2. Prerequisites

        1. Install SDK:

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

        2. Configure OCI credentials: `~/.oci/config` with a profile, e.g. `[DEFAULT]`.

        3. Have **policy manage permission** for your user:

           * For example (granted by someone with tenancy admin rights):

           ```text theme={null}
           Allow group PolicyAdmins to manage policies in tenancy
           ```

        ***

        ## 3. Detection Script – Find “all-resources” Policies

        This script:

        * Lists policies in tenancy (or in all compartments).
        * Flags statements that reference `all-resources`.

        ```python theme={null}
        import oci
        import re

        CONFIG_PROFILE = "DEFAULT"  # change if needed

        def contains_all_resources(statement: str) -> bool:
            # normalize spacing/case
            s = statement.lower()
            return "all-resources" in s

        def main():
            config = oci.config.from_file("~/.oci/config", CONFIG_PROFILE)
            identity = oci.identity.IdentityClient(config)
            tenancy_id = config["tenancy"]

            # Get all compartments (include root)
            compartments = oci.pagination.list_call_get_all_results(
                identity.list_compartments,
                tenancy_id,
                compartment_id_in_subtree=True,
                access_level="ANY"
            ).data

            compartment_ids = [tenancy_id] + [c.id for c in compartments if c.lifecycle_state == "ACTIVE"]

            print("Scanning policies for 'all-resources' usage...")
            for comp_id in compartment_ids:
                # list policies in this compartment
                policies = oci.pagination.list_call_get_all_results(
                    identity.list_policies,
                    compartment_id=comp_id
                ).data

                for policy in policies:
                    if policy.lifecycle_state != "ACTIVE":
                        continue

                    bad_statements = [s for s in policy.statements if contains_all_resources(s)]
                    if bad_statements:
                        print(f"\n[!] Policy: {policy.name} (OCID: {policy.id}) in compartment {comp_id}")
                        for s in bad_statements:
                            print(f"    Statement: {s}")

        if __name__ == "__main__":
            main()
        ```

        Use this first to **monitor** and report problems (e.g., run in a scheduled job, push results to Monitoring/Logging, etc.).

        ***

        ## 4. Plan Your Remediation

        You must define what **permitted resources and actions** should be instead of `all-resources`, such as:

        * Replace:
          ```text theme={null}
          Allow group Devs to read all-resources in compartment MyCompartment
          ```
        * With something like:
          ```text theme={null}
          Allow group Devs to inspect instance-family in compartment MyCompartment
          Allow group Devs to read object-family in compartment MyCompartment
          Allow group Devs to inspect volume-family in compartment MyCompartment
          ```

        This mapping **cannot be safely guessed by a script**; you should define a mapping table per group/use case.

        Example mapping in Python:

        ```python theme={null}
        # Example: define what to replace for each group / pattern
        REMediation_MAP = {
            # key: regex or simple substring for original; value: list of new statements
            r"allow group devs to read all-resources in compartment (\S+)": lambda m: [
                f"Allow group Devs to inspect instance-family in compartment {m.group(1)}",
                f"Allow group Devs to read object-family in compartment {m.group(1)}",
            ],
            # add more patterns per group/use-case
        }
        ```

        ***

        ## 5. Remediation Script – Replace “all-resources” Statements

        This script:

        * Finds policies with `all-resources`.
        * For each affected statement, either:
          * Rewrites it using a custom mapping, **or**
          * Comments it out and leaves the policy for manual editing (safer default).

        Below is a conservative version that **comments out** the bad statements and adds a note, which is safer for automated remediation. After that you can manually refine/replace.

        ```python theme={null}
        import oci
        from datetime import datetime

        CONFIG_PROFILE = "DEFAULT"
        DRY_RUN = True  # set to False to actually update policies

        def contains_all_resources(statement: str) -> bool:
            return "all-resources" in statement.lower()

        def remediate_policy(identity, policy, dry_run=True):
            original_statements = policy.statements
            new_statements = []

            changed = False
            timestamp = datetime.utcnow().isoformat() + "Z"

            for s in original_statements:
                if contains_all_resources(s):
                    changed = True
                    # Comment out the risky statement and add a marker line
                    commented = f"# DISABLED {timestamp} (had all-resources): {s}"
                    note = f"# TODO: Replace this statement with least-privilege equivalent."
                    new_statements.append(commented)
                    new_statements.append(note)
                else:
                    new_statements.append(s)

            if not changed:
                return False  # nothing to do

            if dry_run:
                print(f"[DRY-RUN] Would update policy {policy.name} ({policy.id})")
                print("  Old statements:")
                for s in original_statements:
                    print("   ", s)
                print("  New statements:")
                for s in new_statements:
                    print("   ", s)
                return True

            # Perform actual update
            update_details = oci.identity.models.UpdatePolicyDetails(
                description=policy.description,
                statements=new_statements,
                version_date=policy.version_date  # keep existing date or set new
            )

            response = identity.update_policy(policy.id, update_details)
            print(f"[UPDATED] Policy {policy.name} ({policy.id}) updated.")
            return True

        def main():
            config = oci.config.from_file("~/.oci/config", CONFIG_PROFILE)
            identity = oci.identity.IdentityClient(config)
            tenancy_id = config["tenancy"]

            compartments = oci.pagination.list_call_get_all_results(
                identity.list_compartments,
                tenancy_id,
                compartment_id_in_subtree=True,
                access_level="ANY"
            ).data

            compartment_ids = [tenancy_id] + [c.id for c in compartments if c.lifecycle_state == "ACTIVE"]

            for comp_id in compartment_ids:
                policies = oci.pagination.list_call_get_all_results(
                    identity.list_policies,
                    compartment_id=comp_id
                ).data

                for policy in policies:
                    if policy.lifecycle_state != "ACTIVE":
                        continue

                    has_all = any(contains_all_resources(s) for s in policy.statements)
                    if not has_all:
                        continue

                    print(f"\n[FOUND] Policy with all-resources: {policy.name} (OCID: {policy.id})")
                    remediate_policy(identity, policy, dry_run=DRY_RUN)

        if __name__ == "__main__":
            main()
        ```

        Usage:

        * First run **as monitoring / audit**:

          ```bash theme={null}
          python remediate_policies.py  # with DRY_RUN = True
          ```

        * Review printed before/after.

        * After you’re confident, set `DRY_RUN = False` and rerun to apply.

        ***

        ## 6. Integrating With IAM Monitoring

        For continuous monitoring:

        1. Run a **scheduled job** (e.g., OCI Functions + OCI Events + Logging or an external scheduler like cron) to:
           * Execute the **detection** portion.
           * Send findings to:
             * OCI Logging (via Logging API),
             * Email (via Notifications),
             * Metrics (via Monitoring API) so you can create an alarm when count > 0.

        2. Optionally have a “remediation mode” script:
           * Triggered manually (or via an approval flow),
           * Uses the remediation logic above.

        If you want, I can extend this with:

        * Sample OCI Function (Python) handler for detection,
        * Or a version that actually rewrites specific “all-resources” lines into concrete least-privilege policies based on a configuration file.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "oci_identity_policy" "iam_monitoring_least_privilege" {
          # Replace with your actual compartment OCID (or tenancy OCID if it's a tenancy-level policy)
          compartment_id = "OCID_OF_COMPARTMENT_OR_TENANCY"

          # Replace with your existing policy OCID if you are managing an existing policy,
          # otherwise omit `id` and treat this as a new policy.
          # id = "OCID_OF_EXISTING_POLICY"

          name        = "iam-monitoring-policy"
          description = "Least-privilege policy for IAM Monitoring; no any-user manage all-resources"

          # REMOVE/WITHDRAW POLICIES LIKE THIS (OVERLY BROAD - DO NOT KEEP):
          # "Allow any-user to manage all-resources in tenancy"

          # INSTEAD, USE LEAST PRIVILEGE, SCOPED TO A GROUP AND SPECIFIC SERVICES / VERBS.
          # Example for IAM Monitoring use case: a group allowed to read metrics and alarms only.
          statements = [
            # Replace GROUP_NAME with the actual IAM group you intend to grant access to
            "Allow group GROUP_NAME to read metrics in compartment COMPARTMENT_NAME",
            "Allow group GROUP_NAME to read alarms in compartment COMPARTMENT_NAME",

            # If you need IAM-related monitoring (e.g., audit logs), scope precisely:
            # "Allow group GROUP_NAME to read audit-events in compartment COMPARTMENT_NAME"
          ]
        }
        ```

        Changing the `statements` in `oci_identity_policy` is an in‑place update and does not force replacement of the policy resource; OCI will update the policy text without deleting/recreating it.

        For verification, `terraform plan` should show an update to `oci_identity_policy.iam_monitoring_least_privilege`, with a diff only on the `statements` attribute, removing any `Allow any-user ... manage all-resources ...` entries and replacing them with the new, scoped statements.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
