IAM 권한 문제 해결

IAM 정책 문제 해결 도구는 사용자에게 특정 리소스에 대한 액세스 권한이 있는 이유 또는 API를 호출할 수 있는 권한이 없는 이유를 이해하는 데 도움이 됩니다. 이메일 주소, 리소스, 권한을 입력하면 정책 문제 해결 도구가 리소스에 적용되는 모든 허용 및 거부 정책을 조사합니다. 그런 다음 이러한 정책을 사용하여 주 구성원에게 권한이 있는지 여부를 알려줍니다. 또한 정책의 역할 바인딩 및 거부 규칙을 나열하고 주 구성원의 액세스 권한에 미치는 영향을 설명합니다.

Google Cloud 콘솔, Google Cloud CLI 또는 REST API를 사용하여 정책 문제 해결 도구에 액세스할 수 있습니다. 간단한 쿼리에서는 Google Cloud 콘솔을 사용하는 것이 일반적으로 가장 빠릅니다. 더 복잡한 시나리오에서는 gcloud CLI 또는 REST API를 사용하는 것이 좋습니다.

시작하기 전에

  • Policy Troubleshooter API 사용 설정

    API 사용 설정

필수 권한

주 구성원의 액세스 문제를 완전히 해결하려면 다음 권한이 필요합니다.

개별 주 구성원의 액세스 문제 해결 권한

정책 문제 해결 도구는 허용 정책, 거부 정책, 볼 수 있는 권한이 있는 역할에 따라 리소스에 대한 주 구성원의 액세스 권한을 분석합니다. 리소스에 적용되는 정책을 볼 권한이 없거나 커스텀 역할을 볼 권한이 없는 경우 주 구성원에게 액세스 권한이 있는지 여부를 알 수 없습니다.

주 구성원의 액세스 문제 해결에 필요한 권한을 얻으려면 관리자에게 조직에 대한 다음 IAM 역할을 부여해 달라고 요청하세요.

역할 부여에 대한 자세한 내용은 액세스 관리를 참조하세요.

커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.

그룹 구성원의 액세스 문제 해결 권한

허용 및 거부 정책에 그룹이 포함된 경우 개별 그룹 구성원의 액세스 문제를 해결하려면 Google Workspace Admin API 권한 groups.read가 필요합니다. 최고 관리자 및 그룹 관리자는 이 권한을 자동으로 갖습니다. 최고 관리자나 그룹 관리자가 아닌 사용자에게 이 권한을 부여하려면 groups.read 권한(Admin API 권한 아래에 위치)이 포함된 커스텀 Google Workspace 관리자 역할을 만들고 사용자에게 이 역할을 부여합니다.

이러한 권한이 없으면 역할 바인딩 또는 거부 규칙에 명시적으로 주 구성원이 포함되어 있지 않는 한 그룹 또는 도메인이 포함된 역할 바인딩 및 거부 규칙의 액세스 결과가 알 수 없음입니다.

도메인 구성원의 액세스 문제 해결 권한

허용 및 거부 정책에 Google Workspace 계정 또는 Cloud ID 도메인이 포함된 경우 개별 도메인 구성원의 액세스 문제를 해결하려면 도메인 관리자여야 합니다.

이러한 권한이 없으면 역할 바인딩 또는 거부 규칙에 명시적으로 주 구성원이 포함되어 있지 않는 한 그룹 또는 도메인이 포함된 역할 바인딩 및 거부 규칙의 액세스 결과가 알 수 없음입니다.

액세스 문제 해결

액세스 문제를 해결하려면 다음 정보가 필요합니다.

  • 주 구성원: 확인할 이메일 주소입니다. 이메일 주소는 사용자나 서비스 계정을 참조해야 합니다. 그룹, 도메인, 직원 ID, 워크로드 ID를 비롯한 다른 유형의 주 구성원은 지원되지 않습니다.
  • 리소스: 리소스의 전체 이름입니다. 예를 들어 my-project 프로젝트를 확인하려면 //cloudresourcemanager.googleapis.com/projects/my-project를 입력합니다. 다른 리소스 유형은 전체 리소스 이름의 예시를 참조하세요.
  • 권한: 확인할 권한입니다. Google Cloud 콘솔을 사용하면 입력과 동시에 제안 목록이 표시됩니다. 전체 권한 목록은 권한 참조를 확인하세요.

콘솔

액세스 문제를 해결하려면 다음을 따르세요.

  1. Google Cloud 콘솔에서 정책 문제 해결 도구 페이지로 이동합니다.

    정책 문제 해결 도구로 이동

  2. 액세스 권한을 확인하려는 주 구성원의 이메일을 입력합니다.

  3. 확인할 리소스의 전체 리소스 이름을 입력합니다.

    전체 리소스 이름을 모르면 다음 중 하나를 수행합니다.

    • 프로젝트, 폴더 또는 조직에 대한 액세스 문제를 해결하려면 입력을 시작하여 자동 완성 옵션을 확인합니다.
    • 다른 리소스 유형의 액세스 문제를 해결하려면 찾아보기를 클릭하여 리소스 검색 대화상자를 열고 리소스를 검색합니다.

      1. 범위 선택 상자에서 검색할 프로젝트, 폴더 또는 조직을 선택합니다.
      2. 리소스 유형 상자에서 검색할 리소스 유형을 선택합니다.
      3. 리소스 검색 상자에 리소스 이름 일부를 입력합니다.
      4. 결과 섹션에서 확인하려는 리소스를 선택합니다.
      5. 선택을 클릭하여 리소스를 선택하고 대화상자를 닫습니다.
  4. 확인할 권한을 입력합니다.

    전체 권한 이름을 모르면 입력을 시작하여 자동 완성 옵션을 확인합니다.

  5. 선택사항: 여러 리소스 및 권한을 확인하려면 다른 쌍 추가를 선택하고 이전 단계를 반복합니다.

  6. 액세스 확인을 클릭합니다.

