정책 이해

Google Cloud 리소스의 액세스 제어는 IAM 정책에 의해 관리됩니다. IAM 정책은 리소스에 연결됩니다. 정책은 정책 상속을 통해 리소스 자체 및 모든 하위 리소스에 대한 액세스를 관리합니다.

이 주제에서는 IAM 정책의 JSON 예시를 제공합니다. 단, YAML도 지원됩니다.

정책 구조

정책은 binding, 감사 구성, 메타데이터의 모음입니다. binding은 리소스에 액세스 권한을 부여하는 방법을 지정하며, 역할이 부여되는 방법 및 시기를 변경하는 컨텍스트 특정 조건과 단일 역할을 1명 이상의 구성원과 연결합니다. AuditConfig 필드는 액세스 시도를 감사해야 하는 방법에 대한 구성 데이터를 지정합니다. 메타데이터에는 etag버전 같이 정책 관리를 용이하게 하는 정책 관련 추가 정보가 포함됩니다. 각 요소는 아래에 설명되어 있습니다.

  • binding 목록. 각 binding에는 다음 필드가 포함됩니다.
    • ID 또는 주 구성원이라고도 하는 구성원은 사용자 계정, 서비스 계정, Google 그룹 또는 도메인일 수 있습니다.
    • 역할은 이름이 지정된 권한 모음으로 Google Cloud 리소스에서 작업을 수행하는 데 필요한 액세스 권한을 부여합니다.
    • 조건은 요청의 원본, 대상 리소스 등 속성 기반의 역할 결합을 추가로 제한하는 논리 표현식입니다. 일반적으로 조건은 요청의 컨텍스트에 따라 액세스 권한을 부여할지 여부를 제어하는 데 사용됩니다.
  • AuditConfig 필드. 정책의 감사 로깅을 구성하는 데 사용됩니다.
  • 메타데이터에는 다음 필드가 포함됩니다.
    • 동시 실행 제어에 사용되는 etag 필드를 사용하면 정책을 일관성 있게 업데이트할 수 있습니다.
    • version 필드는 특정 정책에 대한 스키마 버전을 지정합니다. version 필드 사용은 정책 버전 섹션에서 좀 더 자세히 설명합니다.

IAM 정책의 역할 결합은 역할과 구성원 목록의 조합입니다. 역할 결합에 조건이 포함된 경우 조건부 역할 결합이라고 합니다.

정책에서 ETag 사용

여러 시스템에서 동시에 동일한 IAM 정책에 쓰기를 시도하면 서로 다른 시스템의 변경사항을 덮어쓸 수 있습니다. 이 위험은 IAM 정책 업데이트에 여러 작업이 관련되어 있기 때문에 발생합니다.

  1. 기존 정책 읽기
  2. 정책 수정
  3. 전체 정책 쓰기

시스템 A가 정책을 읽고 시스템 B가 해당 정책의 업데이트된 버전을 즉시 쓰면 시스템 A는 시스템 B의 변경사항을 인식하지 못합니다. 시스템 A가 정책에 대한 자체 변경사항을 쓰면 시스템 B의 변경사항이 손실될 수 있습니다.

이 문제를 방지하기 위해 ID 및 액세스 관리(IAM)가 정책의 etag 필드를 사용하여 동시 실행 제어를 지원합니다. 이 필드의 값은 정책이 업데이트될 때마다 변경됩니다.

정책을 업데이트해야 할 때마다 업데이트된 정책을 쓸 때 etag 필드를 포함해야 합니다. 검색 이후에 정책이 수정된 경우 etag 값이 일치하지 않으므로 업데이트가 실패합니다. REST API의 경우 HTTP 상태 코드 409 Conflict가 수신되며 응답 본문은 다음과 유사합니다.

{
  "error": {
    "code": 409,
    "message": "There were concurrent policy changes. Please retry the whole read-modify-write with exponential backoff.",
    "status": "ABORTED"
  }
}

이 오류가 발생하면 정책을 다시 읽고, 필요한 경우 수정한 다음 업데이트된 정책을 쓰는 등 전체 작업을 다시 시도해야 합니다. IAM 정책을 관리하는 데 사용하는 모든 도구에서 지수 백오프를 사용하여 자동으로 재시도를 수행해야 합니다.

