정책 변경사항 시뮬레이션

이 페이지에서는 정책 시뮬레이터를 사용하여 Identity and Access Management(IAM) 정책 변경을 시뮬레이션하는 방법을 설명합니다. 또한 선택하는 경우 시뮬레이션 결과를 해석하는 방법과 시뮬레이션된 정책을 적용하는 방법도 설명합니다.

시작하기 전에

권한 얻기

정책 변경을 시뮬레이션하기 전에 적절한 권한이 있는지 확인해야 합니다. 시뮬레이션을 실행하려면 특정 권한이 필요합니다. 다른 권한은 필수가 아니지만, 시뮬레이션에서 최대한 완벽한 결과를 얻는 데 도움이 됩니다.

IAM 역할에 대해 자세히 알아보려면 역할 이해를 참조하세요.

필수 대상 리소스 권한

시뮬레이션의 대상 리소스는 정책을 시뮬레이션할 리소스입니다.

대상 리소스에 대한 시뮬레이터 관리자 역할(roles/policysimulator.admin) 및 보안 검토자 역할(roles/iam.securityReviewer) 또는 다음 권한이 포함된 다른 역할이 필요합니다.

  • policysimulator.replays.run
  • cloudassets.assets.searchAllResources
  • service.resource.getIamPolicy. 여기서 resource는 대상 리소스의 리소스 유형이며 service는 해당 리소스를 소유한 Google Cloud 서비스의 이름입니다.

필수 호스트 리소스 권한

시뮬레이션의 호스트 리소스는 시뮬레이션을 만들고 실행하는 프로젝트, 폴더 또는 조직입니다. 호스트 리소스는 어떤 방식으로든 대상 리소스와 관련이 없어도 됩니다.

호스트 리소스를 설정하는 방법은 사용 중인 플랫폼에 따라 다릅니다.

Console

호스트 리소스는 리소스 선택기에 표시되는 프로젝트, 폴더 또는 조직입니다.

호스트 리소스를 변경하려면 리소스 선택기에서 다른 프로젝트, 폴더 또는 조직을 선택합니다.

gcloud

호스트 리소스는 현재의 할당량 프로젝트입니다. 할당량 프로젝트를 설정하려면 gcloud auth application-default set-quota-project 명령어를 사용합니다.

REST

요청을 보낼 때마다 호스트 리소스를 수동으로 지정합니다. 자세한 내용은 이 페이지의 정책 변경사항 시뮬레이션을 참조하세요.

호스트 리소스에 대한 시뮬레이터 관리자 역할(roles/policysimulator.admin) 또는 다음 권한이 포함된 다른 역할이 필요합니다.

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

시뮬레이션에서 가장 완벽한 결과를 얻으려면 특정 IAM 및 Google Workspace 권한이 있는 것이 좋습니다. 이러한 권한 중 일부 또는 전체가 없어도 시뮬레이션을 실행할 수 있습니다. 하지만 이러한 권한 없이 시뮬레이션을 실행하면 시뮬레이션 결과에 영향을 줄 수 있는 정보를 가져오지 못할 수 있으므로 알 수 없는 액세스 변경사항이 증가할 수 있습니다.

시뮬레이션을 실행할 때 조직의 보안 검토자 역할(roles/iam.securityReviewer)을 갖는 것이 좋습니다. 또는 보안 관리자 역할(roles/iam.securityAdmin)이 이미 있다면 추가 역할을 부여할 필요가 없습니다.

이러한 역할은 시뮬레이션에서 최대한 완벽한 결과를 얻는 데 도움이 되는 다음 권한을 제공합니다.

  • 커스텀 역할이 정의된 관련 프로젝트, 폴더 또는 조직에 대한 iam.roles.getiam.roles.list. 프로젝트, 폴더 또는 조직은 시뮬레이션할 정책이 있는 리소스의 상위 또는 하위 항목인 경우 관련이 있습니다.
  • service.resource.getIamPolicy. 여기서 resource는 IAM 정책을 가질 수 있는 리소스 유형의 이름이고 service는 해당 리소스를 소유하는 Google Cloud 서비스의 이름입니다.

    시뮬레이션을 실행할 때 다음 기준에 맞는 각 리소스에 대해 이 권한을 갖는 것이 좋습니다.

    • 정책 시뮬레이터는 리소스를 지원합니다.
    • 리소스에는 사용자 액세스에 영향을 줄 수 있는 IAM 정책이 있습니다. 다음 중 하나가 적용되는 경우가 여기에 해당합니다.

      • 리소스가 정책을 시뮬레이션할 리소스의 하위 요소이며 관련 액세스 로그에 표시됩니다.
      • 리소스가 정책을 시뮬레이션할 리소스의 상위 항목입니다.

    예를 들어 프로젝트에 대한 정책을 시뮬레이션한다고 가정해 보겠습니다. 액세스 로그에 프로젝트의 Cloud Storage 버킷에 대한 액세스 시도가 포함된 경우 해당 버킷에 대한 storage.buckets.getIamPolicy 권한이 필요합니다. 프로젝트에 IAM 정책이 있는 상위 폴더가 있는 경우 해당 폴더에 대한 resourcemanager.folders.getIamPolicy 권한도 필요합니다.

