> ## 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.folders.setiampolicy remediation

### Event Information

* **What it is:** `resourcemanager.folders.setIamPolicy` is a Google Cloud Resource Manager API call that sets (overwrites) the IAM policy on a **Folder** resource. It is typically triggered by commands like `gcloud resource-manager folders set-iam-policy` or via the REST API/Client libraries.

* **Security & impact:**
  * It can **add, remove, or replace** roles and member bindings (including custom roles, service accounts, external identities) on the folder.
  * Because IAM is inherited, this can **cascade to all projects and resources under that folder**, potentially granting or revoking broad access.

* **Compliance considerations (e.g., ISO 27001, SOC 2, PCI, HIPAA):**
  * Treat this event as **high‑sensitivity** and log/monitor it via Cloud Audit Logs + SIEM.
  * Require strong **change control** (approval workflow, ticket linkage) and **least privilege** (only Org/Folder Admins with business justification).
  * Periodically review folder IAM policies and compare changes against **policy-as-code baselines** (e.g., Terraform, CSPM tools) to detect unauthorized or non-compliant modifications.

### Examples

* **Overly broad folder-level access (e.g., `roles/owner` / `roles/editor` to a group)**
  * Impact: Users gain inherited control over all child projects/resources (compute, storage, BigQuery) enabling data exfiltration, service deletion, or privilege escalation.
  * Compliance: Violates least privilege in ISO 27001 / SOC 2; risks non-compliant access to regulated data (HIPAA, PCI DSS).

* **Granting external identities access at folder scope (e.g., `user:personal@gmail.com`, `domain:partner.com`)**
  * Impact: Third parties can create/modify resources or IAM at project level, potentially exposing customer data or production systems.
  * Compliance: Breaches data residency / third-party access controls (GDPR, HIPAA BAA terms, PCI DSS 7) due to unmanaged external accounts.

* **Misconfigured service account / CI pipeline role at folder level (e.g., `roles/resourcemanager.folderAdmin`)**
  * Impact: Compromised pipeline or service account can rewrite IAM across all projects in the folder, disable logging, or backdoor access.
  * Compliance: Undermines separation of duties and change control (ISO 27001 A.6/A.8, SOC 2 CC6, PCI DSS 7.2) and can invalidate audit trails.

### Remediation

#### Using Console

* **Remove overly broad folder-level access (roles/owner, roles/editor, etc.)**
  * In Console: Go to **IAM & Admin → IAM**, click **Resource type filter → Folders**, select the target folder → click **Show inherited permissions**. Identify principals (e.g., groups) with `Owner`, `Editor`, or other broad roles at folder level.
  * For each risky binding: click **Edit principal** (pencil icon) → remove `Owner` / `Editor` / other broad role → **Save**. Then re-add only required granular roles at **project** or **resource** level (e.g., `roles/storage.objectViewer`, `roles/bigquery.dataViewer`) based on job function.
  * Validate: Use **IAM → Policy Analyzer** (if available) or export IAM policies (Security → IAM Recommender / Policy Troubleshooter) to confirm that inherited broad roles are removed. Document the change for ISO 27001 / SOC 2 access review, and ensure any regulated projects (HIPAA/PCI) now only use least‑privilege roles.

* **Restrict external identities at folder scope**
  * In Console: **IAM & Admin → IAM**, filter to the folder as above. In the principals list, search for `@gmail.com`, `@yahoo.com`, or partner domains (e.g., `@partner.com`, or type `domain:partner.com` into the filter).
  * For each external identity found at folder level: click **Edit principal** → remove folder‑level roles → **Save**. Re‑grant access, if strictly needed, at the **specific project** or lower resource scope with minimal roles, ideally via **Cloud Identity / managed accounts** under your org domain and, for vendors, using **Cloud Identity federation** with conditional access.
  * Validate and document: Confirm no personal accounts or unmanaged domains retain folder‑ or org‑level access. Capture screenshots / export IAM policy for GDPR, HIPAA, PCI DSS 7 evidence (third‑party access, data residency).

