거부 정책

Identity and Access Management(IAM) 거부 정책을 사용하면 Google Cloud 리소스에 대한 액세스에 가드레일을 설정할 수 있습니다. 거부 정책을 사용하면 부여된 역할에 관계없이 특정 주 구성원이 특정 권한을 사용하지 못하게 하는 거부 규칙을 정의할 수 있습니다.

이 페이지에서는 거부 정책과 거부 규칙을 간략히 설명합니다. 거부 정책을 만들고 업데이트하는 방법은 리소스에 대한 액세스 거부를 참조하세요.

거부 정책 작동 방식

거부 정책은 거부 규칙으로 구성됩니다. 각 거부 규칙은 다음을 지정합니다.

  • 권한이 거부된 주 구성원 집합
  • 주 구성원이 거부되거나 사용할 수 없는 권한
  • 선택사항: 권한이 거부되기 위해 true여야 하는 조건

주 구성원이 권한을 거부당하면 부여된 IAM 역할에 관계없이 해당 권한이 필요한 작업을 수행할 수 없습니다. 이는 IAM이 관련 허용 정책을 확인하기 전에 항상 관련 거부 정책을 검사하기 때문입니다. 자세한 내용은 정책 평가를 참조하세요.

거부 정책을 적용할 위치를 지정하려면 이를 프로젝트, 폴더 또는 조직에 연결합니다. 거부 정책이 이러한 리소스 중 하나에 연결되면 정책의 주 구성원은 리소스 또는 리소스의 하위 항목에 액세스하기 위해 지정된 권한을 사용할 수 없습니다. 거부 정책을 연결할 수 있는 위치에 대해 자세히 알아보려면 이 페이지의 연결 지점을 참고하세요.

단일 리소스에 여러 거부 정책을 연결할 수 있습니다. 이를 통해 다양한 유형의 거부 규칙에 별도의 거부 정책을 만들 수 있습니다. 예를 들어 한 정책에 규정 준수 관련 거부 규칙을 넣은 후 다른 거부 규칙에 다른 정책을 사용할 수 있습니다. 각 거부 정책은 다른 모든 거부 정책과 독립적으로 평가됩니다.

각 리소스에 거부 정책을 최대 500개까지 사용할 수 있습니다. 이러한 거부 정책은 거부 규칙을 총 500개까지 포함할 수 있습니다.

연결 지점

각 거부 정책은 조직, 폴더 또는 프로젝트에 연결됩니다. 이러한 리소스 중 하나에 연결되면 거부 정책은 해당 프로젝트, 폴더 또는 조직의 모든 하위 수준 리소스에 상속됩니다. 거부 정책을 사용하려면 거부 정책이 연결된 리소스의 식별자가 필요합니다. 이를 연결 지점이라고 합니다. 이 식별자는 다음 표의 형식 중 하나를 사용합니다.

연결 지점 형식
조직

cloudresourcemanager.googleapis.com/organizations/ORG_ID
ORG_ID를 숫자 조직 ID로 바꿉니다. REST API의 경우 전체 값을 URL로 인코딩합니다.

gcloud CLI의 예시는 다음과 같습니다.
cloudresourcemanager.googleapis.com/organizations/123456789012

REST API의 예시는 다음과 같습니다.
cloudresourcemanager.googleapis.com%2Forganizations%2F123456789012

폴더

cloudresourcemanager.googleapis.com/folders/FOLDER_ID
FOLDER_ID를 숫자 폴더 ID로 바꿉니다. REST API의 경우 전체 값을 URL로 인코딩합니다.

gcloud CLI의 예시는 다음과 같습니다.
cloudresourcemanager.googleapis.com/folders/987654321098

REST API의 예시는 다음과 같습니다.
cloudresourcemanager.googleapis.com%2Ffolders%2F987654321098

프로젝트

cloudresourcemanager.googleapis.com/projects/PROJECT_ID
PROJECT_ID를 영숫자 또는 숫자 프로젝트 ID로 바꿉니다. REST API의 경우 전체 값을 URL로 인코딩합니다.

gcloud CLI의 예시는 다음과 같습니다.
cloudresourcemanager.googleapis.com/projects/my-project

