IAM으로 조직 리소스의 액세스 제어

Google Cloud에서는 Identity and Access Management(IAM)를 제공하므로 구체적인 Google Cloud 리소스에 더욱 세분화된 액세스 권한을 부여하고 다른 리소스에 대한 무단 액세스를 방지할 수 있습니다. IAM은 최소 권한의 보안 원칙을 채택하여 리소스에 대해 필요한 액세스 권한만 부여할 수 있게 해줍니다.

IAM을 사용하면 IAM 정책을 설정하여 어떠한 리소스에 대해 누구(사용자)에게 어떠한 액세스 권한(역할)이 있는지 제어할 수 있습니다. IAM 정책은 사용자에게 구체적인 역할을 부여하여 특정 권한을 줍니다.

이 페이지에서는 조직 리소스 수준에서 사용할 수 있는 IAM 역할과 Cloud Resource Manager API를 사용하여 조직 리소스의 IAM 정책을 만들고 관리하는 방법에 대해 설명합니다. IAM에 대한 자세한 내용은 IAM 문서를 참조하세요. 특히 액세스 권한 부여, 변경, 취소를 확인하시기 바랍니다.

권한 및 역할

리소스에 대한 액세스 권한을 제어하려면 API 요청을 보내는 Google Cloud 계정에 적절한 IAM 역할이 있어야 합니다. IAM 역할에는 사용자가 Google Cloud 리소스에서 특정 작업을 수행하도록 허용하는 권한이 포함되어 있습니다. 예를 들어 resourcemanager.organizations.get 권한이 있는 사용자는 조직 리소스에 대한 세부정보를 가져올 수 있습니다.

사용자에게 권한을 직접 부여하는 대신 하나 이상의 권한이 번들로 포함된 역할을 부여합니다.

동일한 리소스에 하나 이상의 역할을 부여할 수 있습니다.

사전 정의된 역할 사용

다음 표에는 조직 리소스의 속성에 액세스하기 위해 부여할 수 있는 역할, 각 역할에 대한 설명, 각 역할에 포함된 권한이 나와 있습니다.

역할 권한

(roles/resourcemanager.organizationAdmin)

IAM 정책을 관리하고 조직, 폴더, 프로젝트의 조직 정책을 확인할 수 있는 액세스 권한입니다.

이 역할을 부여할 수 있는 최하위 수준 리소스:

  • 프로젝트

essentialcontacts.*

  • essentialcontacts.contacts.create
  • essentialcontacts.contacts.delete
  • essentialcontacts.contacts.get
  • essentialcontacts.contacts.list
  • essentialcontacts.contacts.send
  • essentialcontacts.contacts.update

orgpolicy.constraints.list

orgpolicy.policies.list

orgpolicy.policy.get

resourcemanager.folders.get

resourcemanager.folders.getIamPolicy

resourcemanager.folders.list

resourcemanager.folders.setIamPolicy

resourcemanager.organizations.*

  • resourcemanager.organizations.get
  • resourcemanager.organizations.getIamPolicy
  • resourcemanager.organizations.setIamPolicy

resourcemanager.projects.get

resourcemanager.projects.getIamPolicy

resourcemanager.projects.list

resourcemanager.projects.setIamPolicy

(roles/resourcemanager.organizationViewer)

조직을 볼 수 있는 액세스 권한을 제공합니다.

이 역할을 부여할 수 있는 최하위 수준 리소스:

  • 조직

resourcemanager.organizations.get

(roles/orgpolicy.policyAdmin)

조직 정책을 설정하여 조직에서 클라우드 리소스 구성에 적용하려는 제한사항을 정의할 수 있는 액세스 권한을 제공합니다.

이 역할을 부여할 수 있는 최하위 수준 리소스:

  • 조직

orgpolicy.*

  • orgpolicy.constraints.list
  • orgpolicy.customConstraints.create
  • orgpolicy.customConstraints.delete
  • orgpolicy.customConstraints.get
  • orgpolicy.customConstraints.list
  • orgpolicy.customConstraints.update
  • orgpolicy.policies.create
  • orgpolicy.policies.delete
  • orgpolicy.policies.list
  • orgpolicy.policies.update
  • orgpolicy.policy.get
  • orgpolicy.policy.set