원래 정책 및 제안된 정책에 있는 각 Google 그룹의 그룹 멤버십 정보를 가져올 권한이 있는 것이 좋습니다.

일반적으로 Google Workspace 최고 관리자와 그룹 관리자에게는 그룹 멤버십을 볼 수 있는 권한이 있습니다. 최고 관리자나 그룹 관리자가 아닌 경우 Google Workspace 관리자에게 groups.read 권한이 포함된 커스텀 Google Workspace 관리자 역할을 만들도록 요청하세요. Admin API 권한 아래에서 이를 부여할 수 있습니다. 이렇게 하면 도메인 내 모든 그룹의 멤버십을 보고 정책 변경사항을 더 효과적으로 시뮬레이션할 수 있습니다.

정책 변경사항 시뮬레이션

다음 단계에 따라 정책 변경사항을 시뮬레이션합니다.

Console

다음 예시에서는 프로젝트의 정책 변경사항을 시뮬레이션하는 방법을 보여줍니다. 단, IAM 정책이 있는 모든 리소스의 정책 변경사항을 시뮬레이션할 수 있습니다.

주 구성원의 권한을 수정한 후 저장 대신 시뮬레이션을 클릭합니다.

  1. Cloud Console에서 IAM 페이지로 이동합니다.

    IAM 페이지로 이동

  2. 기존 주 구성원의 권한을 수정하여 제안된 정책 변경사항을 만듭니다.

    1. 액세스 권한을 수정하려는 주 구성원을 찾고 오른쪽의 수정 버튼을 클릭합니다.
    2. 새 역할을 추가하거나 기존 역할을 취소 또는 변경하여 주 구성원의 액세스 권한을 수정합니다.
  3. 제안된 변경사항을 시뮬레이션하려면 시뮬레이션을 클릭합니다.

  4. 몇 분 후 Cloud Console에 시뮬레이션된 정책의 결과가 액세스 변경사항 목록으로 표시됩니다. 자세한 내용은 이 페이지의 정책 시뮬레이터 결과 이해를 참조하세요.

    기존 정책과 시뮬레이션된 정책 간의 액세스 권한이 변경되지 않은 경우 Cloud Console에 액세스 변경사항이 표시되지 않습니다.

gcloud

정책 변경사항을 시뮬레이션하려면 읽기-수정-쓰기 패턴을 따르되 정책을 작성하는 대신 시뮬레이션합니다.

  1. 다음 명령어를 실행하여 현재 정책을 읽습니다.

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

    다음 값을 바꿉니다.

    • resource-type: 정책을 시뮬레이션할 리소스 유형입니다. 예를 들면 projects입니다.
    • resource-id: 정책을 시뮬레이션할 리소스의 ID입니다. 예를 들면 my-project입니다.
    • format: JSON 또는 YAML입니다.
    • filepath: 정책에 대한 새 출력 파일의 경로입니다.

    예를 들어 다음 명령어는 my-project 프로젝트의 정책을 JSON 형식으로 가져와 사용자의 홈 디렉터리에 저장합니다.

    gcloud projects get-iam-policy my-project --format=json > ~/policy.json
    
  2. get-iam-policy 명령어에서 반환된 JSON 또는 YAML 정책을 수정하여 시뮬레이션할 정책 변경사항을 반영합니다.

    정책 binding에 여러 유형의 변경 작업을 할 수 있습니다. 예를 들어 역할 결합에서 주 구성원을 추가 또는 삭제하거나 정책에서 역할 바인딩을 삭제할 수 있습니다.

  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: 응답 형식입니다. 예를 들면 json 또는 yaml입니다.

    몇 분 후에 제안된 정책이 적용되면 이 명령어는 주 구성원의 액세스 권한이 어떻게 변경될지 설명하는 재생 목록을 출력합니다. 이러한 결과에는 시뮬레이션 중에 발생한 오류가 나열되며 지원되지 않는 리소스 유형으로 인한 오류가 포함됩니다.

    결과를 읽는 방법은 이 페이지의 정책 시뮬레이터 결과 이해를 참조하세요. 시뮬레이션 결과를 출력하는 대신 저장하는 방법은 시뮬레이션 결과 저장을 참조하세요.

    다음은 사용자 my-user@example.com과 관련된 정책 시뮬레이션에 대한 샘플 응답입니다. 이 경우 제안된 변경사항이 적용되면 my-user@example.com은 더 이상 my-project 프로젝트에 대한 resourcemanager.projects.listresourcemanager.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