REST API의 예시는 다음과 같습니다.
cloudresourcemanager.googleapis.com%2Fprojects%2Fmy-project

거부 정책 상속

허용 정책과 같은 거부 정책은 리소스 계층 구조를 통해 상속됩니다. 거부 정책을 프로젝트, 폴더 또는 조직에 연결하면 정책이 해당 프로젝트, 폴더 또는 조직 내의 모든 리소스에도 적용됩니다.

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

마찬가지로프로젝트에 대한 거부 정책에서 주 구성원이 특정 권한을 사용할 수 없다면 주 구성원은 프로젝트 내의 모든 리소스를 찾습니다. 상위 조직 및 폴더에 더 많은 허용 거부 정책이 있는 경우에도 이 규칙이 적용됩니다.

거부 조건

거부 조건은 거부 규칙이 적용되기 위해 충족해야 하는 조건을 지정합니다. 조건이 true로 평가되거나 평가될 수 없으면 거부 규칙이 적용되고 주 구성원은 지정된 권한을 사용할 수 없습니다. 조건이 false로 평가되면 거부 규칙이 적용되지 않으며 주 구성원은 지정된 권한이 있으면 지정된 권한을 사용할 수 있습니다.

거부 조건 구조는 IAM 조건 구조와 동일합니다. 그러나 거부 조건에서는 리소스 태그 함수만 인식합니다.

조건을 작성하는 방법은 IAM 조건 개요를 참조하세요.

권한 그룹

일부 서비스를 사용하면 권한 그룹을 거부할 수 있습니다. 권한 그룹은 지정된 패턴과 일치하는 권한 집합입니다. 권한 그룹을 사용하여 관련 권한 집합을 거부할 수 있습니다. 예를 들어 단일 서비스나 리소스에 대한 모든 권한을 거부할 수 있습니다.