policysimulator.orgPolicyViolations.list

policysimulator.orgPolicyViolationsPreviews.*

  • policysimulator.orgPolicyViolationsPreviews.create
  • policysimulator.orgPolicyViolationsPreviews.get
  • policysimulator.orgPolicyViolationsPreviews.list

(roles/browser)

폴더, 조직, 허용 정책을 포함한 프로젝트 계층 구조를 탐색할 수 있는 읽기 액세스 권한입니다. 프로젝트의 리소스를 볼 수 있는 권한은 포함되어 있지 않습니다.

이 역할을 부여할 수 있는 최하위 수준 리소스:

  • 프로젝트

resourcemanager.folders.get

resourcemanager.folders.list

resourcemanager.organizations.get

resourcemanager.projects.get

resourcemanager.projects.getIamPolicy

resourcemanager.projects.list

커스텀 역할 만들기

이 항목에서 설명하는 사전 정의된 역할 외에, 요구사항에 맞게 조정하는 권한 컬렉션인 커스텀 역할을 만들 수도 있습니다. Resource Manager에 사용할 커스텀 역할을 만들 때 다음 사항에 유의하세요.
  • resourcemanager.projects.get/list 같은 List 및 get 권한은 항상 쌍으로 부여해야 합니다.
  • 커스텀 역할에 folders.listfolders.get 권한이 있는 경우 projects.listprojects.get 권한도 있어야 합니다.
  • 조직, 폴더, 프로젝트 리소스에 대한 setIamPolicy 권한이 있는 사용자는 기타 모든 권한을 부여할 수 있으므로 주의해서 할당해야 합니다.

조직 리소스에 대한 기존 액세스 보기

조직 리소스 수준 IAM 정책을 가져와서 조직 리소스의 사용자에게 부여된 역할을 볼 수 있습니다. Google Cloud 콘솔, Google Cloud CLI, getIamPolicy() 메서드를 사용하여 조직 리소스의 정책을 볼 수 있습니다.

콘솔

Google Cloud 콘솔을 사용하여 조직 리소스 수준에서 부여된 역할을 보려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.

    리소스 관리 페이지 열기

  2. 조직 드롭다운 목록에서 조직 리소스를 선택합니다.

  3. 조직 리소스의 체크박스를 선택합니다.

  4. 오른쪽 정보 패널권한 아래에서 클릭하여 역할을 확장하고 해당 역할이 있는 모든 구성원을 표시합니다.

gcloud

get-iam-policy 명령어를 사용하여 조직 리소스의 IAM 정책을 가져옵니다.

gcloud alpha organizations get-iam-policy [ORGANIZATION_ID] --format json >
[FILENAME.JSON]

이 명령어는 다음과 유사한 정책을 출력합니다.

bindings:
- members:
- user:testuser1@gcp-test.com
role: roles/editor
- members:
- user:admin@gcp-test.com
role:roles/resourcemanager.organizationAdmin
- members:
- user:testuser2@gcp-test.com
role: roles/resourcemanager.projectCreator
etag": "BwU1aRxWk30="

API

다음 코드 스니펫은 조직 리소스 https://cloudresourcemanager.googleapis.com/v3/organizations/12345에 대한 정책을 반환합니다.

요청:

POST
https://cloudresourcemanager.googleapis.com/v3/organizations/12345:getIamPolicy

응답:

{
    "bindings": [
    {
        "role": "roles/resourcemanager.organizationAdmin",
        "members": [
        "user:email1@gmail.com"
    ]
    },
    {
        "role": "roles/resourcemanager.projectCreator",
        "members": [
            "user:email2@gmail.com",
            "user:email3@gmail.com",
            "serviceAccount:my-other-app@appspot.gserviceaccount.com"
        ]
    }
    ]
    "etag": "BwUjHYKHHiQ="
}

Python

getIamPolicy() 메서드를 사용하면 이전에 설정된 정책을 가져올 수 있습니다.

