> ## 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 Admin Full Access Policies Should Have WHERE Conditions

### More Info:

Admin full-access policies (manage all-resources) should include WHERE conditions. Unconditional full access violates least privilege and increases blast radius if admin credentials are compromised.

### Risk Level

High

### 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 the minimal, practical steps to remediate this using the OCI Console by tightening IAM admin policies with `where` conditions and aligning them with OCI IAM Monitoring findings.

        ***

        ## 1. Find the Violating Policy from IAM Monitoring

        1. Sign in to the OCI Console.
        2. Open the navigation menu → **Identity & Security** → **Identity & Access Monitoring** (or **IAM Monitoring** / **Security Center → IAM Monitoring**, depending on your tenancy UI).
        3. Go to **Findings** / **Risky Policies**.
        4. Filter by rule / description containing:\
           `OCI IAM Admin Full Access Policies Should Have WHERE Conditions`
        5. Open the finding and note:
           * **Policy name**
           * **Compartment (or Tenancy)**
           * **Policy statement(s)** that are flagged (you will usually see statements like\
             `Allow group <Admins> to manage all-resources in tenancy` or similar full admin rights without `where`).

        ***

        ## 2. Open and Edit the Policy

        1. From the navigation menu → **Identity & Security** → **Identity & Governance** → **Policies**.
        2. In the **Compartment** dropdown, choose:
           * **Tenancy (root)** if the policy is at tenancy level, or
           * The **compartment** containing the policy as seen in the finding.
        3. Search for the **policy name** you noted in step 1.
        4. Click the policy, then click **Edit Policy Statements** (or **Edit Policy**).

        You will see one or more statements like:

        ```text theme={null}
        Allow group Admins to manage all-resources in tenancy
        Allow group SuperAdmins to manage all-resources in compartment my-compartment
        ```

        These are what need conditions.

        ***

        ## 3. Decide on Appropriate `where` Conditions

        You must decide what constraint is appropriate for your environment. Common patterns:

        ### a) Tag-based restriction (recommended for fine-grained admin)

        ```text theme={null}
        Allow group Admins to manage all-resources in tenancy
          where target.resource.tag.namespace = 'CostCenter' &&
                target.resource.tag.key = 'Critical'
        ```

        ### b) Network-based restriction (admin only from trusted IPs / CIDRs)

        ```text theme={null}
        Allow group Admins to manage all-resources in tenancy
          where request.network.source.ip.address in ('203.0.113.0/24')
        ```

        ### c) Time-based restriction (admin only within business hours)

        ```text theme={null}
        Allow group Admins to manage all-resources in tenancy
          where request.time < '2026-12-31T23:59:59Z'
        ```

        or:

        ```text theme={null}
        Allow group Admins to manage all-resources in tenancy
          where request.time > '2026-07-25T08:00:00Z' &&
                request.time < '2026-07-25T18:00:00Z'
        ```

        ### d) Restrict to specific compartments (if using overly broad “tenancy”)

        Instead of `in tenancy`, use compartment-scoped statements, or compensate with conditions:

        ```text theme={null}
        Allow group Admins to manage all-resources in tenancy
          where target.compartment.id = 'ocid1.compartment.oc1..aaaa...'
        ```

        Or even better, change it to more specific statements per compartment, each with conditions.

        ***

        ## 4. Rewrite the Problematic Statement(s)

        For each flagged full-admin statement:

        1. Copy the existing statement to a text editor.
        2. Add a **WHERE** clause that matches your control choice (tag, IP, time, compartment, etc.).

        Example transformation:

        **Before (violation):**

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

        **After (remediated):**

        ```text theme={null}
        Allow group Admins to manage all-resources in tenancy
          where request.network.source.ip.address in ('203.0.113.0/24')
        ```

        Or:

        ```text theme={null}
        Allow group Admins to manage all-resources in tenancy
          where target.resource.tag.namespace = 'AdminScope' &&
                target.resource.tag.key = 'Allowed'
        ```

        3. Replace the old statement with the new one in the policy editor.
        4. Review for typos (invalid conditions can break policy evaluation).
        5. Click **Save changes**.

        ***

        ## 5. Validate in IAM Monitoring

        1. Return to **Identity & Access Monitoring / IAM Monitoring**.
        2. Open the previous **finding**.
        3. After a short interval (or by manually triggering re-evaluation, if available), verify that:
           * The finding is now **Resolved** or **No longer detected**, OR
           * A new finding clearly indicates any further issue (e.g., syntactic problem with your `where` clause).

        ***

        ## 6. If You Need a Safe Migration Approach

        If you are worried about locking out admins:

        1. **Create a new policy** with the intended `where`-restricted statements.
        2. Have one or two admins verify they can still perform required operations.
        3. Once confirmed:
           * Edit the original policy and remove or tighten the overly broad statements.
        4. Re-check IAM Monitoring findings.

        ***

        If you tell me:

        * Your current exact policy statement(s), and
        * How you prefer to restrict admin (by IP, tag, compartment, or time),

        I can give you a ready-to-paste `where`-clause example tailored to your tenancy.
      </Accordion>

      <Accordion title="Using CLI">
        Below is a minimal, CLI‑only workflow you can use to remediate the finding “OCI IAM Admin Full Access Policies Should Have WHERE Conditions” for IAM Monitoring.

        Assumptions:

        * You already have the OCI CLI configured (`oci setup config` done).
        * You know (or can discover) the compartment(s) where the IAM policies are defined.
        * Your goal is to **add a WHERE condition** to “admin” / “full access” style statements such as `manage all-resources`.

        ***

        ## 1. Identify affected IAM policies

        List policies in the tenancy (or a specific compartment) and search for “manage all-resources” without a `where` clause.

        ```bash theme={null}
        TENANCY_OCID="<your-tenancy-ocid>"

        oci iam policy list \
          --compartment-id "$TENANCY_OCID" \
          --all \
          --output json \
        | jq -r '
          .data[]
          | select(.statements[] | test("manage all-resources in tenancy(?!.*where).*"; "i"))
          | {name: .name, id: .id, statements: .statements}
        '
        ```

        Adjust the regex if your statements use `in compartment <name>` instead of `in tenancy`.

        From this output, note:

        * `id` – the policy OCID
        * `statements` – the existing statements that need to be edited

        ***

        ## 2. Decide the appropriate WHERE condition

        You must pick a condition that makes sense for **IAM Monitoring**. Common patterns:

        1. Limit by compartment:
           ```text theme={null}
           where target.compartment.id = 'ocid1.compartment.oc1..xxxx'
           ```

        2. Limit to IAM‑related resources:
           ```text theme={null}
           where any {
             target.resource.type = 'policy',
             target.resource.type = 'group',
             target.resource.type = 'user',
             target.resource.type = 'dynamic-group'
           }
           ```

        3. Limit to read‑only monitoring:
           ```text theme={null}
           where all {
             request.permission in ('POLICY_INSPECT','POLICY_READ','GROUP_INSPECT','GROUP_READ','USER_INSPECT','USER_READ','DYNAMIC-GROUP_INSPECT','DYNAMIC-GROUP_READ')
           }
           ```

        For example, a previous statement:

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

        could be tightened to something like:

        ```text theme={null}
        Allow group IAM-Monitors to manage all-resources in tenancy
        where any {
          target.resource.type = 'policy',
          target.resource.type = 'group',
          target.resource.type = 'user',
          target.resource.type = 'dynamic-group'
        }
        ```

        Pick and design the `where` that matches your security requirement.

        ***

        ## 3. Build the updated list of statements (locally)

        1. Export the current policy to a file:

           ```bash theme={null}
           POLICY_OCID="<policy-ocid-from-step-1>"

           oci iam policy get \
             --policy-id "$POLICY_OCID" \
             --output json \
           > policy-orig.json
           ```

        2. Extract the current `statements` to a simple JSON array:

           ```bash theme={null}
           jq '.data.statements' policy-orig.json > statements-orig.json
           ```

        3. Edit `statements-orig.json` with any text editor.

           * Replace each “admin/full access” statement, e.g.:

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

           * With a version that includes an appropriate WHERE condition, e.g.:

             ```text theme={null}
             "Allow group IAM-Monitors to manage all-resources in tenancy where any { target.resource.type = 'policy', target.resource.type = 'group', target.resource.type = 'user', target.resource.type = 'dynamic-group' }"
             ```

           Make sure the file remains valid JSON (array of strings).

        ***

        ## 4. Update the policy with the new statements (CLI)

        Once `statements-orig.json` contains your fixed statements:

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

        Optionally preserve / update description:

        ```bash theme={null}
        DESC=$(jq -r '.data.description' policy-orig.json)

        oci iam policy update \
          --policy-id "$POLICY_OCID" \
          --description "$DESC" \
          --statements file://statements-orig.json
        ```

        ***

        ## 5. Verify

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

        Confirm every “full access” / `manage all-resources` statement now contains a `where` clause.

        ***

        ## 6. Automate (optional)

        To remediate many policies, you can script:

        1. Use the `list` + `jq` filter from step 1 to enumerate candidate policies.
        2. For each:
           * Pull policy JSON
           * Use a small script (bash + `jq` or Python) to find statements matching `manage all-resources` or other full‑admin patterns and append a standard `where` clause for IAM Monitoring.
           * Call `oci iam policy update` with the transformed list of statements.

        If you tell me the exact IAM Monitoring group(s) and what they *should* be allowed to do, I can give a concrete `where` template and a sample automation script.
      </Accordion>

      <Accordion title="Using Python">
        Below is a practical way to **detect** and then **remediate** overly‑permissive IAM policies in OCI (those with admin/full access and no `where` conditions) using Python and the OCI SDK.

        ***

        ## 1. What “Admin Full Access Without WHERE” Means

        In OCI, a risky policy typically looks like:

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

        or

        ```text theme={null}
        Allow group DevOps to manage all-resources in compartment MyCompartment
        ```

        These give broad “admin” rights without any limiting `where` clause such as:

        ```text theme={null}
        ... where request.principal.type = 'user'
        ... where request.user.name != 'service-xyz'
        ... where target.compartment.id = 'ocid1.compartment.oc1..xxxxx'
        ```

        The goal is to:

        1. Find statements that are “full access” (e.g., `manage all-resources`, `manage *`).
        2. Ensure they have a `where` condition.
        3. If not, either:
           * Automatically **replace** them with a safer version, or
           * **Alert** and require a human to decide the proper condition.

        ***

        ## 2. Prerequisites

        1. Install the OCI Python SDK:

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

        2. Configure your OCI credentials (e.g., `~/.oci/config`) and note:
           * Tenancy OCID
           * User OCID
           * Key file path
           * Fingerprint
           * Region

        3. Give your monitoring principal (user or dynamic group) permission to read and update policies, for example:

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

        (You can weaken `manage` to specific compartments if needed.)

        ***

        ## 3. Detection Logic (Python)

        This script:

        * Lists all policies
        * Parses each statement
        * Flags those that appear to be “admin/full access” and that do **not** include `where`

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

        # ---------- CONFIG ----------
        PROFILE = "DEFAULT"          # Profile in ~/.oci/config
        TENANCY_OCID = "<your-tenancy-ocid>"  # or read from config
        DRY_RUN = True               # True = only report; False = also remediate (see section 4)
        # ----------------------------

        config = oci.config.from_file(profile_name=PROFILE)
        identity_client = oci.identity.IdentityClient(config)


        def is_admin_full_access(statement: str) -> bool:
            """
            Very simple heuristic: adjust as needed.
            We look for 'to manage all-resources' or 'to manage *'
            """
            s = statement.lower()
            return (
                " to manage all-resources" in s
                or " to manage *" in s
                or re.search(r"\bto\s+manage\s+all-resources\b", s)
            )


        def has_where_clause(statement: str) -> bool:
            return " where " in statement.lower()


        def get_all_policies(identity_client, tenancy_ocid):
            policies = []
            response = identity_client.list_policies(
                compartment_id=tenancy_ocid,
                compartment_id_in_subtree=True
            )
            policies.extend(response.data)
            while response.has_next_page:
                response = identity_client.list_policies(
                    compartment_id=tenancy_ocid,
                    compartment_id_in_subtree=True,
                    page=response.next_page
                )
                policies.extend(response.data)
            return policies


        def main():
            policies = get_all_policies(identity_client, TENANCY_OCID)

            print("Scanning policies for admin full access without WHERE conditions...\n")

            for policy in policies:
                risky_statements = []
                for stmt in policy.statements:
                    if is_admin_full_access(stmt) and not has_where_clause(stmt):
                        risky_statements.append(stmt)

                if risky_statements:
                    print(f"Policy: {policy.name} (OCID: {policy.id}) in compartment {policy.compartment_id}")
                    for rs in risky_statements:
                        print(f"  RISKY: {rs}")

                    if not DRY_RUN:
                        remediate_policy(identity_client, policy, risky_statements)

                    print("-" * 80)


        def remediate_policy(identity_client, policy, risky_statements):
            """
            This function just shows one *pattern* of remediation:
            - Append a WHERE condition to the risky statements.
            Adjust the 'SAFE_WHERE_CLAUSE' to your real guardrails.
            """
            SAFE_WHERE_CLAUSE = " where request.principal.type = 'user'"

            updated_statements = []
            for stmt in policy.statements:
                if stmt in risky_statements:
                    # Example: add a simple where clause if none is present
                    new_stmt = stmt + SAFE_WHERE_CLAUSE
                    updated_statements.append(new_stmt)
                    print(f"  REMEDIATING: {stmt}")
                    print(f"  -> NEW:      {new_stmt}")
                else:
                    updated_statements.append(stmt)

            update_details = oci.identity.models.UpdatePolicyDetails(
                description=policy.description,
                statements=updated_statements,
                version_date=policy.version_date
            )

            response = identity_client.update_policy(policy.id, update_details)
            print(f"  Policy updated: {response.data.name}")


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

        ***

        ## 4. Remediation Strategy (What to Actually Change)

        You must decide **what** restriction makes sense for your environment. Some common patterns:

        1. **Limit to users (not instance principals / services):**

           ```text theme={null}
           where request.principal.type = 'user'
           ```

        2. **Exclude specific break‑glass / automation accounts:**

           ```text theme={null}
           where request.user.name != 'break-glass-admin'
           ```

        3. **Restrict by compartment:**

           ```text theme={null}
           where target.compartment.id = 'ocid1.compartment.oc1..xxxx'
           ```

        4. **Combine:**

           ```text theme={null}
           where request.principal.type = 'user'
             and target.compartment.id = 'ocid1.compartment.oc1..xxxx'
           ```

        Update the `SAFE_WHERE_CLAUSE` (or build more complex logic) in `remediate_policy()` to match your standard.

        ***

        ## 5. Safe Rollout Pattern

        1. Run with `DRY_RUN = True` and just log all risky statements.
        2. Export findings and decide per policy what the correct `where` conditions should be.
        3. Implement a **mapping** (e.g., dict by policy name or compartment) to apply the right `where` condition.
        4. Change `DRY_RUN = False`, run in a test tenancy/compartment.
        5. Then run in production.

        ***

        If you tell me your preferred restriction model (for example: “all admin policies must be limited to `request.principal.type = 'user'` and only to two specific compartments”), I can adjust the sample remediation function to match that exactly.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "oci_identity_policy" "iam_monitoring_admin_full_access" {
          # Replace with your own values
          compartment_id = "OCID_OF_TENANCY_OR_COMPARTMENT"
          name           = "IAM_MONITORING_ADMIN_POLICY"
          description    = "IAM Monitoring admins with constrained full access"

          # This example keeps 'manage all-resources' but adds a WHERE condition,
          # satisfying the control while reducing blast radius.
          statements = [
            # Replace IAM_MONITORING_ADMINS with your IAM group name
            # Replace OCID_OF_ALLOWED_COMPARTMENT with the compartment to which you want to constrain admin actions
            "Allow group IAM_MONITORING_ADMINS to manage all-resources in tenancy where target.compartment.id = 'OCID_OF_ALLOWED_COMPARTMENT'"
          ]
        }
        ```

        This change updates the policy in place (no resource replacement, but effective permissions change for the group).

        To verify, `terraform plan` should show the existing `oci_identity_policy` with its `statements` argument changing from a `manage all-resources in tenancy` statement without a `where` clause to one that includes the `where target.compartment.id = 'OCID_OF_ALLOWED_COMPARTMENT'` condition.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