정책 변경을 시뮬레이션하려면 읽기-수정-쓰기 패턴을 따르되 정책을 작성하는 대신 시뮬레이션을 만들고 실행합니다.

  1. 리소스에 대한 IAM 정책을 읽습니다.

    Resource Manager API의 projects.getIamPolicy 메서드가 프로젝트의 IAM 정책을 가져옵니다.

    요청 데이터를 사용하기 전에 다음을 바꿉니다.

    • PROJECT_ID: Google Cloud 프로젝트 ID. 프로젝트 ID는 my-project 같은 영숫자 문자열입니다.
    • POLICY_VERSION: 반환할 정책 버전입니다. 요청에는 정책 버전 3인 최신 정책 버전이 지정되어야 합니다. 자세한 내용은 정책을 가져올 때 정책 버전 지정을 참조하세요.

    HTTP 메서드 및 URL:

    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"
          ]
        }
      ]
    }
    

  2. 반환된 정책을 수정하여 시뮬레이션할 변경사항을 반영합니다.

    정책 binding에 여러 유형의 변경 작업을 할 수 있습니다. 예를 들어 역할 결합에서 주 구성원을 추가 또는 삭제하거나 정책에서 역할 바인딩을 삭제할 수 있습니다.

  3. 수정된 정책으로 시뮬레이션 또는 재생을 만듭니다.

    정책 시뮬레이터 API의 replays.create 메서드는 프로젝트, 폴더, 조직을 위한 재생을 생성합니다.

    요청 데이터를 사용하기 전에 다음을 바꿉니다.

    • host-resource-type: 재생을 호스팅할 리소스의 유형입니다. 이 값은 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 쌍을 포함합니다.

    HTTP 메서드 및 URL:

    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"
      }
    }
    

  4. 재생을 완료할 때까지 operations.get 메서드를 폴링합니다.

    작업을 폴링하려면 응답에 완료된 재생의 이름이 있는 "done": true 필드 및 name 필드 이름이 포함될 때까지 operations.get 메서드를 반복해서 호출하는 것이 좋습니다. 잘린 지수 백오프를 사용하여 각 요청 간에 지연을 일으킵니다.

    Policy Simulator API의 operations.get 메서드는 재생 상태를 가져옵니다.

    요청 데이터를 사용하기 전에 다음을 바꿉니다.

    • operation-name: operations 프리픽스를 포함한 재생 작업의 이름입니다. replays.create 응답의 name 필드에서 이 값을 복사합니다. 예를 들면 operations/6de23e63-f61a-4b8c-b502-34d717d2d7f8입니다.

    HTTP 메서드 및 URL:

    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
            }
          }
        }
      }
    }
    

  5. 재생 결과를 가져옵니다.

    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: 선택사항. 이 메서드의 이전 응답에서 반환된 페이지 나누기 토큰입니다. 지정하면 결과 목록이 이전 요청이 끝나는 위치에서 시작됩니다.

    HTTP 메서드 및 URL:

    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.listresourcemanager.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"
    }
    

    기존 정책과 시뮬레이션된 정책 간에 액세스 권한이 변경되지 않으면 요청은 빈 목록({})을 반환합니다.

정책 시뮬레이터 결과 이해

정책 시뮬레이터는 제안된 정책 변경사항의 영향을 액세스 변경사항 목록으로 보고합니다. 각 액세스 변경사항은 현재 정책이 아닌 제안된 정책과 결과가 다른 지난 90일 동안의 액세스 시도를 나타냅니다.