* **Tighten service account / CI pipeline roles at folder level**
  * Identify high‑risk roles: In **IAM & Admin → IAM** at folder scope, filter **Principal type → Service accounts** and look for roles like `roles/resourcemanager.folderAdmin`, `roles/owner`, `roles/editor`, or other powerful IAM / org roles.
  * For each CI/service account: click **Edit principal** → remove folder‑level admin roles → **Save**. Then:
    * Move permissions to the **specific projects** the pipeline needs.
    * Replace powerful roles with custom or predefined least‑privilege roles (e.g., `roles/deploymentmanager.editor`, `roles/storage.admin` on specific buckets).
    * If a folder‑level role is truly required, use a narrowly scoped custom role without IAM‑write or logging‑disable permissions.
  * Governance: Enable and verify **Cloud Audit Logs** for Admin Activity and Data Access on the folder and child projects; ensure that pipeline changes go through **Change Management** (e.g., approvals in Cloud Build / GitHub Actions). Record this in your ISO 27001 / SOC 2 change and SoD documentation.

#### Using CLI

* **Tighten folder-level IAM to least privilege**
  * List current bindings and identify broad roles / external principals:
    * `gcloud alpha resource-manager folders get-iam-policy FOLDER_ID --format=json > folder-iam.json`
  * Remove `roles/owner`, `roles/editor`, and overly broad roles from groups and users; replace with least-privilege custom / predefined roles at folder or project scope:
    * `gcloud alpha resource-manager folders remove-iam-policy-binding FOLDER_ID --member="group:example-group@org.com" --role="roles/editor"`
    * `gcloud projects add-iam-policy-binding PROJECT_ID --member="group:example-group@org.com" --role="roles/compute.viewer"`
  * For ISO 27001 / SOC 2 / PCI DSS alignment, document role design and access reviews (e.g., quarterly) and enforce org policies to block legacy roles:
    * `gcloud org-policies set-policy org-policy-least-privilege.yaml --organization=ORG_ID`

* **Restrict external identities and third-party access at folder scope**
  * Enumerate and remove external members (personal Gmail, partner domains) at folder level; re-grant via managed groups or workload identity federation at project level only:
    * `gcloud alpha resource-manager folders get-iam-policy FOLDER_ID --flatten="bindings[].members" --filter="bindings.members:(user: OR domain:)" --format="table(bindings.role, bindings.members)"`
    * `gcloud alpha resource-manager folders remove-iam-policy-binding FOLDER_ID --member="user:personal@gmail.com" --role="roles/viewer"`
  * Enforce domain restriction + external account controls (GDPR / HIPAA / PCI DSS 7) using org policies:
    * `gcloud org-policies set-policy domain_restriction.yaml --organization=ORG_ID`
  * For partners, use dedicated projects + VPC-SC / per-project IAM, not folder-scope; ensure DPAs/BAAs cover access and log all access via Cloud Audit Logs + CMEK.

* **Constrain service accounts / CI roles and monitor IAM changes**
  * Remove high-impact roles (e.g., `roles/owner`, `roles/editor`, `roles/resourcemanager.folderAdmin`) from service accounts/CI at folder scope; assign minimal, task-specific roles at project scope:
    * `gcloud alpha resource-manager folders remove-iam-policy-binding FOLDER_ID --member="serviceAccount:ci-sa@PROJECT_ID.iam.gserviceaccount.com" --role="roles/resourcemanager.folderAdmin"`
    * `gcloud projects add-iam-policy-binding PROJECT_ID --member="serviceAccount:ci-sa@PROJECT_ID.iam.gserviceaccount.com" --role="roles/deployments.deployAgent"`
  * Disable direct key usage where possible and use Workload Identity Federation; restrict IAM write permissions and logging configuration to a small break-glass admin group to maintain audit integrity (ISO 27001 A.6/A.8, SOC 2 CC6, PCI DSS 7.2).
  * Implement continuous detection for risky folder-level grants using SCC / Cloud Asset Inventory and alert on `SetIamPolicy` / `SetOrgPolicy` events: e.g.,
    * `gcloud asset search-all-iam-policies --scope="folders/FOLDER_ID" --query="policy:(roles/owner OR roles/editor OR roles/resourcemanager.folderAdmin)" --format="table(resource, policy.bindings.role, policy.bindings.members)"`