읽기-수정-쓰기 패턴을 사용하여 정책을 업데이트하는 방법을 알아보려면 액세스 권한 부여, 변경, 취소를 참조하세요.

예시: 간단한 정책

다음 정책 예시는 구성원을 역할에 연결하는 방법을 보여줍니다.

{
  "bindings": [
    {
      "members": [
        "user:jie@example.com"
      ],
      "role": "roles/owner"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 1
}

위의 예시에서 jie@example.com은 조건 없이 소유자 기본 역할을 부여받습니다. 이 역할은 jie@example.com에 무제한 액세스 권한을 제공합니다.

예시: 여러 binding이 포함된 정책

다음 정책 예시는 2개 이상의 binding을 포함하는 방법을 보여줍니다. 각 binding은 서로 다른 역할을 부여합니다.

{
  "bindings": [
    {
      "members": [
        "user:jie@example.com"
      ],
      "role": "roles/resourcemanager.organizationAdmin"
    },
    {
      "members": [
        "user:divya@example.com",
        "user:jie@example.com"
      ],
      "role": "roles/resourcemanager.projectCreator"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 1
}

위의 예시에서 Jie(jie@example.com)는 첫 번째 역할 결합에서 사전 정의된 역할(roles/resourcemanager.organizationAdmin)인 조직 관리자를 부여받습니다. 이 역할에는 조직, 폴더, 제한된 프로젝트 작업에 대한 권한이 포함됩니다. 두 번째 역할 결합에서 Jie와 Divya(divya@example.com)는 프로젝트 생성자 역할(roles/resourcemanager.projectCreator)을 통해 프로젝트를 생성할 수 있는 권한을 부여받습니다. 또한 이러한 결합은 Jie와 Divya 모두에게 세밀한 액세스 권한을 부여하며, 여기서 Divya에게 부여된 액세스 권한은 Jie에게 부여된 액세스 권한의 하위 집합입니다.

예시: 조건부 역할 결합을 사용하는 정책

구성원을 사전 정의된 역할에 결합하고 조건 표현식을 사용하여 역할 결합을 제한하는 다음 IAM 정책을 고려합니다.

{
  "bindings": [
    {
      "members": [
        "group:prod-dev@example.com",
        "serviceAccount:prod-dev-example@appspot.gserviceaccount.com"
      ],
      "role": "roles/appengine.deployer",
      "condition": {
          "title": "Expires_July_1_2020",
          "description": "Expires on July 1, 2020",
          "expression":
            "request.time < timestamp('2020-07-01T00:00:00.000Z')"
      }
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 3
}

이 예시에서는 정책에 조건 표현식이 포함되어 있으므로 version 필드는 3으로 설정됩니다. 정책의 binding은 조건부 역할 결합입니다. 2020년 7월 1일까지만 Google 그룹 prod-dev@example.com 및 서비스 계정 prod-dev-example@appspot.gserviceaccount.com에 역할을 부여합니다.

각 정책 버전이 지원하는 기능에 대한 자세한 내용은 이 페이지의 정책 버전을 참조하세요.

예시: 조건부 및 비조건부 역할 결합을 사용하는 정책

동일한 역할에 조건부 및 비조건부 역할 결합을 모두 포함하는 다음 IAM 정책을 고려합니다.

{
  "bindings": [
    {
      "members": [
        "serviceAccount:prod-dev-example@appspot.gserviceaccount.com"
       ],
       "role": "roles/appengine.deployer"
    },
    {
      "members": [
        "group:prod-dev@example.com",
        "serviceAccount:prod-dev-example@appspot.gserviceaccount.com"
      ],
      "role": "roles/appengine.deployer",
      "condition": {
        "title": "Expires_July_1_2020",
        "description": "Expires on July 1, 2020",
        "expression":
          "request.time < timestamp('2020-07-01T00:00:00.000Z')"
      }
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 3
}

이 예시에서는 서비스 계정 serviceAccount:prod-dev-example@appspot.gserviceaccount.com이 동일한 역할의 두 역할 결합에 포함되어 있습니다. 첫 번째 결합에는 조건이 없습니다. 두 번째 결합에는 2020년 7월 1일까지만 역할을 부여하는 조건이 있습니다.

이 정책은 효과적으로 서비스 계정에 항상 역할을 부여합니다. IAM에서 조건부 역할 결합은 조건 없는 역할 결합을 재정의하지 않습니다. 구성원이 역할에 결합되어 있고 역할 결합에 조건이 없는 경우 구성원은 항상 해당 역할을 갖습니다. 동일한 역할의 조건부 결합에 구성원을 추가해도 효과가 없습니다.

반대로 Google 그룹 group:prod-dev@example.com은 조건부 역할 결합에만 포함됩니다. 따라서 2020년 7월 1일 이전 역할만 있습니다.

예시: 삭제된 구성원을 역할에 결합하는 정책

다음 정책 예시를 고려하세요. 이 정책은 계정이 삭제된 사용자 donald@example.com에 역할을 결합합니다.

{
  "bindings": [
    {
      "members": [
        "deleted:user:donald@example.com?uid=123456789012345678901"
      ],
      "role": "roles/owner"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 1
}

donald@example.com이라는 새 사용자를 만들면 삭제된 사용자에 대한 정책의 binding이 새 사용자에게 적용되지 않습니다. 이 동작은 새 사용자가 삭제된 사용자에게 부여된 역할을 상속하지 않도록 합니다.

또한 이제 사용자의 이름에 프리픽스 deleted: 및 서픽스 ?uid=numeric-id가 포함됩니다. 여기서 numeric-id는 삭제된 사용자의 고유 숫자 ID입니다. 이 예시에서 정책은 user:donald@example.com 대신 식별자 deleted:user:donald@example.com?uid=123456789012345678901을 표시합니다.

서비스 계정 및 그룹의 동작은 사용자와 동일합니다. 서비스 계정 또는 그룹을 삭제한 후 해당 구성원이 포함된 정책을 보면 삭제된 구성원의 이름에 프리픽스 deleted: 및 서픽스 ?uid=numeric-id가 있습니다.

이름이 동일한 삭제된 사용자에게 정책이 이미 결합되었으므로 이 예시에서는 새 사용자 donald@example.com을 정책의 binding에 추가할 수 없습니다. 이 문제를 해결하는 방법은 삭제된 구성원을 포함하는 정책의 안내를 참조하세요.

정책 제한사항

IAM 정책에는 다음 제한사항이 적용됩니다.

  • 리소스 계층 구조의 각 수준에서 IAM 정책을 지원하는 모든 Google Cloud 리소스는 정책을 하나만 가질 수 있습니다. 리소스의 예를 들면 조직, 폴더, 프로젝트, 개별 리소스(Compute Engine 디스크, 이미지 등)가 있습니다.
  • 각 IAM 정책은 최대 1,500명까지 members를 포함할 수 있습니다. 최대 250명까지 Google 그룹의 구성원이 될 수 있습니다.

    IAM은 정책의 binding에서 각 구성원의 노출을 모두 집계합니다. binding 두 개 이상에 나타난 구성원을 중복 삭제하여 집계하지 않습니다. 예를 들어 user:alice@example.com 구성원이 50개의 binding에 나타날 경우 정책의 모든 binding에 다른 구성원 1,450명을 추가할 수 있습니다.

  • 일반적으로 모든 정책 변경사항은 setIamPolicy()를 호출하거나 Cloud Console에서 역할 결합을 업데이트한 후 60초 이내에 적용됩니다. 하지만 일부 환경에서는 정책 변경사항을 시스템 전체에 전파하는 데 최대 7분이 걸리기도 합니다.

  • 현재 일부 Google Cloud 서비스는 리소스 이름, 유형 또는 Google Cloud를 조건부 역할 결합에 사용할 수 있더라도 리소스 수준 정책에 대한 조건부 역할 결합을 지원하지 않습니다. 예를 들어 일부 경우에는 서비스 리소스에 대한 액세스를 제한하는 조건부 역할 결합이 있는 정책을 프로젝트에서 설정할 수 있지만 리소스 자체에서는 설정할 수 없습니다. 자세한 내용은 IAM 조건 속성 참조를 확인하세요.

정책 상속 및 리소스 계층 구조

Google 리소스는 계층 구조로 되어 있습니다. 여기서 조직 노드는 계층 구조의 루트 노드이고 폴더와 프로젝트는 선택적 하위 항목입니다. 대부분의 다른 리소스는 프로젝트 하위에서 생성되고 관리됩니다. 계층 구조의 루트 노드를 제외하고 각 리소스는 단 하나의 상위 항목만 가집니다. 자세한 내용은 리소스 계층 구조 주제를 참조하세요.

IAM 정책을 설정할 때는 리소스 계층 구조를 고려하는 것이 중요합니다. 조직 수준, 폴더 수준, 프로젝트 수준 등 계층 구조의 상위 수준에서 정책을 설정할 때는 부여된 액세스 범위에 이 정책이 연결된 리소스 수준과 해당 수준에 속한 모든 리소스가 포함됩니다. 예를 들어 조직 수준에서 설정된 정책은 조직 및 조직에 속한 모든 리소스에 적용됩니다. 마찬가지로 프로젝트 수준에서 설정된 정책은 프로젝트 및 프로젝트에 속한 모든 리소스에 적용됩니다.

정책 상속은 리소스 계층 구조의 각 수준에 속한 리소스에 정책이 적용되는 방식을 설명하는 용어입니다. 유효 정책은 리소스 계층 구조의 모든 상위 정책이 리소스에 상속되는 방식을 설명하는 용어로, 다음의 통합입니다.

  • 리소스에 설정된 정책
  • 계층 구조에서 모든 리소스의 상위 리소스 수준에 설정된 정책

상위 리소스에서 상속되어 리소스의 유효 정책에 영향을 주는 각각의 새로운 역할 결합은 독립적으로 평가됩니다. 상위 수준의 역할 결합 중 하나라도 요청에 대한 액세스 권한을 부여하면 리소스에 대한 특정 액세스 요청이 부여됩니다.

리소스 수준에 관계없이 새 역할 결합이 리소스의 상속된 정책에 도입되면 액세스 권한 부여 범위가 늘어납니다.

예시: 정책 상속

정책 상속을 이해하려면 조직 수준에서 설정된 다음 정책 예시를 참고하세요.

조직 수준 정책

{
  "bindings": [
    {
      "members": [
        "user:divya@example.com"
      ],
      "role": "roles/storage.objectViewer"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 1
}

스토리지 객체 뷰어 역할(roles/storage.objectViewer)에는 프로젝트와 Cloud Storage 객체에 대한 getlist 권한이 포함됩니다. 조직 수준에서 설정하면 이 역할 결합은 모든 프로젝트 및 해당 프로젝트에 속한 모든 Cloud Storage 객체를 포함하는 조직 하위의 다양한 수준에 적용됩니다.

정책 상속에 대해 자세히 알아보려면 myproject-123에서 정책을 추가로 설정할 경우 어떻게 되는지를 고려해야 합니다.

프로젝트 수준 정책

{
  "bindings": [
    {
      "members": [
        "user:divya@example.com"
      ],
      "role": "roles/storage.objectCreator"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 1
}

위의 예시에서 스토리지 객체 생성자 역할(roles/storage.objectCreator)은 Divya에게 myproject-123 하위에 Cloud Storage 객체를 생성할 수 있는 권한을 부여합니다. 이제 myproject-123 하위에는 Divya에게 대상 Cloud Storage 객체에 액세스할 수 있는 권한을 부여한 역할 결합이 2개 있으므로 다음 정책이 적용됩니다.

  • 조직 수준의 정책은 이 조직 하위에 모든 Cloud Storage 객체를 나열하고 가져올 수 있는 권한을 부여합니다.
  • 프로젝트 myproject-123에 대해 프로젝트 수준의 정책은 해당 프로젝트 내에 객체를 만들 수 있는 권한을 부여합니다.

아래 표에는 Divya의 유효 정책 정보가 요약되어 있습니다.

조직 수준에서 'storage.objectViewer' 역할을 통해 부여된 권한 'myproject-123'에서 'storage.objectCreator' 역할을 통해 부여된 권한 'myproject-123'에서 Divya의 유효 권한 부여 범위
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.get
storage.objects.list
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.create
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.get
storage.objects.list
storage.objects.create

정책 버전

시간 경과에 따라 IAM은 정책 스키마의 필드를 획기적으로 추가하거나 변경하는 새로운 기능을 추가할 수 있습니다. 정책 구조의 일관성에 의존하는 기존 통합을 손상시키지 않으려면 새 정책 스키마 버전에 이러한 변경사항을 반영해야 합니다.

IAM과 처음 통합하는 경우에는 해당 시점의 최신 정책 스키마 버전을 사용하는 것이 좋습니다. 아래에서 사용 가능한 다양한 버전과 각 버전의 사용 방법에 대해 알아보겠습니다. 또한 원하는 버전을 지정하는 방법과 몇 가지 문제 해결 시나리오도 단계별로 안내합니다.

모든 기존 IAM 정책은 version 필드를 정책 메타데이터의 일부로 지정합니다. 아래에서 강조표시된 부분을 참조하세요.

{
  "bindings": [
    {
      "members": [
        "user:jie@example.com"
      ],
      "role": "roles/owner"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 1
}

이 필드는 정책의 구문 스키마 버전을 지정합니다. 각 정책 버전에는 binding에서 사용할 수 있는 특정 구문 스키마가 포함됩니다. 최신 버전에는 이전 버전에서 지원되지 않는 최신 구문 스키마와의 역할 결합이 포함될 수 있습니다. 이 필드는 정책 구문 스키마 제어 이외의 목적으로 사용되지 않습니다.

유효한 정책 버전

IAM 정책은 다음 정책 버전을 사용할 수 있습니다.

버전 설명
1 정책에 대한 IAM 구문 스키마의 첫 번째 버전입니다. 하나의 역할과 한 명 이상의 구성원 간의 결합을 지원합니다. 조건부 역할 결합을 지원하지 않습니다.
2 내부에서만 사용됩니다.
3 역할 결합에 condition 필드를 사용하여 컨텍스트 기반 및 속성 기반 규칙을 통해 역할 결합을 제한합니다. 자세한 내용은 IAM 조건 개요를 참조하세요.

정책을 가져올 때 정책 버전 지정

REST API 및 클라이언트 라이브러리의 경우 IAM 정책을 가져올 때 요청에 정책 버전을 지정하는 것이 좋습니다. 요청에서 정책 버전을 지정하면 IAM은 호출자가 해당 정책 버전의 기능을 인식하고 이를 올바르게 처리할 수 있다고 가정합니다.

요청에서 정책 버전을 지정하지 않는 경우 IAM은 호출자가 버전 1 정책을 원한다고 가정합니다.

정책을 가져올 때 IAM은 요청의 정책 버전 또는 요청에 버전이 지정되지 않은 경우 기본 버전을 확인합니다. 또한 IAM은 버전 1 정책에서 지원되지 않는 필드의 정책을 확인합니다. 이 정보를 사용하여 전송할 응답 유형을 결정합니다.

  • 정책에 조건이 없으면 IAM은 요청의 버전 숫자와 관계없이 항상 버전 1 정책을 반환합니다.
  • 정책에 조건이 있고 호출자가 버전 3 정책을 요청하면 IAM은 조건을 포함하는 버전 3 정책을 반환합니다. 예시를 보려면 이 페이지의 시나리오 1을 참조하세요.
  • 정책에 조건이 있고 호출자가 버전 1 정책을 요청하거나 버전을 지정하지 않으면 IAM은 버전 1 정책을 반환합니다.

    조건이 포함된 역할 결합의 경우 IAM은 역할 이름에 문자열 _withcond_를 추가하고 그 뒤에 해시 값(예: roles/iam.serviceAccountAdmin_withcond_2b17cc25d2cd9e2c54d8)을 추가합니다. 조건 자체는 존재하지 않습니다. 예시를 보려면 이 페이지의 시나리오 2를 참조하세요.

이 동작은 조건부 역할 결합을 인식하지 못하는 이전 클라이언트 라이브러리의 문제를 방지합니다. 자세한 내용은 이 페이지의 정책 버전에 대한 클라이언트 라이브러리 지원을 참조하세요.

시나리오 1: IAM 조건을 완전히 지원하는 정책 버전

프로젝트의 IAM 정책을 가져오기 위해 다음 REST API 메서드를 호출한다고 가정해 보겠습니다.

POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:getIamPolicy

요청 본문에는 다음 텍스트가 포함됩니다.

{
  "options": {
    "requestedPolicyVersion": 3
  }
}

응답에는 프로젝트의 IAM 정책이 포함됩니다. 정책에 하나 이상의 조건부 역할 결합이 포함된 경우 version 필드가 3으로 설정됩니다.

{
  "bindings": [
    {
      "members": [
        "user:user@example.com"
      ],
      "role": "roles/iam.securityReviewer",
      "condition": {
          "title": "Expires_July_1_2020",
          "description": "Expires on July 1, 2020",
          "expression": "request.time < timestamp('2020-07-01T00:00:00.000Z')"
      }
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 3
}

정책에 조건부 역할 결합이 포함되지 않은 경우 version 필드는 1로 설정되며 요청이 버전 3을 지정하지 않아도 마찬가지입니다.

{
  "bindings": [
    {
      "members": [
        "user:user@example.com"
      ],
      "role": "roles/iam.securityReviewer",
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 1
}

시나리오 2: IAM 조건에 대한 지원이 제한된 정책 버전

프로젝트의 IAM 정책을 가져오기 위해 다음 REST API 메서드를 호출한다고 가정해 보겠습니다.

POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:getIamPolicy

요청 본문이 비어있습니다. 버전 번호를 지정하지 않습니다. 따라서 IAM은 기본 정책 버전 1을 사용합니다.

정책에 조건부 역할 결합이 포함되어 있습니다. 정책 버전이 1이기 때문에 응답에 조건이 표시되지 않습니다. 역할 결합이 조건을 사용함을 나타내기 위해 IAM은 역할 이름에 문자열 _withcond_를 추가하고 그 뒤에 해시 값을 추가합니다.

{
  "bindings": [
    {
      "members": [
        "user:user@example.com"
      ],
      "role": "roles/iam.securityReviewer_withcond_58e135cabb940ad9346c"
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 1
}

정책 설정 시 정책 버전 지정

IAM 정책을 설정할 때 요청에 정책 버전을 지정하는 것이 좋습니다. 요청에서 정책 버전을 지정하면 IAM은 호출자가 해당 정책 버전의 기능을 인식하고 이를 올바르게 처리할 수 있다고 가정합니다.

요청에서 정책 버전을 지정하지 않으면 IAM은 버전 1 정책에 표시될 수 있는 필드만 허용합니다. 버전 1 정책에서 조건부 역할 결합을 변경하지 않는 것이 좋습니다. 정책이 각 결합에 대한 조건을 표시하지 않기 때문에 결합이 실제로 부여되는 시기나 위치를 알 수 없습니다. 대신 각 결합의 조건을 표시하는 정책의 버전 3 표현을 가져와서 해당 표현을 사용하여 결합을 업데이트합니다.

시나리오: 요청 및 응답의 정책 버전

REST API를 사용하여 IAM 정책을 가져오며 요청에서 버전 3을 지정한다고 가정합니다. 응답에는 버전 3을 사용하는 다음 정책이 포함됩니다.

{
  "bindings": [
    {
      "members": [
        "user:divya@example.com"
      ],
      "role": "roles/storage.admin",
      "condition": {
          "title": "Weekday_access",
          "description": "Monday thru Friday access only in America/Chicago",
          "expression": "request.time.getDayOfWeek('America/Chicago') >= 1 && request.time.getDayOfWeek('America/Chicago') <= 5"
      }
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 3
}

주중뿐만 아니라 일주일 동안 divya@example.com에게 스토리지 관리자 역할(roles/storage.admin)이 있어야 한다고 결정합니다. 역할 결합에서 조건을 삭제하고 REST API 요청을 보내 정책을 설정합니다. 요청에 버전3을 다시 지정합니다.

{
  "bindings": [
    {
      "members": [
        "user:divya@example.com"
      ],
      "role": "roles/storage.admin"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 3
}

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

{
  "bindings": [
    {
      "members": [
        "user:divya@example.com"
      ],
      "role": "roles/storage.admin"
    }
  ],
  "etag": "BwWd8I+ZUAQ=",
  "version": 1
}

요청에서 버전 3을 지정해도 응답에서 정책은 버전 1을 사용합니다. 정책은 버전 1 정책에서 지원되는 필드만 사용하기 때문입니다.

정책 버전에 대한 클라이언트 라이브러리 지원

Google Cloud용 일부 클라이언트 라이브러리는 버전 1 정책만 지원합니다. 클라이언트 라이브러리가 이후 정책 버전을 지원하지 않는 경우 이후 버전에서만 사용할 수 있는 기능을 사용할 수 없습니다. 예를 들어 IAM 조건은 정책 버전 3을 지원해야 합니다.

IAM 조건과 같이 버전 1 정책에서 사용할 수 없는 IAM 기능을 사용하는 경우 정책은 해당 정책 버전을 지원하는 클라이언트 라이브러리를 사용하여 요청에서 올바르게 설정합니다.

다음의 IAM용 Google API 클라이언트 라이브러리는 정책 버전 3을 지원합니다.

언어 정책 버전 3을 지원하는 버전
C# Google.Apis >=v1.41.1
Go google-api-go-client >=v0.10.0
자바
Node.js googleapis >=v43.0.0
PHP google/apiclient >=v2.4.0
Python google-api-python-client >=v1.7.11
Ruby google-api-client >=v0.31.0

이러한 클라이언트 라이브러리를 사용하여 다음 서비스 리소스에 대한 버전 3 IAM 정책을 관리할 수 있습니다.

  • IAM
  • Cloud KMS
  • Cloud Storage
  • Compute Engine
  • Resource Manager

Google Cloud 클라이언트 라이브러리를 포함한 다른 클라이언트 라이브러리는 버전 1 정책만 지원합니다.

정책 버전에 대한 gcloud 지원

gcloud 도구가 IAM 정책을 관리하는 경우 버전 263.0.0 이상을 사용 중인지 확인합니다. 이전 버전은 버전 1 정책만 지원합니다.

gcloud 도구의 버전 번호를 확인하려면 gcloud version을 실행합니다. 최신 버전으로 업데이트하려면 gcloud components update를 실행합니다.

삭제된 구성원이 포함된 정책

정책의 binding에 삭제된 구성원이 포함되어 있고 동일한 이름의 새 구성원에 binding을 추가하려고 하면 INVALID_ARGUMENT 오류가 발생합니다.

예를 들어 삭제된 사용자 donald@example.com과 삭제된 서비스 계정 my-service-account@project-id.iam.gserviceaccount.com에 대한 binding이 포함된 정책을 살펴보겠습니다.

{
  "bindings": [
    {
      "members": [
        "deleted:serviceAccount:my-service-account@project-id.iam.gserviceaccount.com?uid=123456789012345678901",
        "deleted:user:donald@example.com?uid=234567890123456789012"
      ],
      "role": "roles/owner"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 1
}

donald@example.com이라는 새 사용자를 만드는 경우 정책의 binding에 새 사용자를 추가할 수 없습니다. 예를 들어 새 사용자를 프로젝트 생성자 역할(roles/resourcemanager.projectCreator)에 결합하여 사용자가 Google Cloud 프로젝트를 만들 수 있다고 가정해보겠습니다. 다음과 같이 정책을 업데이트합니다.

{
  "bindings": [
    {
      "members": [
        "deleted:serviceAccount:my-service-account@project-id.iam.gserviceaccount.com?uid=123456789012345678901",
        "deleted:user:donald@example.com?uid=234567890123456789012"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "user:donald@example.com"
      ],
      "role": "roles/resourcemanager.projectCreator"
    }
  ],
  "etag": "BwUjMhCsNvY=",
  "version": 1
}

업데이트된 정책을 설정하면 INVALID_ARGUMENT 오류가 발생합니다.

{
  "error": {
    "code": 400,
    "message": "Inconsistent representation of deleted member: 'deleted:user:donald@example.com?uid=234567890123456789012' and 'user:donald@example.com' cannot be on the policy simultaneously.",
    "status": "INVALID_ARGUMENT"
  }
}

마찬가지로 my-service-account@project-id.iam.gserviceaccount.com이라는 새 서비스 계정을 만드는 경우 정책의 binding에 새 서비스 계정을 추가할 수 없습니다. 다른 유형의 구성원에도 동일한 제한사항이 적용됩니다.

이 문제를 해결하려면 다음 중 하나를 변경하면 됩니다

  • 가능한 경우 삭제된 구성원을 삭제 취소합니다. 삭제된 구성원이 binding에 표시되고 구성원을 삭제 취소할 수 있으면 구성원은 결합된 역할을 자동으로 다시 얻습니다. 구성원의 역할을 수동으로 복원할 필요가 없습니다.

    Google Workspace 사용자 삭제를 취소하려면 최근에 삭제한 사용자 복원하기를 참조하세요.

    서비스 계정을 삭제 취소하려면 서비스 계정 삭제 취소를 참조하세요.

  • 다음과 같이 정책을 수정합니다.

    1. 정책이 삭제된 구성원에 결합된 모든 역할을 취소합니다. 삭제된 구성원이 정책에서 2개 이상의 binding에 표시되는 경우 각 binding에서 삭제된 구성원을 삭제해야 합니다.

      다른 정책의 binding에서 삭제된 구성원을 삭제할 필요는 없습니다.

    2. 새 구성원에게 적절한 역할을 부여합니다.

정책 권장사항

Google Cloud 사용자가 많은 조직에서는 다음 권장사항을 따르는 것이 좋습니다.

  • 동일한 액세스 구성으로 여러 사용자 계정을 관리할 때는 Google 그룹을 대신 사용하세요. 개별 사용자 계정을 그룹에 추가하고 개별 사용자 계정 대신 그룹에 원하는 역할을 부여합니다.

  • 조직 수준에서 부여된 권한: 조직 수준에서 구성원에게 액세스 권한을 부여할 때는 신중하게 고려하세요. 대부분의 조직에서는 보안 및 네트워크팀 등 특정한 몇 개 팀에만 리소스 계층 구조의 조직 수준으로 액세스 권한이 부여됩니다.

  • 폴더 수준에서 부여된 권한: 폴더 계층을 사용하여 조직의 운영 구조를 반영할지 여부를 고려하세요. 여기서 각 상위/하위 폴더는 비즈니스 및 운영 요구사항에 따라 서로 다른 액세스 권한 집합으로 구성할 수 있습니다. 예를 들어 상위 폴더는 부서가 될 수 있고 하위 폴더 중 하나는 그룹의 리소스 액세스 및 운영을, 다른 하위 폴더는 소규모 팀을 반영할 수 있습니다. 이 두 폴더에는 모두 팀의 운영에 필요한 프로젝트가 포함될 수 있습니다. 이러한 방식으로 폴더를 사용할 때는 상위 폴더 및 조직에서 상속된 정책을 준수하는 동시에 액세스 권한을 적절히 분리해야 합니다. 이렇게 하면 Google Cloud 리소스를 만들고 관리할 때 정책 유지보수가 덜 필요합니다.

  • 프로젝트 수준에서 부여된 권한: 특정 그룹 또는 세분화된 개별 권한에 대해 필요한 경우에만 프로젝트 수준에서 역할 결합을 부여합니다. 특히 프로젝트가 여러 개인 경우 관리를 용이하게 하려면 가능한 경우 폴더 수준에서 정책을 설정하는 것이 좋습니다.

다음 단계