> ## 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.

# Resourcemanager.organizations.setiampolicy

### Event Information

* **What it is:** `resourcemanager.organizations.setIamPolicy` is an Admin API call that **replaces the IAM policy on an entire GCP organization resource** (not incremental). It’s typically invoked via `gcloud organizations set-iam-policy`, REST API, or through tools that manage org-level IAM.

* **Security / GCPIAM impact:** This event means someone or something has **rewritten the org-level IAM policy**, potentially adding/removing org-wide roles and members. It can:
  * Grant or revoke powerful roles (e.g., `roles/owner`, `roles/resourcemanager.organizationAdmin`) across all projects/folders.
  * Introduce risky principals (e.g., `allUsers`, external domains), affecting least-privilege and segregation-of-duties.

* **Compliance / practical actions:**
  * Treat as **high-sensitivity**; log, alert, and review every occurrence for SOX/PCI-DSS/ISO 27001 evidence.
  * Compare **before/after IAM policies** (use Cloud Logging and version control) to detect privilege escalation or policy drift.
  * Restrict who can call this API (via `resourcemanager.organizations.setIamPolicy` permission) to a **small break-glass/admin group** and enforce approvals via change management.

### Examples

* **Organization-level privilege escalation**
  * An attacker sets an overly permissive policy (e.g., `roles/owner` or `roles/resourcemanager.organizationAdmin`) for their account or a compromised service account at the *organization* level, gaining full control over all projects and folders.
  * Violates least-privilege and separation-of-duties expectations in ISO 27001, SOC 2, and CIS GCP benchmarks.

* **Bypassing security & compliance controls**
  * `setIamPolicy` is used to remove or weaken bindings for `roles/orgPolicyPolicyAdmin`, `roles/securityAdmin`, or `roles/loggingAdmin`, preventing security teams from enforcing org policies, SCC findings, and centralized logging.
  * Can break controls required by PCI DSS and HIPAA around centralized monitoring, auditability, and configuration hardening.

* **Persistence and data exfiltration path**
  * A malicious actor adds a broad group (e.g., `allAuthenticatedUsers` or an external domain group) to roles like `roles/resourcemanager.projectCreator` or high-privilege custom roles at org level, enabling creation of shadow projects or access paths for data exfiltration.
  * Conflicts with identity governance and access control requirements in NIST 800-53 (AC-2, AC-6) and CIS GCP controls.

### Remediation

#### Using Console

* **Containment & investigation (Org-level escalation)**
  * In GCP Console, go to **IAM & Admin → IAM**, set the **Scope** selector (top bar) to your **Organization**.
  * Sort by **Role** and look for any principals with **Owner**, `roles/resourcemanager.organizationAdmin`, or other highly privileged custom roles.
  * For each suspicious principal:
    * Click the **pencil** icon → **Remove** high-privilege roles → **Save**.
    * If the account is compromised (user/service account): in **IAM & Admin → Service Accounts** or **Admin Console** (for users), disable it and rotate all related keys/secrets.
  * In **IAM & Admin → Audit Logs** and **Cloud Logging**, filter on `protoPayload.methodName="SetIamPolicy"` and `resource.type="organization"` to identify when/where the escalation occurred; preserve logs for compliance (ISO 27001 A.12, SOC 2 CC7, CIS GCP).

* **Restore and harden security/compliance controls (securityAdmin/orgPolicy/logging)**
  * In **IAM & Admin → IAM** (scope: **Organization**), verify correct bindings for:
    * `roles/orgPolicyPolicyAdmin` (or tightly scoped policy admin)
    * `roles/securityAdmin` (or SCC/security team roles)
    * `roles/loggingAdmin` / `roles/loggingConfigWriter` (for centralized logs)
  * Re-add legitimate security/compliance groups (e.g., `secops@`, `compliance@`) to these roles at **Org level**: **Grant access → Add principal → Select role → Save**; ensure no unapproved principals retain these roles.
  * In **Organization policies** (IAM & Admin → **Organization policies**), review and re-enable critical policies (e.g., domain restriction, disable service account key creation); validate logging sinks in **Logging → Log Router** still send all ADMIN\_READ / DATA\_ACCESS logs to central SIEM for PCI DSS/HIPAA auditability.

* **Remove persistence paths & enforce least privilege (projectCreator/shadow projects)**
  * In **IAM & Admin → IAM** (scope: **Organization**), search for principals such as `allUsers`, `allAuthenticatedUsers`, external domains, or broad groups on:
    * `roles/resourcemanager.projectCreator`
    * Any high-privilege **custom roles** or roles that can create projects/folders/service accounts.
  * For any broad or external principals: **Edit principal → Remove** these roles at org level → **Save**; replace with tightly scoped internal groups as needed (per NIST 800-53 AC-2/AC-6, CIS GCP).
  * In **IAM & Admin → Folders** and **Manage Resources**, list projects/folders recently created; for suspicious “shadow” projects, remove IAM bindings, disable APIs, and, if confirmed malicious, shut them down (select project → **Shut down**) after exporting required logs/evidence.