지원되는 권한 그룹은 거부 정책에서 지원되는 권한에 나열되어 있습니다. 지원되는 권한 그룹의 식별자는 권한 이름의 섹션 하나 이상을 와일드 카드 문자(*)로 바꿉니다. 각 그룹에 포함된 권한은 와일드 카드의 위치에 따라 다릅니다.

  • SERVICE_FQDN/RESOURCE.*: 지정된 리소스의 모든 권한을 거부합니다.
  • SERVICE_FQDN/*.*: 지정된 서비스의 모든 권한을 거부합니다.
  • SERVICE_FQDN/*.VERB: 지정된 동사로 끝나는 서비스의 모든 권한을 거부합니다.

권한 그룹에는 지정된 패턴과 일치하는 현재 및 미래의 모든 권한이 포함됩니다. 예를 들어 권한 그룹 example.googleapis.com/exampleResource.*를 사용하여 사용자가 exampleResource 리소스 유형에 대한 모든 권한을 거부한다고 가정해 보겠습니다. example.googleapis.com에서 example.googleapis.com/exampleResource.newPermission과 같은 exampleResource 리소스 유형에 대한 새로운 권한을 추가하면 사용자는 자동으로 새 권한을 거부합니다.

지원되는 권한 그룹에서만 와일드 카드를 사용할 수 있습니다. 다른 권한 이름에는 와일드 카드를 사용할 수 없습니다.

거부 정책의 구조

거부 정책은 메타데이터와 거부 규칙 모음입니다. 거부 규칙은 주 구성원 집합을 주 구성원이 거부되거나 사용할 수 없는 권한 집합과 연결합니다. 각 규칙에서는 권한이 거부되는 시기를 결정하는 조건도 지정할 수 있습니다.

예를 들어 다음 거부 정책은 주 구성원이 project-admins 그룹의 구성원이거나 삭제할 프로젝트에 test 값이 있는 태그가 없는 한 모든 주 구성원이 프로젝트를 삭제할 수 없게 차단합니다.

{
  "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F253519172624/denypolicies/limit-project-deletion",
  "uid": "06ccd2eb-d2a5-5dd1-a746-eaf4c6g3f816",
  "kind": "DenyPolicy",
  "displayName": "Only project admins can delete projects.",
  "etag": "MTc1MTkzMjY0MjUyMTExODMxMDQ=",
  "createTime": "2021-09-07T23:15:35.258319Z",
  "updateTime": "2021-09-07T23:15:35.258319Z",
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": [
          "principalSet://goog/public:all"
        ],
        "exceptionPrincipals": [
          "principalSet://goog/group/project-admins@example.com"
        ],
        "deniedPermissions": [
          "cloudresourcemanager.googleapis.com/projects.delete",
          "cloudresourcemanager.googleapis.com/folders.*"
        ],
        "exceptionPermissions": [
          "cloudresourcemanager.googleapis.com/folders.list",
          "cloudresourcemanager.googelapis.com/folders.get"
        ],
        "denialCondition": {
          "title":  "Only for non-test projects",
          "expression": "!resource.matchTag('12345678/env', 'test')"
        }
      }
    }
  ]
}

다음 섹션에서는 거부 정책의 메타데이터 및 거부 규칙의 필드를 설명합니다.

메타데이터

거부 정책에는 다음 메타데이터가 포함됩니다.

  • name: 거부 정책의 이름. 이 이름의 형식은 policies/ATTACHMENT_POINT/denypolicies/POLICY_ID로, 여기서 ATTACHMENT_POINT는 거부 정책이 연결된 프로젝트, 폴더 또는 조직이며 POLICY_ID는 거부 정책의 영숫자 ID입니다.
  • uid: Google에서 거부 정책에 할당한 고유 ID입니다.
  • kind: 정책의 유형. 거부 정책의 kind는 항상 DenyPolicy입니다.
  • displayName: 선택사항. 인간이 읽을 수 있는 거부 정책 이름입니다.
  • etag: 정책 버전 식별자입니다. 업데이트 충돌을 방지하려면 etag 값이 IAM에 저장된 값과 일치해야 합니다. etag 값이 일치하지 않으면 요청이 실패합니다.
  • createTime: 거부 정책이 생성된 시간입니다.
  • updateTime: 거부 정책이 마지막으로 업데이트된 시간입니다.

거부 규칙

각 거부 규칙에는 다음 필드가 포함될 수 있습니다.

  • deniedPrincipals: 권한이 거부된 주 구성원입니다. 개별 주 구성원과 주 구성원 집합을 나열할 수 있습니다. 개별 주 구성원 유형에는 사용자 계정, 서비스 계정, 직원 또는 워크로드 아이덴티티 풀의 단일 ID가 포함됩니다. 주 구성원 집합에는 Google 그룹스, Cloud ID 도메인, 직원 또는 워크로드 아이덴티티 집합, 인터넷의 모든 사용자가 포함됩니다.

    유효한 주 구성원 유형 및 식별자 목록은 IAM V2 API 주 구성원 식별자를 참조하세요.

  • exceptionPrincipals: (선택사항) 거부 규칙에서 제외된 주 구성원입니다. 이러한 주 구성원은 deniedPrincipals에 나열되거나 deniedPrincipals에 나열된 그룹에 속하더라도 지정된 권한이 거부되지 않습니다.

    개별 주 구성원과 주 구성원 집합을 나열할 수 있습니다. 개별 주 구성원 유형에는 사용자 계정, 서비스 계정, 직원 또는 워크로드 아이덴티티 풀의 단일 ID가 포함됩니다. 주 구성원 집합에는 Google 그룹스, Cloud ID 도메인, 직원 또는 워크로드 아이덴티티 집합, 인터넷의 모든 사용자가 포함됩니다.

    유효한 주 구성원 유형 및 식별자 목록은 IAM V2 API 주 구성원 식별자를 참조하세요.

  • deniedPermissions: 지정된 주 구성원이 사용할 수 없거나 거부된 권한입니다. 이러한 권한에서는 정규화된 도메인 이름(FQDN)을 사용하여 서비스를 식별하는 IAM v2 권한 형식을 사용합니다. 형식은 SERVICE_FQDN/RESOURCE.ACTION입니다. Google API에서는 *.googleapis.com 도메인을 사용합니다. 예를 들면 iam.googleapis.com/roles.delete입니다.

    일부 권한만 거부할 수 있습니다. 거부할 수 있는 권한의 전체 목록은 거부 정책에서 지원되는 권한을 참조하세요.

    경우에 따라 권한 그룹을 사용하여 권한 집합을 거부할 수도 있습니다. 자세한 내용은 권한 그룹을 참조하세요.

  • exceptionPermissions: 선택사항. 지정된 주 구성원이 사용할 수 있는 권한 목록입니다(권한이 deniedPermissions에 포함된 경우에도 해당). 예를 들어 이 필드를 사용하여 권한 그룹의 특정 권한에 대한 예외를 설정할 수 있습니다.

  • denialConditions: 선택사항. 거부 규칙이 적용되는 시기에 영향을 주는 논리 표현식입니다. 조건이 true로 평가되거나 평가될 수 없으면 권한이 거부됩니다. 조건이 false로 평가되면 권한이 거부되지 않습니다. 자세한 내용은 이 페이지의 거부 조건을 참조하세요.

일반 사용 사례

다음은 거부 정책을 사용하려는 일반적인 상황과 각 상황에서 만들 수 있는 거부 규칙의 예시입니다. 거부 정책을 만들고 업데이트하는 방법은 리소스에 대한 액세스 거부를 참조하세요.

관리자 권한 중앙화

거부 정책을 사용하여 특정 유형의 관리 활동을 특정 주 구성원 집합으로 제한할 수 있습니다.

예를 들어 조직의 커스텀 역할 관리를 단일 중앙팀으로 제한한다고 가정해 보겠습니다. 이렇게 하려면 관리 그룹(custom-role-admins)의 사용자를 제외하고 모든 사용자에 대한 커스텀 역할 관리에 필요한 권한을 거부하는 거부 규칙을 만듭니다.

{
  "deniedPrincipals": [
    "principalSet://goog/public:all"
  ],
  "exceptionPrincipals": [
    "principalSet://goog/group/custom-role-admins@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/roles.create",
    "iam.googleapis.com/roles.delete",
    "iam.googleapis.com/roles.update",
  ]
}

그런 다음 거부 정책을 조직에 연결합니다.

이제 다른 사용자에게 필요한 권한이 있어도 custom-role-admins 그룹의 구성원만 커스텀 역할을 관리할 수 있습니다.

예를 들어 유리와 탈에 모두 조직 역할 관리자 역할 (roles/iam.organizationRoleAdmin)이 있다고 가정해 보겠습니다. 그러나 유리는 custom-role-admins의 구성원이지만 탈은 그렇지 않습니다. 이 거부 정책을 사용하면 유리만 역할을 생성, 삭제, 업데이트할 수 있습니다.

액세스 권한 부여에 대한 예외 만들기

거부 정책을 사용하여 상속된 권한을 거부할 수 있습니다. 이 기능을 사용하면 리소스 계층 구조의 상위 수준에서 역할을 부여한 후 필요한 경우 개별 하위 수준 리소스에 대한 역할 권한을 거부할 수 있습니다.

예를 들어 프로젝트가 여러 개 포함된 Engineering 폴더가 있다고 가정해 보겠습니다. 폴더 내 거의 모든 프로젝트에 대한 서비스 계정 키 관리자 역할(roles/iam.serviceAccountKeyAdmin)의 eng 권한을 그룹에게 부여하려고 합니다. 하지만 이 그룹에게 example-prod 폴더의 특정 프로젝트 하나에서 서비스 계정 키를 만들고 삭제할 수 있는 권한을 부여하지 않으려고 합니다.

각 개별 프로젝트에 대해 서비스 계정 키 관리자 역할을 부여하는 대신 eng 그룹의 주 구성원에 대한 서비스 계정 키 관리자 역할의 생성 및 삭제 권한을 거부하는 다음 거부 규칙을 생성합니다.

{
  "deniedPrincipals": [
    "principalSet://goog/group/eng@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/serviceAccountKeys.create",
    "iam.googleapis.com/serviceAccountKeys.delete"
  ]
}

그런 다음 이 거부 규칙을 거부 정책에 추가하고 example-prod 프로젝트에 정책을 연결합니다.

프로젝트에 거부 정책을 연결한 후 그룹이 example-prod에서 서비스 계정 키를 생성하거나 삭제하게 하지 않고 Engineering 폴더의 eng 그룹에 서비스 계정 키 관리자 역할을 부여할 수 있습니다.

그러면 eng 그룹의 구성원은 example-prod를 제외한 모든 프로젝트에서 서비스 계정 키를 만들고 삭제할 수 있습니다. 예를 들어 이즈미가 eng 그룹의 구성원인 경우 example-devexample-test에서 서비스 계정의 키를 만들고 삭제할 수 있지만 example-prod에서는 그렇지 않습니다.

하지만 실제로 eng 그룹의 하위 집합이 example-prod에서 서비스 계정 키를 만들고 삭제할 수 있게 하려고 한다고 가정해 보겠습니다. 이 하위 집합은 eng-prod 그룹으로 표시됩니다. eng-prod 그룹의 구성원이 example-prod에서 서비스 계정 키를 만들고 삭제하도록 허용하려면 그룹을 거부 규칙에서 제외하면 됩니다.

{
  "deniedPrincipals": [
    "principalSet://goog/group/eng@example.com"
  ],
  "exceptionPrincipals": [
    "principalSet://goog/group/eng-prod@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/serviceAccountKeys.create",
    "iam.googleapis.com/serviceAccountKeys.delete"
  ]
}

이 수정된 거부 정책을 통해 eng-prod 그룹의 구성원은 example-prod를 포함한 모든 프로젝트에서 서비스 계정 키를 만들고 삭제할 수 있습니다. 예를 들어 찰리가 eng-prod 그룹의 구성원인 경우 eng 그룹의 구성원인 경우에도 example-dev, example-test, example-prod에서 키를 만들고 삭제할 수 있습니다.

태그를 기반으로 액세스 차단

태그는 조직, 폴더 또는 프로젝트에 연결할 수 있는 키-값 쌍입니다. 거부 정책을 사용하면 모든 역할 부여에 IAM 조건을 추가하지 않고도 태그를 기반으로 권한을 거부할 수 있습니다.

예를 들어 모든 프로젝트에 dev, test 또는 prod로 태그를 지정한다고 가정해 보겠습니다. project-admins 그룹의 구성원만 prod 태그가 지정된 프로젝트를 삭제할 수 있게 하려 합니다.

이 문제를 해결하려면 prod 태그가 지정된 리소스의 project-admins 그룹을 제외한 모든 사용자에 대한 cloudresourcemanager.googleapis.com/projects.delete 권한을 거부하는 거부 규칙을 만듭니다.

{
  "displayName": "Only project admins can delete production projects.",
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": [
          "principalSet://goog/public:all"
        ],
        "exceptionPrincipals": [
          "principalSet://goog/group/project-admins@example.com"
        ],
        "deniedPermissions": [
          "cloudresourcemanager.googleapis.com/projects.delete"
        ],
        "denialCondition": {
          "title":  "Only for prod projects",
          "expression": "resource.matchTag('12345678/env', 'prod')"
        }
      }
    }
  ]
}

그런 다음 이 거부 규칙을 거부 정책에 추가하고 정책을 조직에 연결합니다.

이 거부 규칙을 사용하면 역할 부여에 조건을 추가하지 않고도 주 구성원의 액세스를 제한할 수 있습니다. 대신 cloudresourcemanager.googleapis.com/projects.delete 권한이 포함된 주 구성원 역할을 부여하고 거부 규칙을 사용하여 project-admins 그룹 외부의 주 구성원이 prod 태그가 지정된 프로젝트를 삭제하지 못하게 할 수 있습니다.

예를 들어 볼라와 키란이라는 두 명의 사용자가 있다고 가정해 보겠습니다. 두 사용자 모두 프로젝트 삭제자 역할 (roles/resourcemanager.projectDeleter)을 가집니다. 또한 키란은 project-admins 그룹의 구성원입니다. 이 거부 정책을 사용하면 볼라가 dev 또는 test 태그가 있는 프로젝트만 삭제할 수 있습니다. 키란은 태그에 관계없이 모든 프로젝트를 삭제할 수 있습니다.

다음 단계