정책 시뮬레이터는 시뮬레이션 중에 발생한 오류도 나열하므로 시뮬레이션의 잠재적 격차를 식별할 수 있습니다.

이러한 변경사항 및 오류의 표시는 사용 중인 플랫폼에 따라 다릅니다.

Console

정책 시뮬레이터 결과 페이지에는 시뮬레이션 결과가 여러 섹션으로 표시됩니다.

  • 정책 개요: 이 섹션에는 주 구성원이 리소스에 대해 갖고 있던 원래 역할과 제안된 정책에서 갖게 될 역할이 나열됩니다. 원래 역할은 기존 정책에 나열되고 제안된 역할은 제안된 정책에 나열됩니다.

  • 액세스 변경사항 요약: 이 섹션에는 제안된 정책이 적용되었을 때 변경되었을 수 있는 지난 90일 동안의 액세스 시도 횟수가 표시됩니다. 이 요약에는 시뮬레이션 중 발생한 오류와 함께 잠재적인 액세스 문제 또는 알 수 없는 액세스 변경사항이 포함됩니다.

  • 지난 90일 동안의 액세스 변경사항: 이 섹션에는 제안된 정책이 적용되었을 때 변경되었을 수 있는 지난 90일 동안의 각 액세스 시도가 나열됩니다. 각 항목이나 액세스 변경사항에는 액세스 시도와 관련된 리소스, 주 구성원, 권한과 함께 액세스 변경 유형이 포함됩니다.

    액세스 변경사항 유형에는 여러 가지가 있습니다.

    액세스 변경사항 세부정보
    액세스 권한이 취소됨 현재 정책에 따라 주 구성원에게 액세스 권한이 있지만 제안된 변경 후에는 더 이상 액세스 권한이 없습니다.
    액세스 권한이 취소되었을 수 있음

    이 결과는 다음과 같은 원인으로 인해 발생할 수 있습니다.

    • 현재 정책에 따라 주 구성원에게 액세스 권한이 있었지만 제안된 정책에 따른 액세스 권한을 알 수 없습니다.
    • 현재 정책에 따른 주 구성원의 액세스 권한을 알 수 없으며 제안된 변경 후에는 액세스 권한이 없습니다.
    액세스 권한 부여됨 현재 정책에 따라 주 구성원에게 액세스 권한이 없었지만 제안된 변경 후에는 액세스 권한이 있습니다.
    액세스 권한이 부여되었을 수 있음

    이 결과는 다음과 같은 원인으로 인해 발생할 수 있습니다.

    • 현재 정책에 따라 주 구성원에게 액세스 권한이 없으며 제안된 변경 후에 액세스 권한을 알 수 없습니다.
    • 현재 정책에 따른 주 구성원의 액세스 권한을 알 수 없지만 제안된 변경 후에는 액세스 권한이 있습니다.
    액세스 변경사항 알 수 없음 현재 정책과 제안된 정책 모두에서 주 구성원의 액세스 권한을 알 수 없으며 제안된 변경사항이 주 구성원 액세스 권한에 영향을 미칠 수 있습니다.
    오류 시뮬레이션 중에 오류가 발생했습니다.

    액세스 변경사항에 대한 추가 세부정보를 보려면 액세스 변경사항을 클릭합니다. 그러면 액세스 변경 세부정보 패널이 열립니다. 여기에는 주 구성원의 기존 액세스, 주 구성원의 제안된 액세스, 액세스 변경 결과에 대한 추가 세부정보를 포함하여 액세스 변경에 대한 추가 정보가 표시됩니다.

gcloud

