使用 Policy Simulator 測試角色變更

本頁說明如何使用 Policy Simulator,模擬 IAM 允許政策的變更。此外,本文也會說明如何解讀模擬結果,以及如何套用模擬的允許政策 (如果選擇這麼做)。

這項功能只會根據允許政策評估存取權。

如要瞭解如何模擬其他類型政策的變更,請參閱下列文章:

事前準備

  • 啟用 Policy Simulator 和 Resource Manager API。

    啟用 API 時所需的角色

    您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    啟用 API

  • 選用:瞭解允許政策的 Policy Simulator 運作方式

所需權限

模擬變更允許政策前,請務必確認您具備適當權限。執行模擬需要特定權限,其他權限則非必要,但有助於取得最完整的模擬結果。

如要進一步瞭解 Identity and Access Management (IAM) 角色,請參閱「瞭解角色」。

目標資源的必要權限

模擬作業的目標資源是您要模擬允許政策的資源。

如要取得執行模擬所需的權限,請要求管理員在目標資源中授予下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

這些預先定義的角色具備執行模擬所需的權限。如要查看確切的必要權限,請展開「Required permissions」(必要權限) 部分:

所需權限

如要執行模擬,必須具備下列權限:

  • cloudasset.assets.searchAllResources
  • policysimulator.replays.run
  • service.resource.getIamPolicy,其中 resource 是目標資源的資源類型,service 則是擁有該資源的 Google Cloud 服務名稱。
  • 套用模擬的政策變更: service.resource.setIamPolicy,其中 resource 是目標資源的資源類型,service 是擁有該資源的 Google Cloud 服務名稱。

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

必要主機資源權限

模擬作業的主機資源是指建立及執行模擬作業的專案、資料夾或機構。主機資源不必與目標資源有任何關聯。

設定主機資源的方式取決於您使用的平台。

控制台

主機資源是資源選取器中顯示的專案、資料夾或組織。

如要變更主機資源,請在資源選取器中選擇其他專案、資料夾或機構。

gcloud

主機資源是目前的配額專案。如要設定配額專案,請使用 gcloud auth application-default set-quota-project 指令。

REST

每次傳送要求時,您都必須手動指定主機資源。詳情請參閱本頁的「模擬政策變更」。

如要取得執行模擬所需的權限,請要求管理員授予主機資源的模擬工具管理員 (roles/policysimulator.admin) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

這個預先定義的角色具備執行模擬所需的權限。如要查看確切的必要權限,請展開「Required permissions」(必要權限) 部分:

所需權限

如要執行模擬,必須具備下列權限:

  • policysimulator.replayResults.list
  • policysimulator.replays.create
  • policysimulator.replays.get

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

如要從模擬作業取得最完整的結果,建議您具備特定 IAM 和 Google Workspace 權限。如果您沒有部分或全部權限,仍可執行模擬。不過,如果沒有這些權限就執行模擬作業,可能會導致不明存取權變更次數增加,因為您可能無法擷取會影響模擬結果的資訊。

執行模擬時,建議您具備貴機構的安全性審查員角色 (roles/iam.securityReviewer)。或者,如果您已具備安全管理員角色 (roles/iam.securityAdmin),則不需獲派任何其他角色。

這些角色會授予下列權限,協助您從模擬中取得最完整的結果:

  • 在定義自訂角色的任何相關專案、資料夾或機構上,按一下 iam.roles.getiam.roles.list。如果專案、資料夾或機構是您要模擬允許政策的資源的祖系或子系,則該專案、資料夾或機構就與模擬作業相關。
  • ,其中 resource 是可擁有允許政策的資源類型名稱,service 則是擁有該資源的Google Cloud 服務名稱。service.resource.getIamPolicy

    執行模擬時,建議您對符合下列條件的每個資源都擁有這項權限:

    • Policy Simulator 支援該資源
    • 資源有允許政策,可能會影響使用者的存取權。如果符合下列任一條件,即為擁有者:

      • 資源是您要模擬允許政策的資源後代,且會顯示在相關存取記錄中。
      • 資源是您要模擬允許政策的資源的祖系。

    舉例來說,假設您想模擬專案的允許政策。如果存取記錄包含專案中 Cloud Storage 值區的存取嘗試,您需要該值區的 storage.buckets.getIamPolicy 權限。如果專案的上層資料夾設有允許政策,您也需要該資料夾的 resourcemanager.folders.getIamPolicy 權限。

建議您在原始允許政策和建議的允許政策中,都具有擷取每個 Google 群組成員資訊的權限。

Google Workspace 超級管理員和群組管理員通常可以檢視群組成員。如果您不是超級管理員或群組管理員,請要求 Google Workspace 管理員建立自訂的 Google Workspace 管理員角色,這個角色包含 groups.read 權限 (位於「Admin API Privileges」(Admin API 權限) 下),並將該角色指派給您。如此一來,您便可以查看網域中所有群組的成員身分,並更有效地模擬允許政策的變更。

模擬政策變更

請按照下列步驟模擬允許政策的變更。

控制台

以下範例示範如何模擬專案的允許政策變更。不過,您可以模擬變更任何具有允許政策的資源。

編輯主體的權限,然後按一下「測試變更」,不要點選「儲存」

  1. 前往 Google Cloud 控制台的「IAM」(身分與存取權管理) 頁面。

    前往「IAM」頁面

  2. 編輯現有主體的權限,為允許政策建立提議的變更:

    1. 找出要編輯存取權的主體,然後按一下右側的「編輯」 按鈕。
    2. 新增角色,或撤銷/變更現有角色,即可編輯主體的存取權。
  3. 如要模擬建議的變更,請按一下「測試變更」

  4. 幾分鐘後, Google Cloud 控制台會顯示模擬結果,列出存取權變更。詳情請參閱本頁面的「瞭解 Policy Simulator 結果」。

    如果現有允許政策與模擬允許政策的存取權沒有變更, Google Cloud 控制台就不會顯示任何存取權變更。