crm = discovery.build(
    'cloudresourcemanager', 'v3', http=creds.authorize(httplib2.Http()))
policy = crm.organizations().getIamPolicy(
    resource=flags.organizationId, body={}).execute()
print json.dumps(policy, indent=2)

조직 리소스에 대한 액세스 권한 부여

조직 관리자는 조직의 리소스와 API에 액세스할 수 있도록 팀 구성원에게 IAM 역할을 부여할 수 있습니다. Google 계정 이메일, Google 그룹, 서비스 계정 또는 G Suite 도메인에 역할을 부여할 수 있습니다. Google Cloud 콘솔, gcloud CLI 또는 setIamPolicy() 메서드를 사용하여 역할을 부여할 수 있습니다.

콘솔

Google Cloud 콘솔을 사용하여 조직 리소스 수준에서 액세스 제어를 설정하려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.

    리소스 관리 페이지 열기

  2. 조직 드롭다운 목록에서 조직 리소스를 선택합니다.

  3. 조직 리소스의 체크박스를 선택합니다. 폴더 리소스가 없으면 조직 리소스가 표시되지 않습니다. 계속하려면 IAM 페이지를 통한 역할 부여에 대한 안내를 확인하세요.

  4. 오른쪽의 정보 패널 창이 숨겨져 있는 경우 오른쪽 상단에서 정보 패널 표시를 클릭합니다.

  5. 정보 패널 창의 권한 탭에서 구성원 추가를 클릭합니다.

  6. 새 구성원 입력란에 추가할 팀 구성원을 입력합니다. Google 계정 이메일, Google 그룹스, 서비스 계정 또는 G Suite 도메인을 지정할 수 있습니다.

  7. 역할 선택 드롭다운 목록에서 팀 구성원에게 부여할 역할을 선택합니다.

  8. 추가를 클릭합니다.

gcloud

gcloud 명령어를 사용하여 조직 리소스의 IAM 정책을 설정하려면 다음 단계에 따르세요.

  1. get-iam-policy 명령어를 사용하여 조직 리소스의 IAM 정책을 가져오고 정책을 JSON 파일로 출력합니다.

    gcloud alpha organizations get-iam-policy [ORGANIZATION_ID]
    --format json > [FILENAME.JSON]
    
  2. JSON 파일의 내용은 다음과 유사합니다.

    {
        "bindings": [
        {
            "members": [
                "user:testuser1@gcp-test.com"
            ],
            "role": "roles/editor"
        },
        {
            "members": [
                "user:admin@gcp-test.com",
            ],
            "role": "roles/resourcemanager.organizationAdmin"
        },
        {
            "members": [
                "user:testuser2@gcp-test.com"
            ],
            "role": "roles/resourcemanager.projectCreator"
        },
        ],
        "etag": "BwU1aRxWk30="
    }
    
  3. 텍스트 편집기를 사용하여 JSON 파일을 열고 새 항목을 조직 관리자를 정의하는 바인딩 배열에 추가합니다. 예를 들어 anotheradmin@gcp-test.com을 조직 관리자로 지정하려면 위의 예를 다음과 같이 변경합니다.

    {
        "bindings": [
        {
            "members": [
                "user:testuser1@gcp-test.com"
            ],
            "role": "roles/editor"
        },
        {
            "members": [
                "user:admin@gcp-test.com",
                "user:anotheradmin@gcp-test.com"
            ],
            "role": "roles/resourcemanager.organizationAdmin"
        },
        {
            "members": [
                "user:testuser20@gcp-test.com"
            ],
            "role": "roles/resourcemanager.projectCreator"
        },
        ],
        "etag": "BwU1aRxWk30="
    }
    
  4. 다음 명령어를 실행하여 조직 리소스의 정책을 업데이트합니다.

    gcloud alpha organizations set-iam-policy [ORGANIZATION_ID] policy.json
    

API

요청:

