本頁說明如何使用 Policy Simulator 模擬 IAM 許可政策的變更。並說明如何解讀模擬結果,以及如何在需要時套用模擬允許政策。
這項功能只會根據允許政策評估存取權。
如要瞭解如何模擬其他類型政策的變更,請參閱以下文章:
事前準備
-
Enable the Policy Simulator and Resource Manager APIs.
- 選用:瞭解允許政策的 Policy Simulator 運作方式。
所需權限
模擬允許政策變更前,請確認您具備適當的權限。您必須具備特定權限才能執行模擬作業,其他權限則非必要,但有助於您從模擬作業中取得最完整的結果。
如要進一步瞭解 Identity and Access Management (IAM) 角色,請參閱「瞭解角色」一文。
必要的目標資源權限
模擬的目標資源,就是您要模擬允許政策的資源。
如要取得執行模擬作業所需的權限,請要求管理員在目標資源上授予下列 IAM 角色:
-
Cloud Asset Viewer (
roles/cloudasset.viewer
) -
模擬器管理員 (
roles/policysimulator.admin
) -
安全性審查員 (
roles/iam.securityReviewer
)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。
這些預先定義的角色包含執行模擬作業所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:
所需權限
如要執行模擬作業,您必須具備下列權限:
-
cloudasset.assets.searchAllResources
-
policysimulator.replays.run
-
service.resource.getIamPolicy
,其中resource
是目標資源的資源類型,service
是擁有該資源的 Google Cloud 服務名稱。
必要的代管資源權限
模擬作業的主機資源是指建立及執行模擬作業的專案、資料夾或機構。主機資源不必與目標資源有任何關聯。
設定主機資源的方式會因您使用的平台而異。
主控台
主機資源是指資源選取器中顯示的專案、資料夾或機構。
如要變更主機資源,請在資源選取器中選擇其他專案、資料夾或機構。
gcloud
主機資源是目前的配額專案。如要設定配額專案,請使用 gcloud auth application-default set-quota-project
指令。
REST
您每次傳送要求時,都必須手動指定主機資源。詳情請參閱本頁的「模擬政策變更」一節。
如要取得執行模擬作業所需的權限,請要求管理員為您授予主機資源的 Simulator Admin (roles/policysimulator.admin
) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。
這個預先定義的角色包含執行模擬作業所需的權限。如要查看確切的必要權限,請展開「必要權限」部分:
所需權限
如要執行模擬,您必須具備下列權限:
-
policysimulator.replayResults.list
-
policysimulator.replays.create
-
policysimulator.replays.get
建議的權限
為從模擬中取得最完整的結果,建議您取得特定 IAM 和 Google Workspace 權限。即使您沒有部分或全部權限,仍可執行模擬。不過,如果您在沒有這些權限的情況下執行模擬作業,可能會導致不明的存取權變更次數增加,因為您可能無法擷取可能影響模擬結果的資訊。
建議的 IAM 權限
建議您在執行模擬時,為貴機構設定安全性審查員角色 (roles/iam.securityReviewer
)。或者,如果您已具備安全管理員角色 (roles/iam.securityAdmin
),則不需要再授予任何其他角色。
這些角色會提供下列權限,協助您從模擬資料中取得最完整的結果:
- 在定義自訂角色的任何相關專案、資料夾或機構上使用
iam.roles.get
和iam.roles.list
。如果專案、資料夾或機構是您要模擬允許政策的資源的祖系或子系,則該專案、資料夾或機構就與該政策相關。 service.resource.getIamPolicy
,其中resource
是可設有許可政策的資源類型名稱,而service
是擁有該資源的Google Cloud 服務名稱。執行模擬時,建議您為符合下列條件的每個資源設定此權限:
- Policy Simulator 支援這項資源。
資源設有允許政策,可能會影響使用者的存取權。只要符合下列任一條件,就算符合這項條件:
- 這項資源是您要模擬允許政策的資源的子項,並會顯示在相關存取記錄中。
- 該資源是您要模擬允許政策的資源的祖系。
舉例來說,假設您想模擬專案的允許政策。如果存取記錄包含專案中 Cloud Storage 值區的存取嘗試,您就需要該值區的
storage.buckets.getIamPolicy
權限。如果專案含有設有許可政策的上層資料夾,您也需要該資料夾的resourcemanager.folders.getIamPolicy
權限。
建議的 Google Workspace 權限
建議您在原始允許政策和建議的允許政策中,針對每個 Google 群組取得擷取群組成員資訊的權限。
Google Workspace 超級管理員和群組管理員通常可以檢視群組成員。如果您不是超級管理員或群組管理員,請要求 Google Workspace 管理員建立自訂 Google Workspace 管理員角色,這個角色包含 groups.read
權限 (位於「Admin API 權限」下),並授予您該角色。這樣一來,您就能查看網域中所有群組的成員資格,並更有效地模擬允許政策的變更。
模擬政策變更
請按照下列步驟模擬允許政策的變更。
控制台
以下範例說明如何模擬對專案的許可政策進行變更。不過,您可以針對任何設有允許政策的資源模擬允許政策變更。
編輯實體的權限,然後點選「測試變更」,而非「儲存」:
gcloud
如要模擬允許政策的變更,請遵循「讀取-修改-寫入」模式,但模擬允許政策,而非寫入。
執行下列指令,讀取目前的許可政策:
gcloud resource-type get-iam-policy resource-id --format=format > filepath
替換下列值:
resource-type
:您要模擬允許政策的資源類型。例如:projects
。resource-id
:您要模擬允許政策的資源 ID。例如:my-project
。format
:回應格式。使用json
或yaml
值。filepath
:允許政策的新輸出檔案路徑。
例如,以下指令會以 JSON 格式取得專案
my-project
的許可政策,並將其儲存到使用者的主目錄中:gcloud projects get-iam-policy my-project --format=json > ~/policy.json
修改
get-iam-policy
指令傳回的 JSON 或 YAML 允許政策,以反映您要模擬的變更。您可以對允許政策進行多種變更,舉例來說,您可以從角色繫結中新增或移除主體,或是從允許政策中移除角色繫結。
執行下列指令,模擬允許政策的變更:
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
:回應格式。例如json
或yaml
。
幾分鐘後,指令會列印重播結果清單,說明套用提議的允許政策後,主體的存取權會如何變更。這些結果也會列出模擬期間發生的任何錯誤,包括因不支援的資源類型而發生的任何錯誤。
如要瞭解如何解讀結果,請參閱本頁的「解讀政策模擬器結果」。如要瞭解如何儲存模擬結果,而不是列印結果,請參閱「儲存模擬結果」。
以下是涉及使用者
my-user@example.com
的允許政策模擬作業的回應範例。在這種情況下,如果套用建議的變更,my-user@example.com
可能就不再擁有專案my-project
的resourcemanager.projects.list
和resourcemanager.projects.get
權限,而且肯定也不再擁有專案my-project
的resourcemanager.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": { "day": 10, "month": 1, "year": 2021 } }, { "accessTuple": { "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project", "permission": "resourcemanager.projects.update", "principal": "my-user@example.com" }, "diff": { "accessDiff": { "accessChange": "ACCESS_REVOKED", "baseline": { "accessState": "GRANTED" }, "simulated": { "accessState": "NOT_GRANTED" } } }, "lastSeenDate": { "day": 15, "month": 1, "year": 2021 } }, { "accessTuple": {}, "error": { "code": 12, "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.create" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.setIamPolicy" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.delete" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.update" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "pubsub.topics.publish" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.list" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.getIamPolicy" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.get" }, "reason": "UNSUPPORTED_RESOURCE" } ], "message": "Simulator does not yet support all resource types for 8 removed permissions." } } ]
如果現有允許政策與模擬允許政策之間的存取權沒有變更,指令會列印
No access changes found in the replay
。
REST
如要模擬允許政策的變更,請遵循「讀取-修改-寫入」模式,但不要寫入允許政策,而是建立並執行模擬作業。
閱讀資源的允許政策。
如要取得專案的允許政策,請使用 Resource Manager API 的
projects.getIamPolicy
方法。使用任何要求資料之前,請先替換以下項目:
PROJECT_ID
:您的 Google Cloud 專案 ID。專案 ID 為英數字元字串,例如my-project
。POLICY_VERSION
:要傳回的政策版本。要求應指定最新的政策版本,也就是政策版本 3。詳情請參閱「取得政策時指定政策版本」。
HTTP 方法和網址:
POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:getIamPolicy
JSON 要求主體:
{ "options": { "requestedPolicyVersion": POLICY_VERSION } }
如要傳送要求,請展開以下其中一個選項:
您應該會收到如下的 JSON 回應:
{ "version": 1, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/owner", "members": [ "user:project-owner@example.com" ] }, { "role": "roles/iam.securityReviewer", "members": [ "user:fatima@example.com" ] } ] }
修改傳回的允許政策,反映您要模擬的變更。
您可以對允許政策進行多種變更,舉例來說,您可以從角色繫結中新增或移除主體,或是從允許政策中移除角色繫結。
使用修改後的允許政策建立模擬或重播。
如要為專案、資料夾或機構建立重播,請使用 Policy Simulator API 的
replays.create
方法。使用任何要求資料之前,請先替換以下項目:
-
HOST_RESOURCE_TYPE
:要代管 Replay 的資源類型。這個值必須是projects
、folders
或organizations
。 HOST_RESOURCE_ID
:主機資源的 ID,例如my-project
。-
TARGET_FULL_RESOURCE_NAME
:您要模擬政策的資源完整資源名稱。這項資源可以是任何接受 IAM 政策的資源,且不必與主機資源有任何關聯。完整資源名稱是 URI,由服務名稱和資源路徑組成。舉例來說,如果您要模擬專案的政策,請使用
//cloudresourcemanager.googleapis.com/projects/PROJECT_ID
,其中PROJECT_ID
是您要模擬政策的專案 ID。如需資源名稱格式的完整清單,請參閱「完整資源名稱」。
-
POLICY
:您要模擬的政策。如需政策範例,請參閱 政策參考資料。如要模擬多個政策,請在要求主體中加入多個
"OBJECT_FULL_RESOURCE_NAME" : POLICY
組合。 PROJECT_ID
:您的 Google Cloud 專案 ID。專案 ID 為英數字元字串,例如my-project
。
HTTP 方法和網址:
POST https://policysimulator.googleapis.com/v1/HOST_RESOURCE_TYPE/HOST_RESOURCE_ID/locations/global/replays
JSON 要求主體:
{ "config": { "policyOverlay": { "TARGET_FULL_RESOURCE_NAME" : POLICY } } }
如要傳送要求,請展開以下其中一個選項:
回應會包含代表重播作業的名稱:
{ "name": "operations/6de23e63-f61a-4b8c-b502-34d717d2d7f8", "metadata": { "type_url": "type.googleapis.com/google.cloud.policysimulator.v1.ReplayOperationMetadata" } }
-
輪詢
operations.get
方法,直到重播作業完成為止。如要輪詢作業,建議您重複叫用
operations.get
方法,直到回應中包含"done": true
欄位和name
欄位 (含有已完成的 Replay 名稱) 為止。使用部分指數輪詢,在每次要求之間加入延遲時間。如要取得重播的狀態,請使用 Policy Simulator API 的
operations.get
方法。使用任何要求資料之前,請先替換以下項目:
OPERATION_NAME
:重播作業的名稱,包括operations
前置字串。從replays.create
回應的name
欄位複製這個值。例如:operations/6de23e63-f61a-4b8c-b502-34d717d2d7f8
PROJECT_ID
:您的 Google Cloud 專案 ID。專案 ID 為英數字元字串,例如my-project
。
HTTP 方法和網址:
GET https://policysimulator.googleapis.com/v1/OPERATION_NAME
如要傳送要求,請展開以下其中一個選項:
進行中的作業會傳回類似以下的回應:
{ "name": "operations/42083b6b-3788-41b9-ae39-e97d7615a22d", "metadata": { "@type": "type.googleapis.com/google.cloud.policysimulator.v1.ReplayOperationMetadata", "startTime": "2021-01-15T05:34:14.732Z" } }
已完成的作業會傳回類似以下的回應:
{ "name": "operations/89ab4892-9605-4c84-aedb-4fce4fc5195b", "metadata": { "@type": "type.googleapis.com/google.cloud.policysimulator.v1.ReplayOperationMetadata", "startTime": "2021-01-15T05:40:15.922Z" }, "done": true, "response": { "@type": "type.googleapis.com/google.cloud.policysimulator.v1.Replay", "replay": { "name": "projects/my-project/locations/global/replays/89ab4892-9605-4c84-aedb-4fce4fc5195b", "state": SUCCEEDED, "config": {}, "resultsSummary": { "logCount": 1319, "unchangedCount": 1169, "differenceCount": 149, "errorCount": 1, "oldestDate": { "year": 2020, "month": 10, "day": 15 }, "newestDate": { "year": 2021, "month": 1, "day": 12 } } } } }
取得重播結果。
如要取得重播結果,請使用 Policy Simulator API 的
replays.results.list
方法。使用任何要求資料之前,請先替換以下項目:
-
REPLAY_NAME
:您要擷取結果的回放項目名稱。請從operations.get
回應的response.replay.name
欄位複製這個值。請加入任何資源類型和位置前置字串。例如:"projects/my-project/locations/global/replays/89ab4892-9605-4c84-aedb-4fce4fc5195b"
-
PAGE_SIZE
:選用。此要求傳回的結果數量上限。如果未指定,伺服器會決定要傳回的結果數量。如果結果數量超過頁面大小,回應就會包含分頁符記,可用來擷取下一頁的結果。 PAGE_TOKEN
:選用。這個方法在先前回應中傳回的分頁符記。如果指定,結果清單會從上一個要求結束處開始。PROJECT_ID
:您的 Google Cloud 專案 ID。專案 ID 為英數字元字串,例如my-project
。
HTTP 方法和網址:
GET https://policysimulator.googleapis.com/v1/REPLAY_NAME/results?pageSize=page-size&pageToken=PAGE_TOKEN
如要傳送要求,請展開以下其中一個選項:
回應包含結果清單,說明套用提議的政策後,主體的存取權會如何變更。這些結果也會列出模擬期間發生的任何錯誤,特別是因不支援的資源類型而發生的任何錯誤
如要瞭解如何解讀結果,請參閱本頁的「解讀政策模擬器結果」。
以下是涉及使用者
my-user@example.com
的政策模擬作業的回應範例。在這種情況下,如果套用建議的變更,my-user@example.com
可能就不會再擁有專案my-project
的resourcemanager.projects.list
和resourcemanager.projects.get
權限,而且肯定不會再擁有專案my-project
的resourcemanager.projects.update
權限:{ "replayResults": [ { "accessTuple": { "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project", "permission": "resourcemanager.projects.list", "principal": "my-user@example.com" }, "lastSeenDate": { "day": 27, "month": 3, "year": 2020 }, "diff": { "accessDiff": { "accessChange": "ACCESS_MAYBE_REVOKED", "baseline": { "accessState": "GRANTED" }, "simulated": { "accessState": "UNKNOWN_INFO_DENIED", "errors": [ { "code": 7, "message": "Missing permission to get relevant IAM policies.", "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" } ] } ], "policies": [ { "access": "UNKNOWN_INFO_DENIED", "policy": {} } ] } } } }, { "accessTuple": { "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project", "permission": "resourcemanager.projects.get", "principal": "my-user@example.com" }, "lastSeenDate": { "day": 27, "month": 3, "year": 2020 }, "diff": { "accessDiff": { "accessChange": "ACCESS_MAYBE_REVOKED", "baseline": { "accessState": "GRANTED" }, "simulated": { "accessState": "UNKNOWN_INFO_DENIED", "errors": [ { "code": 7, "message": "Missing permission to view group membership.", "details": [ { "@type": "type.googleapis.com/google.rpc.ResourceInfo", "description": "Missing permission to view group membership.", "resourceName": "group:everyone@example.com", "resourceType": "Google group" } ] }, { "code": 7, "message": "Missing permission to get relevant IAM policies.", "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" } ] } ], "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": {} } ] } } } }, { "accessTuple": { "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project", "permission": "resourcemanager.projects.update", "principal": "my-user@example.com" }, "lastSeenDate": { "day": 27, "month": 3, "year": 2020 }, "diff": { "accessDiff": { "accessChange": "ACCESS_REVOKED", "baseline": { "accessState": "GRANTED" }, "simulated": { "accessState": "NOT_GRANTED" } } } }, { "accessTuple": {}, "error": { "code": 12, "message": "Simulator does not yet support all resource types for 8 removed permissions.", "details": [ { "@type": "type.googleapis.com/google.rpc.Status", "code": 12, "message": "Simulator does not yet support all resource types for 8 removed permissions.", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.create" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.setIamPolicy" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.delete" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.update" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "pubsub.topics.publish" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.list" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.getIamPolicy" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.get" }, "reason": "UNSUPPORTED_RESOURCE" } ] } ] } } ], "nextPageToken": "AWukk3zjv80La+chWx6WNt7X8czGPLtP792gRpkNVEV/URZ/VdWzxmuJKr" }
如果現有允許政策與模擬允許政策之間的存取權限沒有變更,要求會傳回空白清單 (
{}
)。-
瞭解 Policy Simulator 結果
Policy Simulator 會將允許政策的變更提案影響列為存取權變更清單。每個存取權變更都代表過去 90 天內的存取嘗試,在提議的允許政策和目前的允許政策下,會有不同的結果。
政策模擬工具也會列出模擬期間發生的所有錯誤,協助您找出模擬中可能出現的差距。
這些變更和錯誤的呈現方式取決於您使用的平台。
控制台
「政策模擬工具」結果頁面會在多個不同部分顯示模擬結果:
政策變更:這個部分會列出您要變更許可政策的資源、要移除的角色,以及要新增的角色。
這個部分還包含「查看政策差異」按鈕。按一下這個按鈕,即可查看資源的允許政策在建議變更前後的樣貌。
權限變更:這個部分包含移除和新增的權限計數,說明如果您套用建議的變更,主體的權限會如何變更。系統比較了主體在現有與預期角色之間的權限差異,接著產生出這些權限數量,但不會考量繼承的角色。
這個部分也包含「查看權限差異」按鈕。按一下這個按鈕,即可並排比較主體現有角色和建議角色的權限。
過去 90 天內的存取權變更:這個部分會顯示過去 90 天內哪些存取嘗試在提議的許可政策和目前的許可政策下,會產生不同的結果。本節包含存取權變更摘要,以及更詳細的結果表格。
存取權變更摘要會列出各類型存取權變更的數量、錯誤和不明結果的數量,以及在建議的允許政策和目前允許政策下,存取嘗試次數相同的數量。摘要也會顯示無法模擬的權限數量。詳情請參閱本頁的「錯誤」一節。
這個部分也包含存取權變更表格。這份表格列出過去 90 天內,在建議的許可政策和目前許可政策下,存取權限有所不同的每一次存取嘗試。每個項目都包含主體嘗試存取的資源、要求日期、提出要求的主體、要求中的權限,以及建議允許政策下的存取狀態,並與目前允許政策下的存取狀態進行比較。
存取權變更類型有幾種:
如要查看存取權變更的其他詳細資料,請按一下存取權變更。系統會開啟「存取權限變更詳細資料」面板,顯示存取權限變更的其他資訊,包括主體的現有存取權、主體建議的存取權,以及存取權限變更結果的其他詳細資料。
gcloud
使用 replay-recent-access
指令時,gcloud CLI 的回應會包含 replayResults
清單。
每個重播結果都會說明一次存取嘗試,如果在嘗試時採用所提的允許政策,結果就會有所不同。舉例來說,下列重播結果顯示 my-user@example.com
曾使用 resourcemanager.projects.update
權限在專案 my-project
中執行動作。不過,如果已實施建議的許可政策,他們就會遭拒。
{ "accessTuple": { "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project", "permission": "resourcemanager.projects.update", "principal": "my-user@example.com" }, "lastSeenDate": { "day": 15, "month": 1, "year": 2021 }, "diff": { "accessDiff": { "baseline": { "accessState": "GRANTED" }, "simulated": { "accessState": "NOT_GRANTED" }, "accessChange": "ACCESS_REVOKED" } } }
每個重播結果都包含下列欄位:
accessTuple
:結果相關的存取嘗試。這個欄位包含存取嘗試中涉及的資源、權限和主體。lastSeenDate
:上次嘗試存取的日期。diff.accessDiff
或error
:如果存取嘗試的回放作業成功,結果會包含diff.accessDiff
欄位,用於回報目前允許政策和建議允許政策下,存取嘗試結果的差異。如果重播嘗試未成功,重播結果就會包含error
欄位,其中包含錯誤的說明。如要進一步瞭解模擬錯誤,請參閱本頁的「錯誤」一節。
每個存取差異都包含下列元件:
baseline
:使用目前允許政策時的存取結果。這會以下列任一值回報:GRANTED
、NOT_GRANTED
、UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
。如果結果為UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
,回應也會列出與不明資訊相關的任何錯誤,以及與該錯誤相關的允許政策。如要進一步瞭解UNKNOWN
值,請參閱本頁面的「不明結果」一節。simulated
:使用建議的允許政策時的存取結果。這會以下列任一值回報:GRANTED
、NOT_GRANTED
、UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
。如果結果為UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
,回應也會列出與不明資訊相關的任何錯誤,以及與該錯誤相關的允許政策。如要進一步瞭解UNKNOWN
值,請參閱本頁面的「不明結果」一節。accessChange
:基準存取狀態和模擬存取狀態之間的變化。如需可能的值清單,請參閱下表:
REST
呼叫 replays.results.list
方法時,回應會包含 replayResults
清單。
每個重播結果都會說明一次存取嘗試,如果在嘗試時採用所提的允許政策,結果就會有所不同。舉例來說,下列重播結果顯示 my-user@example.com
曾使用 resourcemanager.projects.update
權限在專案 my-project
中執行動作。不過,如果已實施建議的許可政策,他們就會遭拒。
{ "accessTuple": { "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project", "permission": "resourcemanager.projects.update", "principal": "my-user@example.com" }, "lastSeenDate": { "day": 15, "month": 1, "year": 2021 }, "diff": { "accessDiff": { "baseline": { "accessState": "GRANTED" }, "simulated": { "accessState": "NOT_GRANTED" }, "accessChange": "ACCESS_REVOKED" } } }
每個重播結果都包含下列欄位:
accessTuple
:結果相關的存取嘗試。這個欄位包含存取嘗試中涉及的資源、權限和主體。lastSeenDate
:上次嘗試存取的日期。diff.accessDiff
或error
:如果存取嘗試的回放作業成功,結果會包含diff.accessDiff
欄位,用於回報目前允許政策和建議允許政策下,存取嘗試結果的差異。如果重播嘗試未成功,重播結果就會包含error
欄位,其中包含錯誤的說明。如要進一步瞭解模擬錯誤,請參閱本頁的「錯誤」一節。
每個存取差異都包含下列元件:
baseline
:使用目前允許政策時的存取結果。這會以下列任一值回報:GRANTED
、NOT_GRANTED
、UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
。如果結果為UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
,回應也會列出與不明資訊相關的任何錯誤,以及與該錯誤相關的允許政策。如要進一步瞭解UNKNOWN
值,請參閱本頁面的「不明結果」一節。simulated
:使用建議的允許政策時的存取結果。這會以下列任一值回報:GRANTED
、NOT_GRANTED
、UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
。如果結果為UNKNOWN_CONDITIONAL
或UNKNOWN_INFO_DENIED
,回應也會列出與不明資訊相關的任何錯誤,以及與該錯誤相關的允許政策。如要進一步瞭解UNKNOWN
值,請參閱本頁面的「不明結果」一節。accessChange
:基準存取狀態和模擬存取狀態之間的變化。如需可能的值清單,請參閱下表:
不明的結果
如果存取結果為「不明」,表示 Policy Simulator 沒有足夠的資訊來完整評估存取權要求。
控制台
如果存取結果不明,存取權變更詳細資料面板會回報不明的原因,以及無法存取或評估的特定角色、允許政策、群組成員資格和條件。
以下是可能導致結果不明的幾個原因:
- 角色資訊遭拒:執行模擬的使用者沒有權限查看一或多個模擬角色的角色詳細資料。
- 無法存取政策:執行模擬的使用者主體沒有權限,無法取得模擬中涉及的一或多項資源的允許政策。
- 成員資訊遭拒:執行模擬的管理員沒有權限查看所提議許可政策中包含的一或多個群組的成員。
- 不支援的條件:在測試的許可政策中,有條件式角色繫結。政策模擬工具不支援條件,因此無法評估繫結。
gcloud
在 gcloud CLI 中,模擬結果會在存取差異中回報結果不明的原因。
存取結果不明的原因可能是下列其中一項:
UNKNOWN_INFO_DENIED
:使用者沒有權限存取評估存取狀態所需的資訊。導致這種情況的可能原因如下:- 使用者沒有權限擷取要模擬的允許政策,或是沒有權限擷取存取記錄檔中資源的允許政策。
- 使用者沒有查看群組成員資格的權限。
- 使用者無法擷取必要的角色資訊。
如要瞭解缺少哪些資訊,請查看所回報存取狀態後面的錯誤資訊。
UNKNOWN_CONDITIONAL
:在測試的許可政策中,有條件式角色繫結。政策模擬工具不支援條件,因此無法評估繫結。
如果結果不明,允許政策的欄位 (baseline
或 simulated
) 會包含 errors
欄位,說明資訊不明的原因,以及 policies
欄位,列出與錯誤相關的允許政策。如要進一步瞭解錯誤,請參閱本頁的「錯誤」一節。
REST
在 REST API 中,模擬結果會在存取差異中回報結果不明的原因。
存取結果不明的原因可能是下列其中一項:
UNKNOWN_INFO_DENIED
:使用者沒有權限存取評估存取狀態所需的資訊。導致這種情況的可能原因如下:- 使用者沒有權限擷取要模擬的允許政策,或是沒有權限擷取存取記錄檔中資源的允許政策。
- 使用者沒有查看群組成員資格的權限。
- 使用者無法擷取必要的角色資訊。
如要瞭解缺少哪些資訊,請查看所回報存取狀態後面的錯誤資訊。
UNKNOWN_CONDITIONAL
:在測試的許可政策中,有條件式角色繫結。政策模擬工具不支援條件,因此無法評估繫結。
如果結果不明,允許政策的欄位 (baseline
或 simulated
) 會包含 errors
欄位,說明資訊不明的原因,以及 policies
欄位,列出與錯誤相關的允許政策。如要進一步瞭解錯誤,請參閱本頁的「錯誤」一節。
錯誤
政策模擬工具也會回報模擬期間發生的任何錯誤。請務必檢查這些錯誤,瞭解模擬中可能存在的差距。
控制台
政策模擬器可能會回報幾種錯誤:
操作錯誤:無法執行模擬作業。政策模擬工具會在結果頁面頂端回報操作錯誤。
如果錯誤訊息指出,由於專案或機構中的記錄檔過多,因此無法執行模擬作業,您就無法在資源上執行模擬作業。
如果您因其他原因收到此錯誤訊息,請嘗試再次執行模擬作業。如果您仍無法執行模擬,請來信至 policy-simulator-feedback@google.com。
重播錯誤:重播單一存取嘗試失敗,因此 Policy Simulator 無法判斷在提議的允許政策下,存取嘗試的結果是否會變更。
Google Cloud 控制台會在「過去 90 天內的存取權變更」表格中列出重播錯誤。每個錯誤的「存取變更詳細資料」面板都會顯示錯誤訊息,協助您瞭解問題,以及發生錯誤時模擬的資源和權限。
不支援的資源類型錯誤:建議的允許政策會影響與不支援的資源類型相關聯的權限,而 Policy Simulator 無法模擬這類錯誤。
Policy Simulator 會在模擬結果中列出這些權限,讓您瞭解無法模擬哪些權限。
gcloud
在 gcloud CLI 的模擬結果中,錯誤可能會出現在兩個位置:
replayResult.error
欄位:如果重播嘗試失敗,政策模擬工具會在replayResult.error
欄位中回報錯誤。如果重播結果包含這個欄位,就不會包含diff
欄位。replayResult.diff.accessDiff.policy-type.errors
欄位,其中 policy-type 為baseline
或simulated
。如果重播嘗試成功,但結果為UNKNOWN_INFO_DENIED
或UNKNOWN_CONDITIONAL
,Policy Simulator 會在這個欄位中回報結果不明的原因。
Policy Simulator 會產生下列類型的錯誤:
錯誤 | 錯誤代碼 | 詳細資料 |
---|---|---|
GENERIC_INTERNAL_ERROR |
13 | 模擬失敗,因為發生內部錯誤。如要解決這個問題,請嘗試再次執行模擬。如果模擬結果仍失敗,請來信至 policy-simulator-feedback@google.com。 |
INVALID_ACCESS_TUPLE |
3 | 政策模擬工具無法重播存取嘗試,因為該嘗試含有無效的權限、資源名稱或主體。 |
OUT_OF_RANGE_GROUP_TOO_LARGE |
11 | 群組內含太多子群組,因此政策模擬工具無法評估群組中的管理員成員資格。這個錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
PERMISSION_DENIED_ON_GROUP_MEMBERSHIP |
7 | 由於呼叫端沒有查看群組成員的權限,因此政策模擬工具無法評估使用者的存取權。這個錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
PERMISSION_DENIED_ON_IAM_POLICY |
7 | 由於呼叫端沒有擷取允許政策的權限,因此政策模擬工具無法評估使用者的存取權。這類錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
PERMISSION_DENIED_ON_IAM_ROLE |
7 | 由於呼叫端沒有權限擷取 IAM 角色中的權限,因此政策模擬工具無法評估使用者的存取權。這類錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
PERMISSION_DENIED_ON_PARENT_IAM_POLICY |
7 | 由於呼叫端沒有權限擷取祖系資源的允許政策,因此政策模擬工具無法評估使用者的存取權。這類錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
UNIMPLEMENTED_MEMBER_TYPE |
12 | 存取元組包含 Policy Simulator 不支援的主體類型。 |
UNIMPLEMENTED_MEMBER |
12 | 存取元組包含 Policy Simulator 不支援的主體。 |
UNIMPLEMENTED_CONDITION |
12 | 存取元組包含 Policy Simulator 不支援的條件。這類錯誤與 UNKNOWN_CONDITIONAL 存取權變更有關。 |
LOG_SIZE_TOO_LARGE |
8 | 資源與太多存取記錄相關聯,因此 Policy Simulator 無法執行模擬作業。如需詳細資訊,請參閱政策模擬器概念頁面中的「記錄重播大小上限」一節。 |
UNSUPPORTED_RESOURCE |
12 |
所提的允許政策會變更與不支援的資源類型相關聯的權限。這項錯誤會顯示在 "error": { "code": 12, "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.create" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.setIamPolicy" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.get" }, "reason": "UNSUPPORTED_RESOURCE" } ], "message": "unsupported-permissions-error-message" } 如要進一步瞭解不支援的資源類型,請參閱「政策模擬工具」概念頁面中的「資源類型的支援層級」。 |
REST
在 REST API 模擬結果中,錯誤可能會出現在兩個位置:
replayResult.error
欄位:如果重播嘗試失敗,政策模擬工具會在replayResult.error
欄位中回報錯誤。如果重播結果包含這個欄位,就不會包含diff
欄位。replayResult.diff.accessDiff.policy-type.errors
欄位,其中 policy-type 為baseline
或simulated
。如果重播嘗試成功,但結果為UNKNOWN_INFO_DENIED
或UNKNOWN_CONDITIONAL
,Policy Simulator 會在這個欄位中回報結果不明的原因。
Policy Simulator 會產生下列類型的錯誤:
錯誤 | 錯誤代碼 | 詳細資料 |
---|---|---|
GENERIC_INTERNAL_ERROR |
13 | 模擬失敗,因為發生內部錯誤。如要解決這個問題,請嘗試再次執行模擬。如果模擬結果仍失敗,請來信至 policy-simulator-feedback@google.com。 |
INVALID_ACCESS_TUPLE |
3 | 政策模擬工具無法重播存取嘗試,因為該嘗試含有無效的權限、資源名稱或主體。 |
OUT_OF_RANGE_GROUP_TOO_LARGE |
11 | 群組內含太多子群組,因此政策模擬工具無法評估群組中的管理員成員資格。這個錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
PERMISSION_DENIED_ON_GROUP_MEMBERSHIP |
7 | 由於呼叫端沒有查看群組成員的權限,因此政策模擬工具無法評估使用者的存取權。這個錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
PERMISSION_DENIED_ON_IAM_POLICY |
7 | 由於呼叫端沒有擷取允許政策的權限,因此政策模擬工具無法評估使用者的存取權。這類錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
PERMISSION_DENIED_ON_IAM_ROLE |
7 | 由於呼叫端沒有權限擷取 IAM 角色中的權限,因此政策模擬工具無法評估使用者的存取權。這類錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
PERMISSION_DENIED_ON_PARENT_IAM_POLICY |
7 | 由於呼叫端沒有權限擷取祖系資源的允許政策,因此政策模擬工具無法評估使用者的存取權。這類錯誤與 UNKNOWN_INFO_DENIED 存取權變更有關。 |
UNIMPLEMENTED_MEMBER_TYPE |
12 | 存取元組包含 Policy Simulator 不支援的主體類型。 |
UNIMPLEMENTED_MEMBER |
12 | 存取元組包含 Policy Simulator 不支援的主體。 |
UNIMPLEMENTED_CONDITION |
12 | 存取元組包含 Policy Simulator 不支援的條件。這類錯誤與 UNKNOWN_CONDITIONAL 存取權變更有關。 |
LOG_SIZE_TOO_LARGE |
8 | 資源與太多存取記錄相關聯,因此 Policy Simulator 無法執行模擬作業。如需詳細資訊,請參閱政策模擬器概念頁面中的「記錄重播大小上限」一節。 |
UNSUPPORTED_RESOURCE |
12 |
所提的允許政策會變更與不支援的資源類型相關聯的權限。這項錯誤會顯示在 "error": { "code": 12, "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.create" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.setIamPolicy" }, "reason": "UNSUPPORTED_RESOURCE" }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "domain": "policysimulator.googleapis.com", "metadata": { "permission": "storage.objects.get" }, "reason": "UNSUPPORTED_RESOURCE" } ], "message": "unsupported-permissions-error-message" } 如要進一步瞭解不支援的資源類型,請參閱「政策模擬工具」概念頁面中的「資源類型的支援層級」。 |
套用模擬政策變更
如要對允許政策套用模擬變更,請按照下列步驟操作:
控制台
按一下「套用提議的變更」。
在確認對話方塊中,按一下「Apply」確認變更。
gcloud
使用 set-iam-policy
指令,並提供包含要套用的模擬允許政策之 JSON 檔案路徑:
gcloud resource-type set-iam-policy resource-id filepath
提供以下這些值:
resource-type
:您要更新允許政策的資源類型。例如:projects
。resource-id
:您要更新允許政策的資源 ID。例如:my-project
。filepath
:包含更新版許可政策的檔案路徑。
回應包含更新後的許可政策。如果您將 IAM 許可政策視為程式碼,並儲存在版本控制系統中,請儲存 gcloud CLI 傳回的許可政策,而非包含模擬許可政策的 JSON 檔案。
REST
將建議的允許政策設為資源的新允許政策。
如要將要求中的允許政策設為專案的新允許政策,請使用 Resource Manager API 的 projects.setIamPolicy
方法。
使用任何要求資料之前,請先替換以下項目:
PROJECT_ID
:您的 Google Cloud 專案 ID。專案 ID 為英數字元字串,例如my-project
。POLICY
:您要設定的政策的 JSON 表示法。如要進一步瞭解政策格式,請參閱政策參考資料。
HTTP 方法和網址:
POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setIamPolicy
JSON 要求主體:
{ "policy": { POLICY } }
如要傳送要求,請展開以下其中一個選項:
回應包含更新後的許可政策。
儲存模擬結果
如果您使用 gcloud CLI,可以將政策模擬器結果儲存為 JSON、YAML 或 CSV 檔案。
另存為 JSON 或 YAML
如要將模擬結果儲存為 JSON 或 YAML 檔案,請在執行模擬時,將下列旗標新增至 replay-recent-access
指令:
--output=output-format > filename
替換下列值:
output-format
:匯出檔案的語言,可為json
或yaml
。filename
:匯出檔案的名稱。
儲存為 CSV
如要儲存 CSV 檔案,請在執行模擬時,將下列標記新增至 replay-recent-access
指令:
--flatten="diffs[]" --format=csv(output-fields) > filename
替換下列值:
output-fields
:以半形逗號分隔的清單,列出要納入匯出結果的欄位。例如:diffs.accessTuple.principal, diffs.accessTuple.permission
。filename
:匯出檔案的名稱。
您可以選擇將其他欄位 (例如 errors[]
) 新增至 --flatten
標記。將欄位新增至 --flatten
標記,即可在 CSV 檔案中以個別行列出這些欄位的元素。
以下是 replay-recent-access
指令範例,可將模擬結果中最重要的欄位儲存為 CSV 檔案 simulation-results.csv
:
gcloud iam simulator replay-recent-access --flatten="diffs[]" \ --format="csv(diffs.accessTuple.principal, diffs.accessTuple.permission, \ diffs.accessTuple.fullResourceName, diffs.diff.accessDiff.accessChange, \ diffs.diff.accessDiff.baseline.accessState, \ diffs.diff.accessDiff.simulated.accessState)" \ //cloudresourcemanager.googleapis.com/projects/my-project \ proposed-policy.json > simulation-results.csv
這個範例會模擬專案 my-project
的 proposed-policy.json
,並將結果儲存為 simulation-results.csv
。這個 CSV 檔案包含以下欄位:主體、權限、資源、存取權變更、基準存取狀態和模擬存取狀態。
如要進一步瞭解如何使用 gcloud CLI 設定格式,請參閱格式。
後續步驟
- 瞭解如何排解現有實體的存取權問題。
- 瞭解如何依據角色建議強制實行最低權限機制。