replay-recent-access 명령어를 사용하면 gcloud 도구의 응답에 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: 기준 액세스 상태와 시뮬레이션된 액세스 상태 간의 변경사항입니다. 가능한 값 목록은 다음 표를 참조하세요.

    액세스 변경사항 세부정보
    ACCESS_REVOKED 현재 정책에 따라 주 구성원에게 액세스 권한이 있지만 제안된 변경 후에는 더 이상 액세스 권한이 없습니다.
    ACCESS_MAYBE_REVOKED

    이 결과는 다음과 같은 원인으로 인해 발생할 수 있습니다.

    • 현재 정책에 따라 주 구성원에게 액세스 권한이 있었지만 제안된 정책에 따른 액세스 권한을 알 수 없습니다.
    • 현재 정책에 따른 주 구성원의 액세스 권한을 알 수 없으며 제안된 변경 후에는 액세스 권한이 없습니다.
    ACCESS_GAINED 현재 정책에 따라 주 구성원에게 액세스 권한이 없었지만 제안된 변경 후에는 액세스 권한이 있습니다.
    ACCESS_MAYBE_GAINED

    이 결과는 다음과 같은 원인으로 인해 발생할 수 있습니다.

    • 현재 정책에 따라 주 구성원에게 액세스 권한이 없으며 제안된 변경 후에 액세스 권한을 알 수 없습니다.
    • 현재 정책에 따른 주 구성원의 액세스 권한을 알 수 없지만 제안된 변경 후에는 액세스 권한이 있습니다.
    UNKNOWN_CHANGE 현재 정책과 제안된 정책 모두에서 주 구성원의 액세스 권한을 알 수 없으며 제안된 변경사항이 주 구성원 액세스 권한에 영향을 미칠 수 있습니다.

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: 기준 액세스 상태와 시뮬레이션된 액세스 상태 간의 변경사항입니다. 가능한 값 목록은 다음 표를 참조하세요.

    액세스 변경사항 세부정보
    ACCESS_REVOKED 현재 정책에 따라 주 구성원에게 액세스 권한이 있지만 제안된 변경 후에는 더 이상 액세스 권한이 없습니다.
    ACCESS_MAYBE_REVOKED

    이 결과는 다음과 같은 원인으로 인해 발생할 수 있습니다.

    • 현재 정책에 따라 주 구성원에게 액세스 권한이 있었지만 제안된 정책에 따른 액세스 권한을 알 수 없습니다.
    • 현재 정책에 따른 주 구성원의 액세스 권한을 알 수 없으며 제안된 변경 후에는 액세스 권한이 없습니다.
    ACCESS_GAINED 현재 정책에 따라 주 구성원에게 액세스 권한이 없었지만 제안된 변경 후에는 액세스 권한이 있습니다.
    ACCESS_MAYBE_GAINED

    이 결과는 다음과 같은 원인으로 인해 발생할 수 있습니다.

    • 현재 정책에 따라 주 구성원에게 액세스 권한이 없으며 제안된 변경 후에 액세스 권한을 알 수 없습니다.
    • 현재 정책에 따른 주 구성원의 액세스 권한을 알 수 없지만 제안된 변경 후에는 액세스 권한이 있습니다.
    UNKNOWN_CHANGE 현재 정책과 제안된 정책 모두에서 주 구성원의 액세스 권한을 알 수 없으며 제안된 변경사항이 주 구성원 액세스 권한에 영향을 미칠 수 있습니다.

알 수 없는 결과

액세스 결과를 알 수 없는 경우는 정책 시뮬레이터에 액세스 시도를 완벽하게 평가할 수 있는 정보가 부족하다는 의미입니다.

Console

액세스 결과를 알 수 없는 경우 액세스 변경 세부정보 패널에 알 수 없는 이유와 액세스할 수 없거나 평가할 수 없는 특정 역할, 정책, 그룹 멤버십, 조건이 보고됩니다.

결과를 알 수 없는 이유에는 여러 가지가 있습니다.

  • 역할 정보가 거부됨: 시뮬레이션을 실행하는 주 구성원에게 시뮬레이션하는 역할 하나 이상에 대한 역할 세부정보를 확인할 수 있는 권한이 없습니다.
  • 정책에 액세스할 수 없음: 시뮬레이션을 실행하는 주 구성원에게 시뮬레이션에 관련된 리소스 하나 이상에 대한 IAM 정책을 가져올 수 있는 권한이 없습니다.
  • 멤버십 정보가 거부됨: 시뮬레이션을 실행하는 주 구성원에게 제안된 정책에 포함된 그룹 하나 이상의 구성원을 볼 수 있는 권한이 없습니다.
  • 지원되지 않는 조건: 테스트 중인 정책에 조건부 역할 결합이 있습니다. 정책 시뮬레이터는 조건을 지원하지 않으므로 binding을 평가할 수 없습니다.

gcloud

gcloud 도구에서 시뮬레이션 결과는 액세스 차이에서 결과를 알 수 없는 이유를 보고합니다.