POST https://cloudresourcemanager.googleapis.com/v3/organizations/12345:setIamPolicy
{
    "policy": {
    "version": "0",
    "bindings": [
    {
        "role": "roles/resourcemanager.organizationAdmin",
        "members": [
            "user:email1@gmail.com"
        ]
    },
    {
        "role": "roles/resourcemanager.projectCreator",
        "members": [
        "user:email2@gmail.com",
        "user:email3@gmail.com",
        "serviceAccount:my-other-app@appspot.gserviceaccount.com"
        ]
    }
    ]
    "etag": "BwUjHYKHHiQ="
    }
}

응답:

{
    "bindings": [
    {
        "role": "roles/resourcemanager.organizationAdmin",
        "members": [
            "user:email1@gmail.com"
        ]
    },
    {
        "role": "roles/resourcemanager.projectCreator",
        "members": [
            "user:email2@gmail.com",
            "user:email3@gmail.com",
            "serviceAccount:my-other-app@appspot.gserviceaccount.com"
        ]
    }
    ]
    "etag": "BwUjHYKJUiQ="
}

setIamPolicy() 메서드를 사용하면 조직 리소스에 IAM 정책을 연결하여 사용자에게 역할을 부여할 수 있습니다. IAM 정책은 사용자마다 부여할 액세스를 정의하는 구문의 모음입니다.

Read-Modify-Write: 정책과 같은 리소스의 메타데이터를 업데이트하는 데 일반적으로 사용하는 패턴으로 현재 상태를 읽고 데이터를 로컬에서 업데이트한 다음 쓰기를 수행하기 위해 수정된 데이터를 전송합니다. 이 패턴에서는 서로 독립된 둘 이상의 프로세스가 동시에 시퀀스를 시도할 경우 충돌이 발생할 수 있습니다. 예를 들어 프로젝트 소유자가 두 명이고 둘 모두 동시에 상충하는 정책 변경을 시도한다고 가정해 보겠습니다. 이 경우 프로젝트 소유자 중 한 명이 시도한 변경이 실패할 수 있습니다. IAM은 IAM 정책에서 etag 속성을 사용하여 이 문제를 해결합니다. 이 속성은 마지막 요청 이후 정책이 변경되었는지 확인하는 데 사용됩니다. etag 값으로 IAM에 요청을 수행하면 IAM이 요청의 etag 값을 정책과 연결된 기존 etag 값과 비교합니다. 이때 ETag 값이 일치하는 경우에만 정책을 씁니다.

정책을 업데이트할 때는 일단 getIamPolicy()를 사용해 정책을 가져와 업데이트한 다음 setIamPolicy()를 사용해 업데이트된 정책을 씁니다. 정책을 설정할 때는 GetPolicyResponse에서 해당하는 정책에 ETag 값이 있는 경우에만 ETag 값을 사용하세요.

Python

setIamPolicy() 메서드를 사용하면 리소스에 정책을 연결할 수 있습니다. setIamPolicy 메서드는 설정할 정책과 이 정책과 연결되는 리소스를 포함하는 SetIamPolicyRequest를 사용합니다. 이 메서드는 결과로 나오는 정책을 반환합니다. setIamPolicy()를 사용하여 정책을 업데이트할 때 read-modify-write 패턴을 따르는 것이 좋습니다.

다음은 조직 리소스의 정책을 설정하는 샘플 코드입니다.

crm = discovery.build(
    'cloudresourcemanager', 'v3', http=creds.authorize(httplib2.Http()))
policy = crm.organizations().getIamPolicy(
    resource=flags.organizationId, body={}).execute()

admin_binding = next(
    (binding
        for binding in policy['bindings']
        if binding['role'] == 'roles/resourcemanager.organizationAdmin'),
        None)

# Add an empty Organization Administrator binding if not present.
if not admin_binding:
    admin_binding = {
        'role': 'roles/resourcemanager.organizationAdmin',
        'members': []
    }
policy['bindings'].append(admin_binding)

# Add the new Admin (if necessary).
new_admin = 'user:' + flags.adminEmail
if new_admin not in admin_binding['members']:
    admin_binding['members'].append(new_admin)
policy = crm.organizations().setIamPolicy(
    resource=flags.organizationId,
    body={
        'resource': flags.organizationId,
        'policy': policy
    }).execute()