gcloud

如要模擬允許政策的變更,請按照「讀取 - 修改 - 寫入」模式操作,但請模擬允許政策,而不是寫入政策。

  1. 執行下列指令,讀取目前的允許政策:

    gcloud resource-type get-iam-policy resource-id --format=format > filepath

    替換下列值:

    • resource-type:您要模擬允許政策的資源類型。例如:projects
    • resource-id:要模擬允許政策的資源 ID。例如:my-project
    • format:回應格式。請使用 jsonyaml 值。
    • filepath:允許政策的新輸出檔案路徑。

    舉例來說,以下指令會以 JSON 格式取得專案 my-project 的允許政策,並將其儲存至使用者的主目錄:

    gcloud projects get-iam-policy my-project --format=json > ~/policy.json
  2. 修改 get-iam-policy 指令傳回的 JSON 或 YAML 允許政策,反映您要模擬的變更。

    您可以對允許政策進行多種變更,舉例來說,您可以從角色繫結新增或移除主體,也可以從允許政策移除角色繫結。

  3. 執行下列指令,模擬允許政策的變更:

    gcloud iam simulator replay-recent-access \
        full-resource-name \
        filepath \
        --format=format

    替換下列值:

    • full-resource-name:要模擬允許政策的資源完整資源名稱。

      完整資源名稱是 URI,由服務名稱和資源路徑組成。舉例來說,如果您要模擬專案的允許政策,請使用 //cloudresourcemanager.googleapis.com/projects/project- id,其中 project-id 是要模擬允許政策的專案 ID。

      如需完整資源名稱格式清單,請參閱「完整資源名稱」。

    • filepath:包含要模擬的已修改允許政策的檔案路徑。例如:~/proposed_policy.json

    • format:回應格式。例如 jsonyaml

    幾分鐘後,這項指令會列印重播結果清單,說明套用提議的允許政策後,主體的存取權會如何變更。這些結果也會列出模擬期間發生的任何錯誤,包括因不支援的資源類型而發生的錯誤。

    如要瞭解如何解讀結果,請參閱本頁的「瞭解政策模擬器結果」。如要瞭解如何儲存模擬結果而非列印,請參閱儲存模擬結果

    以下是允許政策模擬的範例回應,其中涉及使用者 my-user@example.com。在這種情況下,如果套用建議的變更,my-user@example.com 可能會失去專案 my-projectresourcemanager.projects.listresourcemanager.projects.get 權限,且一定會失去專案 my-projectresourcemanager.projects.update 權限:

    [
      {
        "accessTuple": {
          "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
          "permission": "resourcemanager.projects.list",
          "principal": "my-user@example.com"
        },
        "diff": {
          "accessDiff": {
            "accessChange": "ACCESS_MAYBE_REVOKED",
            "baseline": {
              "accessState": "GRANTED"
            },
            "simulated": {
              "accessState": "UNKNOWN_INFO_DENIED",
              "errors": [
                {
                  "code": 7,
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                      "description": "Missing permission to retrieve IAM policies above the resource in hierarchy.",
                      "resourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                      "resourceType": "cloudresourcemanager.googleapis.com/projects"
                    }
                  ],
                  "message": "Missing permission to get relevant IAM policies."
                }
              ],
              "policies": [
                {
                  "access": "UNKNOWN_INFO_DENIED",
                  "policy": {}
                }
              ]
            }
          }
        },
        "lastSeenDate": {
          "day": 12,
          "month": 1,
          "year": 2021
        }
      },
      {
        "accessTuple": {
          "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
          "permission": "resourcemanager.projects.get",
          "principal": "my-user@example.com"
        },
        "diff": {
          "accessDiff": {
            "accessChange": "ACCESS_MAYBE_REVOKED",
            "baseline": {
              "accessState": "GRANTED"
            },
            "simulated": {
              "accessState": "UNKNOWN_INFO_DENIED",
              "errors": [
                {
                  "code": 7,
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                      "description": "Missing permission to view group membership.",
                      "resourceName": "group:everyone@example.com",
                      "resourceType": "Google group"
                    }
                  ],
                  "message": "Missing permission to view group membership."
                },
                {
                  "code": 7,
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ResourceInfo",
                      "description": "Missing permission to retrieve IAM policies above the resource in hierarchy.",
                      "resourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                      "resourceType": "cloudresourcemanager.googleapis.com/projects"
                    }
                  ],
                  "message": "Missing permission to get relevant IAM policies."
                }
              ],
              "policies": [
                {
                  "access": "UNKNOWN_INFO_DENIED",
                  "bindingExplanations": [
                    {
                      "access": "UNKNOWN_INFO_DENIED",
                      "memberships": {
                        "group:everyone@example.com": {
                          "membership": "MEMBERSHIP_UNKNOWN_INFO_DENIED"
                        }
                      },
                      "role": "roles/owner"
                    }
                  ],
                  "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
                  "policy": {
                    "bindings": [
                      {
                        "members": [
                          "group:everyone@example.com"
                        ],
                        "role": "roles/owner"
                      }
                    ],
                    "etag": "BwWgJSIInYA=",
                    "version": 3
                  }
                },
                {
                  "access": "UNKNOWN_INFO_DENIED",
                  "policy": {}
                }
              ]
            }
          }
        },
        "lastSeenDate"