#### Using Python

* **Tighten folder-level IAM & remove broad roles (`owner` / `editor` / broad custom roles) from groups and externals**
  * Discover and review bindings on the target folder (and optionally recursively) and generate a report of high‑risk principals and roles:
    ```python theme={null}
    from google.cloud import resourcemanager_v3

    FOLDER_NAME = "folders/1234567890"  # <-- change

    HIGH_RISK_ROLES = {
        "roles/owner",
        "roles/editor",
        "roles/resourcemanager.folderAdmin",
        "roles/resourcemanager.projectCreator",
        "roles/iam.securityAdmin",
        "roles/iam.serviceAccountAdmin",
    }

    EXTERNAL_DOMAIN_SUFFIXES = (
        "@gmail.com",
        "@yahoo.com",
        "@outlook.com",
        # add known external domains or use allow-list of corp domains
    )

    def is_external_member(member: str) -> bool:
        # basic heuristic – prefer an allow‑list of internal domains in production
        if member.startswith("user:") or member.startswith("group:"):
            email = member.split(":", 1)[1]
            return email.endswith(EXTERNAL_DOMAIN_SUFFIXES)
        if member.startswith("domain:"):
            domain = member.split(":", 1)[1]
            # treat any non‑corp domain as external
            return domain not in {"corp.example.com"}  # <-- change
        return False

    def main():
        client = resourcemanager_v3.FoldersClient()
        policy = client.get_iam_policy(request={"resource": FOLDER_NAME})
        print(f"IAM Policy for {FOLDER_NAME}")
        for b in policy.bindings:
            risky_role = b.role in HIGH_RISK_ROLES
            for m in b.members:
                external = is_external_member(m)
                if risky_role or external:
                    print(f"RISK: role={b.role}, member={m}, risky_role={risky_role}, external={external}")

    if __name__ == "__main__":
        main()
    ```
  * Remediate by: (1) designing least‑privilege custom roles at project level, (2) migrating groups to scoped roles (`roles/viewer`, per‑service roles like `roles/bigquery.dataViewer`), (3) then editing the folder IAM policy to remove the high‑risk bindings:
    ```python theme={null}
    from google.cloud import resourcemanager_v3

    FOLDER_NAME = "folders/1234567890"  # <-- change
    PRINCIPALS_TO_STRIP = {
        "group:all-devs@example.com",     # <-- change
        "group:ci-pipeline@example.com",  # <-- change
    }
    ROLES_TO_STRIP = {
        "roles/owner",
        "roles/editor",
        "roles/resourcemanager.folderAdmin",
    }

    def main():
        client = resourcemanager_v3.FoldersClient()
        policy = client.get_iam_policy(request={"resource": FOLDER_NAME})

        new_bindings = []
        for b in policy.bindings:
            if b.role in ROLES_TO_STRIP:
                remaining_members = [
                    m for m in b.members
                    if m not in PRINCIPALS_TO_STRIP
                ]
                if remaining_members:
                    b.members[:] = remaining_members
                    new_bindings.append(b)
                else:
                    # drop entire binding
                    continue
            else:
                new_bindings.append(b)

        policy.bindings[:] = new_bindings
        # use etag for optimistic locking to satisfy change‑control processes
        updated = client.set_iam_policy(
            request={"resource": FOLDER_NAME, "policy": policy}
        )
        print(f"Updated bindings for {FOLDER_NAME}:")
        for b in updated.bindings:
            print(b.role, b.members)

    if __name__ == "__main__":
        main()
    ```
  * Map to compliance: document the role redesign and approval (change tickets), and keep the script output as evidence for ISO 27001 / SOC 2 / PCI DSS least‑privilege reviews.