print json.dumps(policy, indent=2)

사용자를 위한 프로젝트 공개 상태 제한

사용자는 현재 선택된 조직 리소스에 속해있는지 여부에 관계없이 Google Cloud 콘솔 및 검색어에서 액세스할 수 있는 모든 프로젝트를 볼 수 있습니다. 조직 정책 서비스를 사용하여 쿼리 및 Google Cloud 콘솔에서 반환되는 프로젝트 집합을 제한할 수 있습니다. 이 옵션을 사용하면 사용자가 자체 도메인 내의 프로젝트만 보도록 제한할 수 있습니다.

조직 정책 제약조건 constraints/resourcemanager.accessBoundaries는 조직 리소스에 적용되는 목록 제약조건입니다. 이 제약조건은 쿼리 또는 Google Cloud 콘솔의 사용자에게 리소스를 표시하는 조직 리소스 집합을 정의하는 조직 리소스 ID 목록을 허용합니다.

사용자에게 프로젝트의 상위 조직 리소스에 대한 resourcemanager.organizations.get 권한이 없는 경우 No organization 아래에 프로젝트가 표시됩니다. 이로 인해 조직 리소스에 속하지 않은 프로젝트가 조직 리소스와 전혀 연결되지 않은 것처럼 보일 수 있습니다. resourcemanager.accessBoundaries 제약조건을 사용하여 조직 리소스를 허용하지 않는 경우 해당 조직 리소스에 속하는 프로젝트가 쿼리 또는 Google Cloud 콘솔에 표시되지 않습니다. 이 제약조건이 적용되면 아직 조직 리소스로 마이그레이션되지 않은 프로젝트는 표시되지 않습니다.

이 제약조건을 적용하기 전에 No organization에 속한 프로젝트를 조직 리소스로 마이그레이션하는 것이 좋습니다. 프로젝트를 조직 리소스로 마이그레이션하는 방법에 대한 자세한 내용은 프로젝트 이동을 참조하세요.

조직 정책 설정에 대한 자세한 내용은 제약조건 사용을 참조하세요.

권한 테스트

testIamPermissions() 메서드를 사용하여 조직 리소스 사용자의 IAM 권한을 테스트할 수 있습니다. 이 메서드는 테스트 대상 리소스 URL 및 권한 집합을 입력 매개변수로 받고 사용자에게 부여된 권한의 하위 집합을 반환합니다.

Google Cloud 콘솔을 직접 사용하여 권한을 관리하는 경우 일반적으로 testIamPermission()을 호출하지 않습니다. testIamPermissions()는 맞춤설정된 그래픽 사용자 인터페이스와 같은 독점 소프트웨어와 통합할 때 사용됩니다. 예를 들어 Google Cloud 콘솔은 testIamPermissions()를 내부적으로 사용하여 로그인한 사용자가 사용할 수 있는 UI를 결정합니다.

API

testIamPermissions() 메서드를 사용하여 호출자가 특정 리소스에 대해 보유한 권한을 확인할 수 있습니다. 이 메서드는 리소스 이름과 권한 집합을 매개변수로 사용하여 호출자에게 있는 권한의 하위 집합을 반환합니다.

다음은 조직 리소스에 대한 권한을 테스트하는 샘플 코드입니다.

Request:

POST https://cloudresourcemanager.googleapis.com/v3/organizations/12345:testIamPermissions

{
    "permissions":  [
        "resourcemanager.organizations.get",
        "resourcemanager.organizations.setIamPolicy"
    ]
}

Response:

{
    "permissions": [
        "resourcemanager.organizations.get"
    ]
}

Python

crm = discovery.build(
    'cloudresourcemanager', 'v3', http=creds.authorize(httplib2.Http()))

response = crm.organizations().testIamPermissions(
    resource=flags.organizationId,
    body={
        'resource': flags.organizationId,
        'permissions': [
            'resourcemanager.organizations.setIamPolicy',
            'resourcemanager.projects.patch'
        ]
    }).execute()

print json.dumps(response, indent=2)