#### Using CLI

* **Immediate containment & rollback of org-level IAM escalation**
  * Identify and revoke unauthorized org-level bindings (including `roles/owner`, `roles/resourcemanager.organizationAdmin`, broad groups) and re‑apply baseline access:
    ```bash theme={null}
    ORG_ID="1234567890"

    # 1. Export current org policy
    gcloud organizations get-iam-policy $ORG_ID > org-iam-current.yaml

    # 2. (Offline) Edit org-iam-current.yaml: remove/adjust malicious bindings
    #    Ensure only approved groups/service accounts keep org-level roles
    #    e.g. roles/resourcemanager.organizationAdmin, roles/owner

    # 3. Apply corrected policy
    gcloud organizations set-iam-policy $ORG_ID org-iam-current.yaml
    ```
  * Enumerate and clean up shadow access paths (project creators, custom roles, external groups):
    ```bash theme={null}
    # List all org IAM bindings for review
    gcloud organizations get-iam-policy $ORG_ID \
      --format="table(bindings.role, bindings.members)"

    # Remove overly broad project creator or custom-role grants
    gcloud organizations remove-iam-policy-binding $ORG_ID \
      --member="group:allAuthenticatedUsers" \
      --role="roles/resourcemanager.projectCreator"
    ```

* **Restore and lock down security/compliance control roles (Security Admin, Org Policy, Logging)**
  * Re‑grant required roles only to tightly controlled security groups, and verify no weakened bindings:
    ```bash theme={null}
    SEC_GROUP="group:security-admins@example.com"
    gcloud organizations add-iam-policy-binding $ORG_ID \
      --member="$SEC_GROUP" \
      --role="roles/orgpolicy.policyAdmin"

    gcloud organizations add-iam-policy-binding $ORG_ID \
      --member="$SEC_GROUP" \
      --role="roles/security.admin"

    gcloud organizations add-iam-policy-binding $ORG_ID \
      --member="$SEC_GROUP" \
      --role="roles/logging.admin"
    ```
  * Enforce constraints to prevent future org‑level privilege escalation and bypass of security controls (aligns with ISO 27001, SOC 2, PCI DSS, HIPAA, NIST 800‑53, CIS GCP):
    ```bash theme={null}
    # Example: restrict who can create projects (blocks shadow projects)
    gcloud org-policies set-policy project_creation_policy.yaml

    # Example project_creation_policy.yaml
    # name: organizations/1234567890/policies/constraints/resourcemanager.projectCreator
    # spec:
    #   rules:
    #   - allow_all: false
    #   - values:
    #       allowedValues:
    #       - user:admin@example.com
    #       - group:project-creators@example.com
    ```

* **Detection, monitoring, and long‑term hardening**
  * Review Cloud Audit Logs for `SetIamPolicy` on the organization and security‑sensitive roles, and enable high‑severity alerts:
    ```bash theme={null}
    # Filter recent org-level SetIamPolicy calls
    gcloud logging read \
      'resource.type="organization" AND protoPayload.methodName="SetIamPolicy"' \
      --organization=$ORG_ID --limit=100 \
      --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.serviceData.policyDelta.bindingDeltas)"
    ```
  * Implement continuous controls to meet CIS GCP, NIST AC‑2/AC‑6:
    * Require approval workflows and break‑glass processes for org‑level roles (via IAM Conditions, Cloud Functions / Cloud Workflows + security ticketing).
    * Regularly export and baseline‑compare org IAM and org policies with CI/CD or compliance tooling to detect unauthorized changes.

#### Using Python