* **Remove / restrict external identities at folder scope & enforce org‑level controls**
  * Enumerate and flag all external members and external `domain:` bindings at folder level (to satisfy GDPR / HIPAA / PCI DSS 7 third‑party access controls):
    ```python theme={null}
    from google.cloud import resourcemanager_v3

    FOLDER_NAME = "folders/1234567890"  # <-- change
    INTERNAL_DOMAINS = {"corp.example.com"}  # <-- change

    def is_external(member: str) -> bool:
        if member.startswith(("user:", "group:")):
            email = member.split(":", 1)[1]
            domain = email.split("@")[-1]
            return domain not in INTERNAL_DOMAINS
        if member.startswith("domain:"):
            domain = member.split(":", 1)[1]
            return domain not in INTERNAL_DOMAINS
        return False

    def main():
        client = resourcemanager_v3.FoldersClient()
        policy = client.get_iam_policy(request={"resource": FOLDER_NAME})
        for b in policy.bindings:
            for m in b.members:
                if is_external(m):
                    print(f"EXTERNAL at folder: role={b.role}, member={m}")

    if __name__ == "__main__":
        main()
    ```
  * After confirming business need and BAA/DPA/PCI agreements, either: (1) move access down to specific projects/resources, (2) replace personal accounts with managed identities in a dedicated group, or (3) remove the binding entirely via `set_iam_policy` (similar pattern as above, filtering `is_external(member)`).
  * At the org level, configure:
    * `constraints/iam.allowedPolicyMemberDomains` to restrict which domains can appear in IAM policies.
    * `constraints/iam.disableServiceAccountKeyCreation` and workload identity for partners.\
      Use policy export as audit evidence that external access is controlled.

* **Constrain service accounts / CI roles at folder scope & implement SoD and logging guardrails**
  * Inventory service accounts and automated principals bound at folder level with elevated roles (e.g., `roles/resourcemanager.folderAdmin`, `roles/iam.securityAdmin`), then downgrade to least‑privilege project‑level roles:
    ```python theme={null}
    from google.cloud import resourcemanager_v3

    FOLDER_NAME = "folders/1234567890"
    ELEVATED_ROLES = {
        "roles/resourcemanager.folderAdmin",
        "roles/iam.securityAdmin",
        "roles/iam.serviceAccountAdmin",
        "roles/owner",
    }

    def main():
        client = resourcemanager_v3.FoldersClient()
        policy = client.get_iam_policy(request={"resource": FOLDER_NAME})
        for b in policy.bindings:
            if b.role in ELEVATED_ROLES:
                for m in b.members:
                    if m.startswith("serviceAccount:"):
                        print(f"ELEVATED SA at folder: role={b.role}, member={m}")

    if __name__ == "__main__":
        main()
    ```
  * For each CI/service account:
    * Move permissions to per‑project custom roles aligned with pipeline stages (build/test/deploy), and use per‑env SAs (dev/stage/prod) to enforce separation of duties.
    * Remove folder‑level admin roles and replace with narrowly scoped permissions (e.g., `roles/deploymentmanager.editor`, `roles/clouddeploy.releaseManager`) only where needed.
  * Ensure compliance and auditability:
    * Require approvals (e.g., via Cloud Build/Cloud Deploy gates) for IAM‑affecting changes.
    * Enable Cloud Audit Logs for Admin Activity and Data Access on the org/folder and monitor for `SetIamPolicy` / `SetOrganizationPolicy` by CI/service accounts, feeding into SIEM with alerts for ISO 27001 A.6/A.8, SOC 2 CC6, PCI DSS 7.2 evidence.