액세스 결과를 알 수 없는 이유는 다음 중 하나입니다.

  • UNKNOWN_INFO_DENIED: 사용자에게 액세스 상태 평가에 필요한 정보에 액세스할 권한이 없습니다. 여기에는 다음과 같은 이유가 있을 수 있습니다.

    • 사용자에게 시뮬레이션되는 정책을 검색할 권한이 없거나 액세스 로그의 리소스에 대한 정책을 검색할 권한이 없습니다.
    • 사용자에게 그룹 멤버십을 볼 권한이 없습니다.
    • 사용자가 필요한 역할 정보를 검색할 수 없습니다.

    누락된 정보를 확인하려면 보고된 액세스 상태 이후의 오류 정보를 참조하세요.

  • UNKNOWN_CONDITIONAL: 테스트 중인 정책에 조건부 역할 결합이 있습니다. 정책 시뮬레이터는 조건을 지원하지 않으므로 binding을 평가할 수 없습니다.

결과를 알 수 없는 경우 정책의 accessDiff 필드(baseline 또는 simulated)에 정보를 알 수 없는 이유를 설명하는 errors 필드 및 policies 필드에 오류와 관련된 정책이 나열됩니다. 오류에 대한 자세한 내용은 이 페이지의 오류를 참조하세요.

REST

REST API의 경우 시뮬레이션 결과에서 액세스 차이에서 결과를 알 수 없는 이유를 보고합니다.

액세스 결과를 알 수 없는 이유는 다음 중 하나입니다.

  • UNKNOWN_INFO_DENIED: 사용자에게 액세스 상태 평가에 필요한 정보에 액세스할 권한이 없습니다. 여기에는 다음과 같은 이유가 있을 수 있습니다.

    • 사용자에게 시뮬레이션되는 정책을 검색할 권한이 없거나 액세스 로그의 리소스에 대한 정책을 검색할 권한이 없습니다.
    • 사용자에게 그룹 멤버십을 볼 권한이 없습니다.
    • 사용자가 필요한 역할 정보를 검색할 수 없습니다.

    누락된 정보를 확인하려면 보고된 액세스 상태 이후의 오류 정보를 참조하세요.

  • UNKNOWN_CONDITIONAL: 테스트 중인 정책에 조건부 역할 결합이 있습니다. 정책 시뮬레이터는 조건을 지원하지 않으므로 binding을 평가할 수 없습니다.

결과를 알 수 없는 경우 정책의 accessDiff 필드(baseline 또는 simulated)에 정보를 알 수 없는 이유를 설명하는 errors 필드 및 policies 필드에 오류와 관련된 정책이 나열됩니다. 오류에 대한 자세한 내용은 이 페이지의 오류를 참조하세요.

오류

정책 시뮬레이터는 시뮬레이션 중에 발생한 오류도 보고합니다. 시뮬레이션의 잠재적 차이를 이해하려면 이러한 오류를 검토해야 합니다.

Console

정책 시뮬레이터에서 보고할 수 있는 오류 유형에는 여러 가지가 있습니다.

  • 작업 오류: 시뮬레이션을 실행할 수 없습니다. 정책 시뮬레이터는 결과 페이지 상단에 작업 오류를 보고합니다.

    프로젝트나 조직에 로그가 너무 많아 시뮬레이션을 실행할 수 없음을 나타내는 오류 메시지가 표시되는 경우 리소스에 시뮬레이션을 실행할 수 없습니다.

    다른 이유로 인해 이 오류가 표시되면 시뮬레이션을 다시 실행해 봅니다. 시뮬레이션을 여전히 실행할 수 없으면 policy-simulator-feedback@google.com에 문의하세요.

  • 재생 오류: 단일 액세스 시도 재생이 실패했으므로 정책 시뮬레이터에서 제안된 정책에 따라 액세스 시도 결과가 변하는지를 확인할 수 없습니다.

    Cloud Console에 지난 90일 동안의 액세스 변경사항 표에 재생 오류가 나열됩니다. 각 오류의 액세스 변경 세부정보 패널에는 문제를 이해할 수 있도록 오류 메시지와 오류 발생 시 시뮬레이션된 리소스 및 권한이 포함되어 있습니다.

  • 지원되지 않는 리소스 유형 오류: 제안된 정책은 지원되지 않는 리소스 유형과 관련된 권한에 영향을 미치므로 정책 시뮬레이터에서 시뮬레이션할 수 없습니다.

    정책 시뮬레이터는 시뮬레이션 결과에 이러한 권한을 나열하므로 시뮬레이션할 수 없는 권한을 알 수 있습니다.