* **Identify and contain org-level IAM abuse**

  * Enumerate and review all org-level bindings, focusing on `roles/owner`, `roles/resourcemanager.organizationAdmin`, `roles/resourcemanager.projectCreator`, custom high-privilege roles, and security roles (`roles/orgPolicyPolicyAdmin`, `roles/securityAdmin`, `roles/loggingAdmin`), then immediately remove or narrow any non-approved principals and rotate credentials for compromised accounts.
  * Example Python (Cloud Resource Manager v1) to list and then clean risky bindings (ensure `ORGANIZATION_ID` and `ALLOWED_PRINCIPALS` reflect your policies and approval list):

    ```python theme={null}
    from googleapiclient import discovery
    from google.oauth2 import service_account

    ORG_ID = "123456789012"  # your organization ID
    ALLOWED_PRINCIPALS = {
        "roles/owner": {"group:cloud-admins@example.com"},
        "roles/resourcemanager.organizationAdmin": {"group:org-admins@example.com"},
        "roles/resourcemanager.projectCreator": {"group:project-creators@example.com"},
        "roles/orgPolicyPolicyAdmin": {"group:secops@example.com"},
        "roles/securityAdmin": {"group:secops@example.com"},
        "roles/loggingAdmin": {"group:secops@example.com"},
    }

    SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
    creds = service_account.Credentials.from_service_account_file(
        "service-account.json", scopes=SCOPES
    )

    crm = discovery.build("cloudresourcemanager", "v1", credentials=creds)

    def get_org_policy():
        req = crm.organizations().getIamPolicy(
            resource=f"organizations/{ORG_ID}",
            body={"options": {"requestedPolicyVersion": 3}},
        )
        return req.execute()

    def set_org_policy(policy):
        # Required for conditional bindings
        if policy.get("version", 0) < 3:
            policy["version"] = 3
        req = crm.organizations().setIamPolicy(
            resource=f"organizations/{ORG_ID}", body={"policy": policy}
        )
        return req.execute()

    def is_high_risk_member(member: str) -> bool:
        if member in ("allUsers", "allAuthenticatedUsers"):
            return True
        # Add domain-level and external checks as per your governance
        if member.endswith("@gmail.com") or member.endswith("@yahoo.com"):
            return True
        # Example: block external domain
        if member.endswith("@external-partner.com"):
            return True
        return False

    def clean_org_bindings():
        policy = get_org_policy()
        bindings = policy.get("bindings", [])
        new_bindings = []

        for b in bindings:
            role = b["role"]
            members = set(b.get("members", []))

            # Enforce allow-list for specific sensitive roles
            if role in ALLOWED_PRINCIPALS:
                allowed = ALLOWED_PRINCIPALS[role]
                # Only keep members that are in the approved list
                filtered = {m for m in members if m in allowed}
                if filtered:
                    b["members"] = sorted(filtered)
                    new_bindings.append(b)
                # else drop the binding entirely
                continue

            # For all other roles, at least strip obviously risky principals
            filtered = {m for m in members if not is_high_risk_member(m)}
            if filtered:
                b["members"] = sorted(filtered)
                new_bindings.append(b)
            # if nothing left, we drop this binding

        policy["bindings"] = new_bindings
        result = set_org_policy(policy)
        print("Updated org IAM policy etag:", result.get("etag"))

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

* **Reinstate security/compliance guardrails and monitoring**

  * Re-add or validate bindings so that only dedicated security/compliance groups hold `roles/orgPolicyPolicyAdmin`, `roles/securityAdmin`, `roles/loggingAdmin`, and `roles/accessContextManager.policyAdmin`, and ensure audit logs (Admin, Data Access, Policy Denied) are enabled org-wide; configure log sinks locked to a security project to meet PCI DSS / HIPAA centralized logging.
  * Example: Python to ensure security teams have required roles (idempotent “ensure-binding” pattern):

    ```python theme={null}
    SEC_BINDINGS = {
        "roles/orgPolicyPolicyAdmin": {"group:secops@example.com"},
        "roles/securityAdmin": {"group:secops@example.com"},
        "roles/loggingAdmin": {"group:secops@example.com"},
    }

    def ensure_security_bindings():
        policy = get_org_policy()
        bindings = policy.get("bindings", [])
        role_to_binding = {b["role"]: b for b in bindings}

        changed = False
        for role, must_have in SEC_BINDINGS.items():
            if role not in role_to_binding:
                bindings.append({"role": role, "members": sorted(must_have)})
                changed = True
            else:
                b = role_to_binding[role]
                members = set(b.get("members", []))
                if not must_have.issubset(members):
                    members.update(must_have)
                    b["members"] = sorted(members)
                    changed = True

        if changed:
            policy["bindings"] = bindings
            set_org_policy(policy)
            print("Security bindings enforced")
        else:
            print("Security bindings already compliant")

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

* **Prevent persistence / re-escalation and align with least-privilege controls**

  * Remove broad identities like `allAuthenticatedUsers`, external domains, or unapproved groups from org-level high-privilege roles and especially from `roles/resourcemanager.projectCreator`; replace them with tightly controlled groups, enable Org Policy constraints (`constraints/iam.allowedPolicyMemberDomains`, `constraints/iam.disableServiceAccountKeyCreation`, `constraints/compute.disableSerialPortAccess`), and require approvals for org-level IAM changes (change management to align with ISO 27001, SOC 2, NIST 800-53 AC-2/AC-6).
  * Example: Python snippet to specifically harden `roles/resourcemanager.projectCreator` and strip public/external members to reduce “shadow project” risk:

    ```python theme={null}
    SENSITIVE_ROLE = "roles/resourcemanager.projectCreator"

    def harden_project_creator():
        policy = get_org_policy()
        bindings = policy.get("bindings", [])
        for b in bindings:
            if b["role"] != SENSITIVE_ROLE:
                continue
            members = set(b.get("members", []))
            safe_members = {
                m for m in members
                if not is_high_risk_member(m)
                and m.startswith("group:project-creators@yourcorp.com")
            }
            if safe_members:
                b["members"] = sorted(safe_members)
            else:
                # If nothing safe remains, remove binding entirely
                bindings.remove(b)
        policy["bindings"] = bindings
        set_org_policy(policy)
        print("Hardened project creator role")

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