gcloud

주 구성원에게 IAM 권한이 있거나 없는 이유를 찾으려면 gcloud policy-troubleshoot iam 명령어를 사용합니다.

아래의 명령어 데이터를 사용하기 전에 다음을 바꿉니다.

  • EMAIL: 권한 문제를 해결하려는 주 구성원의 이메일 주소입니다.
  • RESOURCE: 권한이 부여된 리소스입니다.
  • PERMISSION: 문제를 해결하려는 권한입니다.

gcloud policy-troubleshooter iam 명령어를 실행합니다.

Linux, macOS 또는 Cloud Shell

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL \
    --permission=PERMISSION

Windows(PowerShell)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL `
    --permission=PERMISSION

Windows(cmd.exe)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL ^
    --permission=PERMISSION

다음과 비슷한 응답이 표시됩니다.

{
  "accessTuple": {
    "conditionContext": {
      "destination": {},
      "effectiveTags": [
        {
          "tagValue": "tagValues/281481941428044",
          "namespacedTagValue": "803434038361/env/dev",
          "tagKey": "tagKeys/281475994198094",
          "namespacedTagKey": "803434038361/env",
          "tagKeyParentName": "organizations/803434038361"
        }
      ],
      "request": {},
      "resource": {}
    },
    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
    "permission": "compute.instances.get",
    "permissionFqdn": "compute.googleapis.com/instances.get",
    "principal": "user1@example.com"
  },
  "allowPolicyExplanation": {
    "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
    "explainedPolicies": [
      {
        "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
        "bindingExplanations": [
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_HIGH"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH",
            "role": "roles/compute.viewer",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_NOT_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user2@example.com": {
                "membership": "MEMBERSHIP_NOT_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL",
            "role": "roles/owner",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL",
            "role": "roles/resourcemanager.organizationAdmin",
            "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL"
          }
        ],
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
        "policy": {
          "bindings": [
            {
              "members": [
                "user:user1@example.com"
              ],
              "role": "roles/compute.viewer"
            },
            {
              "members": [
                "user:user2@example.com"
              ],
              "role": "roles/owner"
            },
            {
              "members": [
                "user:user1@example.com"
              ],
              "role": "roles/resourcemanager.organizationAdmin"
            },
          ],
          "etag": "BwX5/L9Vbg4=",
          "version": 3
        },
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
  },
  "denyPolicyExplanation": {
    "denyAccessState": "DENY_ACCESS_STATE_DENIED",
    "explainedResources": [
      {
        "denyAccessState": "DENY_ACCESS_STATE_DENIED",
        "explainedPolicies": [
          {
            "denyAccessState": "DENY_ACCESS_STATE_DENIED",
            "policy": {
              "createTime": "2023-04-18T07:15:47.702191Z",
              "displayName": "Deny compute instance get",
              "etag": "MTc3MDA1ODIyNjExNTMzMDg2NzI=",
              "kind": "DenyPolicy",
              "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F123456789012/denypolicies/deny-compute-get",
              "rules": [
                {
                  "denyRule": {
                    "deniedPrincipals": [
                      "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com"
                    ],
                    "deniedPermissions": [
                      "compute.googleapis.com/instances.get"
                    ]
                  }
                }
              ],
              "uid": "77e93c80-b383-0027-268e-a52a608aa13d",
              "updateTime": "2023-04-18T07:15:47.702191Z",
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH",
            "ruleExplanations": [
              {
                "combinedDeniedPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedDeniedPrincipal": {
                  "membership": "MEMBERSHIP_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedExceptionPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedExceptionPrincipal": {
                  "membership": "MEMBERSHIP_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPermissions": {
                  "compute.googleapis.com/instances.get": {
                    "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "deniedPrincipals": {
                  "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com": {
                    "membership": "MEMBERSHIP_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "denyAccessState": "DENY_ACCESS_STATE_DENIED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            ]
          }
        ],
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/123456789012",
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "permissionDeniable": true,
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "overallAccessState": "CANNOT_ACCESS"
}

REST

주 구성원에게 IAM 권한이 있거나 없는 이유를 찾으려면 Policy Troubleshooter API의 iam.troubleshoot 메서드를 사용합니다.

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

  • EMAIL: 권한 문제를 해결하려는 주 구성원의 이메일 주소입니다.
  • RESOURCE: 권한이 부여된 리소스입니다.
  • PERMISSION: 문제를 해결하려는 권한입니다.
  • PROJECT_ID: 요청을 전송하는 데 사용할 프로젝트의 ID입니다. 프로젝트 ID는 my-project 같은 영숫자 문자열입니다.

HTTP 메서드 및 URL:

POST https://policytroubleshooter.googleapis.com/v3/iam:troubleshoot

JSON 요청 본문:

{
  "accessTuple": {
    "principal": "EMAIL",
    "fullResourceName": "RESOURCE",
    "permission": "PERMISSION"
  }
}

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

다음과 비슷한 JSON 응답이 표시됩니다.

{
  "overallAccessState": "CANNOT_ACCESS",
  "accessTuple": {
    "principal": "user1@example.com",
    "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
    "permission": "compute.instances.get",
    "permissionFqdn": "compute.googleapis.com/instances.get",
    "conditionContext": {
      "effectiveTags": [
        {
          "tagValue": "tagValues/281481941428044",
          "namespacedTagValue": "803434038361/env/dev",
          "tagKey": "tagKeys/281475994198094",
          "namespacedTagKey": "803434038361/env",
          "tagKeyParentName": "organizations/803434038361"
        }
      ]
    }
  },
  "allowPolicyExplanation": {
    "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
    "explainedPolicies": [
      {
        "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/my-project",
        "bindingExplanations": [
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
            "role": "roles/compute.viewer",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_HIGH"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_HIGH"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "role": "roles/owner",
            "rolePermission": "ROLE_PERMISSION_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
            "combinedMembership": {
              "membership": "MEMBERSHIP_NOT_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user2@example.com": {
                "membership": "MEMBERSHIP_NOT_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL"
          },
          {
            "allowAccessState": "ALLOW_ACCESS_STATE_NOT_GRANTED",
            "role": "roles/resourcemanager.organizationAdmin",
            "rolePermission": "ROLE_PERMISSION_NOT_INCLUDED",
            "rolePermissionRelevance": "HEURISTIC_RELEVANCE_NORMAL",
            "combinedMembership": {
              "membership": "MEMBERSHIP_MATCHED",
              "relevance": "HEURISTIC_RELEVANCE_NORMAL"
            },
            "memberships": {
              "user:user1@example.com": {
                "membership": "MEMBERSHIP_MATCHED",
                "relevance": "HEURISTIC_RELEVANCE_NORMAL"
              }
            },
            "relevance": "HEURISTIC_RELEVANCE_NORMAL"
          }
        ],
        "relevance": "HEURISTIC_RELEVANCE_HIGH",
        "policy": {
          "version": 3,
          "etag": "BwX5/L9Vbg4=",
          "bindings": [
            {
              "role": "roles/compute.viewer",
              "members": [
                "user:user1@example.com"
              ]
            },
            {
              "role": "roles/owner",
              "members": [
                "user:user2@example.com"
              ]
            },
            {
              "role": "roles/resourcemanager.organizationAdmin",
              "members": [
                "user:user1@example.com"
              ]
            },
          ]
        }
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
  },
  "denyPolicyExplanation": {
    "denyAccessState": "DENY_ACCESS_STATE_DENIED",
    "explainedResources": [
      {
        "denyAccessState": "DENY_ACCESS_STATE_DENIED",
        "fullResourceName": "//cloudresourcemanager.googleapis.com/projects/123456789012",
        "explainedPolicies": [
          {
            "denyAccessState": "DENY_ACCESS_STATE_DENIED",
            "policy": {
              "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F123456789012/denypolicies/deny-compute-get",
              "uid": "77e93c80-b383-0027-268e-a52a608aa13d",
              "kind": "DenyPolicy",
              "displayName": "Deny compute instance get",
              "etag": "MTc3MDA1ODIyNjExNTMzMDg2NzI=",
              "createTime": "2023-04-18T07:15:47.702191Z",
              "updateTime": "2023-04-18T07:15:47.702191Z",
              "rules": [
                {
                  "denyRule": {
                    "deniedPrincipals": [
                      "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com"
                    ],
                    "deniedPermissions": [
                      "compute.googleapis.com/instances.get"
                    ]
                  }
                }
              ]
            },
            "ruleExplanations": [
              {
                "denyAccessState": "DENY_ACCESS_STATE_DENIED",
                "combinedDeniedPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPermissions": {
                  "compute.googleapis.com/instances.get": {
                    "permissionMatchingState": "PERMISSION_PATTERN_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "combinedExceptionPermission": {
                  "permissionMatchingState": "PERMISSION_PATTERN_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "combinedDeniedPrincipal": {
                  "membership": "MEMBERSHIP_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "deniedPrincipals": {
                  "principal://iam.googleapis.com/projects/-/serviceAccounts/user1@example.com": {
                    "membership": "MEMBERSHIP_MATCHED",
                    "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                  }
                },
                "combinedExceptionPrincipal": {
                  "membership": "MEMBERSHIP_NOT_MATCHED",
                  "relevance": "HEURISTIC_RELEVANCE_NORMAL"
                },
                "relevance": "HEURISTIC_RELEVANCE_HIGH"
              }
            ],
            "relevance": "HEURISTIC_RELEVANCE_HIGH"
          }
        ],
        "relevance": "HEURISTIC_RELEVANCE_HIGH"
      }
    ],
    "relevance": "HEURISTIC_RELEVANCE_HIGH",
    "permissionDeniable": true
  }
}

문제 해결 도구 결과 이해

콘솔

결과 페이지에는 다음 정보가 포함됩니다.

평가 세부정보

평가 세부정보 섹션에는 지정된 주 구성원, 리소스, 권한을 포함하여 문제를 해결 중인 액세스에 대한 요약이 포함되어 있습니다. 여러 리소스 권한 쌍의 문제를 해결하는 경우 액세스 평가 목록을 사용하여 권한 쌍을 전환할 수 있습니다.

정책 세부정보

정책 세부정보 섹션에는 관련 허용 및 거부 정책이 주 구성원의 액세스에 미치는 영향이 자세히 설명되어 있습니다.

관련 허용 및 거부 정책에는 다음이 포함됩니다.

  • 리소스의 허용 정책
  • 리소스의 거부 정책(있는 경우)
  • 리소스의 상위 프로젝트, 폴더, 조직의 허용 정책(있는 경우)
  • 리소스의 상위 프로젝트, 폴더, 조직의 거부 정책(있는 경우)

상위 프로젝트, 폴더, 조직의 허용 및 거부 정책은 정책 상속으로 인해 관련이 있습니다. 허용 또는 거부 정책을 프로젝트, 폴더 또는 조직에 연결하면 해당 프로젝트, 폴더 또는 조직 내의 모든 리소스에도 정책이 적용됩니다.

예를 들어 조직에 대한 거부 정책에서 주 구성원이 특정 권한을 사용할 수 없다면 주 구성원은 조직 내의 모든 리소스에 해당 권한을 사용할 수 없습니다. 이 규칙은 해당 조직 내 폴더 및 프로젝트에 더 많은 허용 거부 정책이 있거나 주 구성원에게 권한을 부여하는 허용 정책이 있는 경우에도 적용됩니다.

마찬가지로 프로젝트의 허용 정책이 주 구성원에게 특정 권한을 부여하는 경우 주 구성원은 해당 권한이 거부되지 않는 한 프로젝트 내의 모든 리소스에 대한 해당 권한을 가질 수 있습니다.

정책 세부정보 섹션에는 다음 섹션이 포함되어 있습니다.

액세스 상태

액세스 상태 섹션에는 관련 IAM 허용 및 거부 정책에 따른 주 구성원의 액세스 권한에 대한 간략한 요약이 포함되어 있습니다. 이 요약에는 거부 정책의 영향, 허용 정책의 영향, 관련 거부 및 허용 정책에 따른 최종 액세스 결과가 포함됩니다.

거부 정책

거부 정책 섹션에서 모든 관련 거부 정책을 보고, 주 구성원에 대한 액세스 권한을 거부하는 거부 규칙을 식별하고, 거부 규칙이 주 구성원의 권한을 거부하거나 거부하지 않는 이유를 확인할 수 있습니다.

거부 정책과 리소스 창에는 모든 관련 거부 정책이 연결된 리소스별로 정리된 나열됩니다. 각 거부 정책 옆에는 액세스 평가가 있습니다. 이 평가는 거부 정책에만 적용되며 상속된 정책의 액세스는 반영하지 않습니다. 리소스의 거부 정책을 볼 권한이 없으면 리소스 목록에 해당 리소스 또는 거부 정책이 포함되지 않습니다.

이러한 거부 정책에서 관련 거부 규칙을 보려면 거부 정책을 클릭합니다. 리소스의 거부 정책에서 모든 거부 규칙을 보려면 리소스를 클릭합니다. 거부 규칙 창에 거부 규칙이 표시됩니다. 이 창에는 선택한 리소스 또는 거부 정책에 대해 쿼리된 주 구성원 또는 권한과 모든 거부 규칙의 표가 포함됩니다.

액세스 열은 거부 규칙이 주 구성원의 권한을 거부하는지 여부를 나타냅니다. 거부 규칙에 대한 자세한 내용을 보려면 규칙 행에서 거부 규칙 보기를 클릭합니다.

허용 정책

허용 정책 섹션에서 모든 관련 허용 정책을 살펴보고, 주 구성원에 액세스 권한을 부여하는 역할 바인딩을 식별하고, 역할 바인딩이 주 구성원에게 권한을 부여하거나 부여하지 않는 이유를 알아볼 수 있습니다.

리소스 창에는 지정된 리소스와 상위 항목이 나열됩니다. 각 리소스 옆에는 액세스 평가가 있습니다. 이 평가는 리소스의 허용 정책에만 적용되며 상속된 정책의 액세스는 반영하지 않습니다. 리소스의 허용 정책을 볼 권한이 없으면 리소스 목록에 해당 리소스가 포함되지 않습니다.

리소스의 허용 정책에서 관련 역할 바인딩을 보고 주 구성원에게 권한을 부여하는지 여부를 확인하려면 리소스를 클릭합니다. 허용 정책의 바인딩이 역할 바인딩 창에 표시됩니다.

역할 바인딩 창에는 선택한 리소스의 허용 정책에 포함된 역할 바인딩의 표가 포함되어 있습니다. 기본적으로 이 표에는 지정된 권한이 있는 역할이 포함된 역할 바인딩만 있습니다. 주 구성원에게 액세스 권한이 없으면 표에 수정 가능한 커스텀 역할이 있는 역할 바인딩도 표시됩니다. 모든 역할 바인딩을 보려면 관련 바인딩만 표시 체크박스를 선택 취소합니다.

액세스 열은 역할 바인딩이 주 구성원에게 권한을 부여하는지 여부를 나타냅니다. 역할 바인딩에 대한 자세한 내용을 보려면 해당 바인딩 행의 바인딩 세부정보 보기를 클릭합니다.

gcloud

응답에는 요청의 액세스 튜플에 대한 설명, 허용 정책 평가 결과, 거부 정책 평가 결과, 전체 액세스 상태 등 4개의 기본 섹션이 포함됩니다.

  • accessTuple: 사용자가 제공한 조건 컨텍스트를 포함하여 요청의 액세스 튜플에 대한 설명입니다. 이 섹션에는 리소스에 적용되는 태그 요약도 포함되어 있습니다.
  • allowPolicyExplanation: 관련 허용 정책이 주 구성원에게 권한을 부여하는지 여부에 대한 요약이며, 허용 정책 및 역할 바인딩 목록이 뒤에 옵니다.

    각 허용 정책에 대한 응답에는 정책의 모든 역할 바인딩이 나열되고 다음 기준에 따라 평가됩니다.

    • 바인딩에 권한이 포함되어 있는지 여부
    • 바인딩에 주 구성원이 포함되어 있는지 여부
    • 바인딩의 조건(있는 경우)이 충족되는지 여부

    그런 다음 허용 정책의 전체 JSON 텍스트가 출력됩니다.

  • denyPolicyExplanation: 관련 거부 정책이 주 구성원의 권한을 거부하는지 여부에 대한 요약이며, 거부 정책이 있는 리소스 목록이 뒤에 옵니다. 각 리소스에 대한 응답에는 리소스에 연결된 모든 거부 정책이 나열됩니다.

    각 거부 정책에 대한 응답에서는 정책의 메타데이터가 출력되고 정책의 거부 규칙이 나열된 후 다음 기준에 따라 각 규칙이 평가됩니다.

    • 거부 규칙에 권한이 포함되어 있는지 여부
    • 거부 규칙에 권한이 예외로 나열되어 있는지 여부
    • 거부 규칙에 주 구성원이 포함되어 있는지 여부
    • 거부 규칙에 주 구성원이 예외로 나열되어 있는지 여부
    • 거부 규칙의 조건이 충족되었는지 여부(있는 경우)
  • overallAccessState: 주 구성원이 관련 허용 및 거부 정책에 따라 지정된 권한을 사용하여 지정된 리소스에 액세스할 수 있는지 여부입니다.

    관련 허용 및 거부 정책에는 다음이 포함됩니다.

    • 리소스의 허용 정책
    • 리소스의 거부 정책(있는 경우)
    • 리소스의 상위 프로젝트, 폴더, 조직의 허용 정책(있는 경우)
    • 리소스의 상위 프로젝트, 폴더, 조직의 거부 정책(있는 경우)

    상위 프로젝트, 폴더, 조직의 허용 및 거부 정책은 정책 상속으로 인해 관련이 있습니다. 허용 또는 거부 정책을 프로젝트, 폴더 또는 조직에 연결하면 해당 프로젝트, 폴더 또는 조직 내의 모든 리소스에도 정책이 적용됩니다.

    예를 들어 조직에 대한 거부 정책에서 주 구성원이 특정 권한을 사용할 수 없다면 주 구성원은 조직 내의 모든 리소스에 해당 권한을 사용할 수 없습니다. 이 규칙은 해당 조직 내 폴더 및 프로젝트에 더 많은 허용 거부 정책이 있거나 주 구성원에게 권한을 부여하는 허용 정책이 있는 경우에도 적용됩니다.

    마찬가지로 프로젝트의 허용 정책이 주 구성원에게 특정 권한을 부여하는 경우 주 구성원은 해당 권한이 거부되지 않는 한 프로젝트 내의 모든 리소스에 대한 해당 권한을 가질 수 있습니다.

  • 응답의 많은 객체에는 relevance 필드도 있습니다. 이 필드의 값은 객체가 전체 액세스 상태에 기여하는 정도를 나타냅니다. relevance 필드는 다음 값을 가질 수 있습니다.

    • HEURISTIC_RELEVANCE_HIGH: 객체가 결과에 큰 영향을 준다는 것을 나타냅니다. 즉, 객체를 삭제하면 전체 액세스 상태가 변경될 가능성이 높습니다. 예를 들어 주 구성원에게 지정된 권한을 부여하는 역할 바인딩은 이 관련성 값을 갖습니다.

    • HEURISTIC_RELEVANCE_NORMAL: 객체가 결과에 미치는 영향이 제한적임을 나타냅니다. 즉, 객체를 삭제해도 전체 액세스 상태가 변경될 가능성이 낮습니다. 예를 들어 권한이 없거나 주 구성원이 없는 거부 규칙은 이 관련성 값을 갖습니다.

REST

응답에는 전체 액세스 상태, 요청의 액세스 튜플에 대한 설명, 허용 정책 평가 결과, 거부 정책 평가 결과 등 4개의 기본 섹션이 포함됩니다.

  • overallAccessState: 주 구성원이 관련 허용 및 거부 정책에 따라 지정된 권한을 사용하여 지정된 리소스에 액세스할 수 있는지 여부입니다.

    관련 허용 및 거부 정책에는 다음이 포함됩니다.

    • 리소스의 허용 정책
    • 리소스의 거부 정책(있는 경우)
    • 리소스의 상위 프로젝트, 폴더, 조직의 허용 정책(있는 경우)
    • 리소스의 상위 프로젝트, 폴더, 조직의 거부 정책(있는 경우)

    상위 프로젝트, 폴더, 조직의 허용 및 거부 정책은 정책 상속으로 인해 관련이 있습니다. 허용 또는 거부 정책을 프로젝트, 폴더 또는 조직에 연결하면 해당 프로젝트, 폴더 또는 조직 내의 모든 리소스에도 정책이 적용됩니다.

    예를 들어 조직에 대한 거부 정책에서 주 구성원이 특정 권한을 사용할 수 없다면 주 구성원은 조직 내의 모든 리소스에 해당 권한을 사용할 수 없습니다. 이 규칙은 해당 조직 내 폴더 및 프로젝트에 더 많은 허용 거부 정책이 있거나 주 구성원에게 권한을 부여하는 허용 정책이 있는 경우에도 적용됩니다.

    마찬가지로 프로젝트의 허용 정책이 주 구성원에게 특정 권한을 부여하는 경우 주 구성원은 해당 권한이 거부되지 않는 한 프로젝트 내의 모든 리소스에 대한 해당 권한을 가질 수 있습니다.

  • accessTuple: 사용자가 제공한 조건 컨텍스트를 포함하여 요청의 액세스 튜플에 대한 설명입니다. 이 섹션에는 리소스에 적용되는 태그 요약도 포함되어 있습니다.
  • allowPolicyExplanation: 관련 허용 정책이 주 구성원에게 권한을 부여하는지 여부에 대한 요약이며, 허용 정책 및 역할 바인딩 목록이 뒤에 옵니다.

    각 허용 정책에 대한 응답에는 정책의 모든 역할 바인딩이 나열되고 다음 기준에 따라 평가됩니다.

    • 바인딩에 권한이 포함되어 있는지 여부
    • 바인딩에 주 구성원이 포함되어 있는지 여부
    • 바인딩의 조건(있는 경우)이 충족되는지 여부

    그런 다음 허용 정책의 전체 JSON 텍스트가 출력됩니다.

  • denyPolicyExplanation: 관련 거부 정책이 주 구성원의 권한을 거부하는지 여부에 대한 요약이며, 거부 정책이 있는 리소스 목록이 뒤에 옵니다. 각 리소스에 대한 응답에는 리소스에 연결된 모든 거부 정책이 나열됩니다.

    각 거부 정책에 대한 응답에서는 정책의 메타데이터가 출력되고 정책의 거부 규칙이 나열된 후 다음 기준에 따라 각 규칙이 평가됩니다.

    • 거부 규칙에 권한이 포함되어 있는지 여부
    • 거부 규칙에 권한이 예외로 나열되어 있는지 여부
    • 거부 규칙에 주 구성원이 포함되어 있는지 여부
    • 거부 규칙에 주 구성원이 예외로 나열되어 있는지 여부
    • 거부 규칙의 조건이 충족되었는지 여부(있는 경우)
  • 응답의 많은 객체에는 relevance 필드도 있습니다. 이 필드의 값은 객체가 전체 액세스 상태에 기여하는 정도를 나타냅니다. relevance 필드는 다음 값을 가질 수 있습니다.

    • HEURISTIC_RELEVANCE_HIGH: 객체가 결과에 큰 영향을 준다는 것을 나타냅니다. 즉, 객체를 삭제하면 전체 액세스 상태가 변경될 가능성이 높습니다. 예를 들어 주 구성원에게 지정된 권한을 부여하는 역할 바인딩은 이 관련성 값을 갖습니다.

    • HEURISTIC_RELEVANCE_NORMAL: 객체가 결과에 미치는 영향이 제한적임을 나타냅니다. 즉, 객체를 삭제해도 전체 액세스 상태가 변경될 가능성이 낮습니다. 예를 들어 권한이 없거나 주 구성원이 없는 거부 규칙은 이 관련성 값을 갖습니다.

조건부 역할 바인딩 문제 해결

정책 문제 해결 도구는 태그를 기준으로 조건부 역할 바인딩 및 거부 규칙 문제를 자동으로 해결합니다. 그러나 정책 문제 해결 도구가 다른 종류의 조건부 역할 바인딩 또는 조건부 거부 규칙 문제를 해결하려면 요청에 대한 추가 컨텍스트가 필요합니다. 예를 들어 날짜/시간 속성을 기반으로 한 조건 문제를 해결하려면 정책 문제 해결 도구에 요청 시간이 필요합니다.

gcloud CLI 및 REST API에서는 이 추가 컨텍스트를 수동으로 제공합니다.

Google Cloud 콘솔의 관리자 활동 감사 로그 또는 데이터 액세스 감사 로그에서 직접 문제 해결을 수행하여 이 추가 컨텍스트를 제공할 수 있습니다. 각 감사 로그 항목은 Google Cloud API에 대한 요청 또는 Google Cloud에서 사용자 대신 수행하는 작업에 해당합니다. 감사 로그에서 문제를 해결할 때 정책 문제 해결 도구는 요청에 대한 추가 정보(예: 날짜 및 시간)를 자동으로 가져와서 정책 문제 해결 도구가 조건부 역할 바인딩 및 거부 규칙을 분석할 수 있도록 합니다.

콘솔

조건부 역할 바인딩 및 거부 규칙 문제를 해결하려면 다음을 수행합니다.

  1. Google Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.

    로그 탐색기로 이동

  2. 페이지 제목이 기존 로그 뷰어인 경우 업그레이드 드롭다운 목록을 클릭하고 새 로그 탐색기로 업그레이드를 선택합니다.

  3. 관리자 활동 및 데이터 액세스 감사 로그만 보려면 쿼리 빌더에 다음 쿼리를 입력한 다음 쿼리 실행을 클릭합니다.

    logName=("RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity" OR "RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Fdata_access")
    

    다음 값을 바꿉니다.

    • RESOURCE_TYPE: 감사 로그를 나열하는 리소스 유형입니다. projects, folders, organizations을 사용합니다.
    • RESOURCE_ID: 리소스 ID입니다.
  4. 문제를 해결할 요청에 해당하는 감사 로그 항목을 찾습니다. 로그 탐색기를 사용하여 특정 로그 항목을 찾는 방법은 로그 탐색기 사용을 참조하세요.

  5. 로그 항목의 요약 열에서 IAM을 클릭한 후 액세스 문제 해결을 클릭합니다.

    정책 문제 해결 도구는 로그 항목의 정보를 사용하여 액세스 문제를 해결한 다음 결과를 표시합니다. 추가 컨텍스트는 조건 컨텍스트의 평가 세부정보에 나열됩니다. 컨텍스트 세부정보를 보려면 조건 컨텍스트 보기를 클릭합니다. 정책 문제 해결 도구 결과 페이지에 대해 자세히 알아보려면 이 페이지의 액세스 문제 해결을 참조하세요.

  6. 선택사항: 조건부 역할 바인딩 및 거부 규칙과 관련된 다른 요청의 문제를 해결하려면 로그 탐색기 페이지로 돌아가서 이전 단계를 반복합니다.

gcloud

조건부 역할 바인딩 및 거부 규칙 문제를 해결하려면 gcloud policy-troubleshoot iam 명령어를 사용합니다.

아래의 명령어 데이터를 사용하기 전에 다음을 바꿉니다.

  • EMAIL: 권한 문제를 해결하려는 주 구성원의 이메일 주소입니다.
  • RESOURCE: 권한이 부여된 리소스입니다.
  • PERMISSION: 문제를 해결하려는 권한입니다.
  • DESTINATION_IP: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 요청 대상 IP 주소입니다. 예를 들면 198.1.1.1입니다.
  • DESTINATION_PORT: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 요청 대상 포트입니다. 예를 들어 `8080`입니다.
  • REQUEST_TIME: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 요청 타임스탬프입니다. RFC3339 형식의 타임스탬프를 사용합니다(예: 2099-02-01T00:00:00Z).
  • RESOURCE_NAME: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 리소스 이름 값입니다. 허용되는 리소스 이름 형식 목록은 리소스 이름 형식을 참조하세요.
  • RESOURCE_SERVICE: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 리소스 서비스 값입니다. 허용되는 서비스 이름 목록은 리소스 서비스 값을 참조하세요.
  • RESOURCE_TYPE: 선택사항. 허용되는 리소스 유형 목록은 리소스 유형 값을 참조하세요.

gcloud policy-troubleshooter iam 명령어를 실행합니다.

Linux, macOS 또는 Cloud Shell

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL \
    --permission=PERMISSION --destination-ip=DESTINATION_IP \
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME \
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE \
    --resource-type=RESOURCE_TYPE

Windows(PowerShell)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL `
    --permission=PERMISSION --destination-ip=DESTINATION_IP `
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME `
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE `
    --resource-type=RESOURCE_TYPE

Windows(cmd.exe)

gcloud policy-intelligence troubleshoot-policy iam RESOURCE --principal-email=EMAIL ^
    --permission=PERMISSION --destination-ip=DESTINATION_IP ^
    --destination-port=DESTINATION_PORT --request-time=REQUEST_TIME ^
    --resource-name=RESOURCE_NAME --resource-service=RESOURCE_SERVICE ^
    --resource-type=RESOURCE_TYPE

응답에는 주 구성원의 액세스에 대한 설명이 포함됩니다. 조건이 있는 각 역할 바인딩 및 거부 규칙에 대한 응답에는 제공된 조건 컨텍스트를 기준으로 조건이 true 또는 false로 평가되는지 여부를 설명하는 conditionExplanation 필드가 포함됩니다.

예를 들어 다음은 리소스 유형 및 리소스 서비스를 지정하는 조건을 가진 역할 바인딩에 대한 평가입니다.

...
{
  "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
  "combinedMembership": {
    "membership": "MEMBERSHIP_MATCHED",
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "condition": {
    "expression": " resource.type \u003d\u003d \"compute.googleapis.com/Instance\" \u0026\u0026 resource.service \u003d\u003d \"compute.googleapis.com\"",
    "title": "Compute instances only",
    "description": "Condition that limits permissions to only Compute instances"
  },
  "conditionExplanation": {
    "evaluationStates": [{
      "end": 51,
      "start": 1,
      "value": true
    }, {
      "end": 99,
      "start": 55,
      "value": true
    }],
    "value": true,
  },
  "memberships": {
    "user:my-user@example.com": {
      "membership": "MEMBERSHIP_MATCHED",
      "relevance": "HEURISTIC_RELEVANCE_HIGH"
    }
  },
  "relevance": "HEURISTIC_RELEVANCE_HIGH",
  "role": "roles/compute.viewer",
  "rolePermission": "ROLE_PERMISSION_INCLUDED",
  "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH"
}
...

REST

조건부 역할 바인딩 및 거부 규칙의 문제를 해결하려면 Policy Troubleshooter API의 iam.troubleshoot 메서드를 사용합니다.

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

  • EMAIL: 권한 문제를 해결하려는 주 구성원의 이메일 주소입니다.
  • RESOURCE: 권한이 부여된 리소스입니다.
  • PERMISSION: 문제를 해결하려는 권한입니다.
  • DESTINATION_IP: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 요청 대상 IP 주소입니다. 예를 들면 198.1.1.1입니다.
  • DESTINATION_PORT: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 요청 대상 포트입니다. 예를 들어 `8080`입니다.
  • REQUEST_TIME: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 요청 타임스탬프입니다. RFC3339 형식의 타임스탬프를 사용합니다(예: 2099-02-01T00:00:00Z).
  • RESOURCE_NAME: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 리소스 이름 값입니다. 허용되는 리소스 이름 형식 목록은 리소스 이름 형식을 참조하세요.
  • RESOURCE_SERVICE: 선택사항. 조건부 역할 바인딩을 확인할 때 사용할 리소스 서비스 값입니다. 허용되는 서비스 이름 목록은 리소스 서비스 값을 참조하세요.
  • RESOURCE_TYPE: 선택사항. 허용되는 리소스 유형 목록은 리소스 유형 값을 참조하세요.

HTTP 메서드 및 URL:

POST https://policytroubleshooter.googleapis.com/v3/iam:troubleshoot

JSON 요청 본문:

{
  "accessTuple": {
    "principal": "EMAIL",
    "fullResourceName": "RESOURCE",
    "permission": "PERMISSION",
    "conditionContext": {
      "destination": {
        "ip": DESTINATION_IP,
        "port": DESTINATION_PORT
      },
      "request": {
        "receiveTime": REQUEST_TIME
      },
      "resource": {
        "name": RESOURCE_NAME,
        "service": RESOURCE_SERVICE,
        "type": RESOURCE_TYPE
      }
    }
  }
}

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

응답에는 주 구성원의 액세스에 대한 설명이 포함됩니다. 조건이 있는 각 역할 바인딩 및 거부 규칙에 대한 응답에는 제공된 조건 컨텍스트를 기준으로 조건이 true 또는 false로 평가되는지 여부를 설명하는 conditionExplanation 필드가 포함됩니다.

예를 들어 다음은 리소스 유형 및 리소스 서비스를 지정하는 조건을 가진 역할 바인딩에 대한 평가입니다.

...
{
  "allowAccessState": "ALLOW_ACCESS_STATE_GRANTED",
  "role": "roles/compute.viewer",
  "rolePermission": "ROLE_PERMISSION_INCLUDED",
  "rolePermissionRelevance": "HEURISTIC_RELEVANCE_HIGH",
  "combinedMembership": {
    "membership": "MEMBERSHIP_MATCHED",
    "relevance": "HEURISTIC_RELEVANCE_HIGH"
  },
  "memberships": {
    "user:my-user@example.com": {
      "membership": "MEMBERSHIP_MATCHED",
      "relevance": "HEURISTIC_RELEVANCE_HIGH"
    }
  },
  "relevance": "HEURISTIC_RELEVANCE_HIGH",
  "condition": {
    "expression": " resource.type \u003d\u003d \"compute.googleapis.com/Instance\" \u0026\u0026 resource.service \u003d\u003d \"compute.googleapis.com\"",
    "title": "Compute instances only",
    "description": "Condition that limits permissions to only Compute instances"
  },
  "conditionExplanation": {
    "value": true,
    "evaluationStates": [{
      "start": 1,
      "end": 51,
      "value": true
    }, {
      "start": 55,
      "end": 99,
      "value": true
    }]
  }
}
...

다음 단계