gcloud

gcloud 도구의 시뮬레이션 결과에서 오류가 두 개 위치에 나타날 수 있습니다.

  • replayResult.error 필드: 재생 시도가 실패하면 정책 시뮬레이터가 replayResult.error 필드에 오류를 보고합니다. 재생 결과에 이 필드가 포함되어 있으면 diff 필드가 포함되지 않습니다.
  • replayResult.diff.accessDiff.policy-type.errors 필드. 여기서 policy-typebaseline 또는 simulated입니다. 재생 시도는 성공했지만 결과가 UNKNOWN_INFO_DENIED 또는 UNKNOWN_CONDITIONAL이면 정책 시뮬레이터에서 이 필드에 결과를 알 수 없는 이유를 보고합니다.

정책 시뮬레이터에서 생성되는 오류 유형은 다음과 같습니다.

오류 오류 코드 세부정보
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 호출자에게 IAM 정책을 검색할 권한이 없으므로 정책 시뮬레이터에서 사용자의 액세스 권한을 평가할 수 없습니다. 이 유형의 오류는 UNKNOWN_INFO_DENIED 액세스 변경사항과 관련이 있습니다.
PERMISSION_DENIED_ON_IAM_ROLE 7 호출자에게 IAM 역할의 권한을 검색할 권한이 없으므로 정책 시뮬레이터에서 사용자의 액세스를 평가할 수 없습니다. 이 유형의 오류는 UNKNOWN_INFO_DENIED 액세스 변경사항과 관련이 있습니다.
PERMISSION_DENIED_ON_PARENT_IAM_POLICY 7 호출자에게 상위 리소스의 IAM 정책을 검색할 권한이 없으므로 정책 시뮬레이터에서 사용자의 액세스 권한을 평가할 수 없습니다. 이 유형의 오류는 UNKNOWN_INFO_DENIED 액세스 변경사항과 관련이 있습니다.
UNIMPLEMENTED_MEMBER_TYPE 12 액세스 튜플에는 정책 시뮬레이터에서 지원하지 않는 주 구성원 유형이 포함되어 있습니다.
UNIMPLEMENTED_MEMBER 12 액세스 튜플에는 정책 시뮬레이터에서 지원하지 않는 구성원이 포함되어 있습니다.
UNIMPLEMENTED_CONDITION 12 액세스 튜플에 정책 시뮬레이터가 지원하지 않는 조건이 포함되어 있습니다. 이 유형의 오류는 UNKNOWN_CONDITIONAL 액세스 변경사항과 관련이 있습니다.
LOG_SIZE_TOO_LARGE 8 리소스가 너무 많은 액세스 로그에 연결되어 있으므로 정책 시뮬레이터에서 시뮬레이션을 실행할 수 없습니다. 자세한 내용은 정책 시뮬레이터 개념 페이지의 최대 로그 재생 크기를 참조하세요.
UNSUPPORTED_RESOURCE 12

제안된 정책이 지원되지 않는 리소스 유형과 관련된 권한을 변경합니다. 이 오류는 replayResult.error 필드에 표시되며 지원되지 않는 리소스 유형과 관련된 권한 목록을 포함합니다. 예를 들면 다음과 같습니다.


"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-typebaseline 또는 simulated입니다. 재생 시도는 성공했지만 결과가 UNKNOWN_INFO_DENIED 또는 UNKNOWN_CONDITIONAL이면 정책 시뮬레이터에서 이 필드에 결과를 알 수 없는 이유를 보고합니다.

정책 시뮬레이터에서 생성되는 오류 유형은 다음과 같습니다.

오류 오류 코드 세부정보
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 호출자에게 IAM 정책을 검색할 권한이 없으므로 정책 시뮬레이터에서 사용자의 액세스 권한을 평가할 수 없습니다. 이 유형의 오류는 UNKNOWN_INFO_DENIED 액세스 변경사항과 관련이 있습니다.
PERMISSION_DENIED_ON_IAM_ROLE 7 호출자에게 IAM 역할의 권한을 검색할 권한이 없으므로 정책 시뮬레이터에서 사용자의 액세스를 평가할 수 없습니다. 이 유형의 오류는 UNKNOWN_INFO_DENIED 액세스 변경사항과 관련이 있습니다.
PERMISSION_DENIED_ON_PARENT_IAM_POLICY 7 호출자에게 상위 리소스의 IAM 정책을 검색할 권한이 없으므로 정책 시뮬레이터에서 사용자의 액세스 권한을 평가할 수 없습니다. 이 유형의 오류는 UNKNOWN_INFO_DENIED 액세스 변경사항과 관련이 있습니다.
UNIMPLEMENTED_MEMBER_TYPE 12 액세스 튜플에는 정책 시뮬레이터에서 지원하지 않는 주 구성원 유형이 포함되어 있습니다.
UNIMPLEMENTED_MEMBER 12 액세스 튜플에는 정책 시뮬레이터에서 지원하지 않는 구성원이 포함되어 있습니다.
UNIMPLEMENTED_CONDITION 12 액세스 튜플에 정책 시뮬레이터가 지원하지 않는 조건이 포함되어 있습니다. 이 유형의 오류는 UNKNOWN_CONDITIONAL 액세스 변경사항과 관련이 있습니다.
LOG_SIZE_TOO_LARGE 8 리소스가 너무 많은 액세스 로그에 연결되어 있으므로 정책 시뮬레이터에서 시뮬레이션을 실행할 수 없습니다. 자세한 내용은 정책 시뮬레이터 개념 페이지의 최대 로그 재생 크기를 참조하세요.
UNSUPPORTED_RESOURCE 12

제안된 정책이 지원되지 않는 리소스 유형과 관련된 권한을 변경합니다. 이 오류는 replayResult.error 필드에 표시되며 지원되지 않는 리소스 유형과 관련된 권한 목록을 포함합니다. 예를 들면 다음과 같습니다.


"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"
}

지원되지 않는 리소스 유형에 대한 자세한 내용은 정책 시뮬레이터 개념 페이지에서 리소스 유형의 지원 수준을 참조하세요.

시뮬레이션된 정책 변경사항 적용

시뮬레이션된 정책 변경사항을 적용하려면 다음 단계를 따르세요.

Console

  1. 제안된 변경사항 적용을 클릭합니다.

  2. 확인 대화상자에서 적용을 클릭하여 변경사항을 확인합니다.

gcloud

set-iam-policy 명령어를 사용하고 적용할 시뮬레이션된 정책이 포함된 JSON 파일의 경로를 제공합니다.

gcloud resource-type set-iam-policy resource-id filepath

다음 값을 제공합니다.

  • resource-type: 정책을 업데이트할 리소스 유형입니다. 예를 들면 projects입니다.
  • resource-id: 정책을 업데이트할 리소스의 ID입니다. 예를 들면 my-project입니다.
  • filepath: 업데이트된 정책이 포함된 파일의 경로입니다.

응답에는 업데이트된 정책이 포함됩니다. IAM 정책을 코드로 취급하고 버전 제어 시스템에 저장하는 경우에는 시뮬레이션된 정책이 포함된 JSON 파일이 아니라 gcloud 도구가 반환하는 정책을 저장해야 합니다.

REST

제안된 정책을 리소스의 새 정책으로 설정합니다.

Resource Manager API의 projects.setIamPolicy 메서드는 요청의 정책을 프로젝트의 새 IAM 정책으로 설정합니다.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • PROJECT_ID: Google Cloud 프로젝트 ID. 프로젝트 ID는 my-project 같은 영숫자 문자열입니다.
  • POLICY: 설정하려는 정책의 JSON 표현입니다. 정책 형식에 대한 자세한 내용은 정책 참조를 확인하세요.

HTTP 메서드 및 URL:

POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setIamPolicy

JSON 요청 본문:

{
  "policy": {
    POLICY
  }
}

요청을 보내려면 다음 옵션 중 하나를 펼칩니다.

응답에는 업데이트된 정책이 포함됩니다.


시뮬레이션 결과 저장

gcloud 도구를 사용하는 경우 정책 시뮬레이터 결과를 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 파일에서 여러 줄로 나열될 수 있습니다.

다음은 시뮬레이션 결과의 가장 중요한 필드를 CSV 파일 simulation-results.csv로 저장하는 replay-recent-access 명령어의 예시입니다.

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 도구를 사용한 형식 지정에 대한 자세한 내용은 형식을 참조하세요.

다음 단계