IAM を使用した組織リソースのアクセス制御

Google Cloud には Identity and Access Management(IAM)機能があり、特定の Google Cloud リソースに対するアクセス権を詳細に設定できるため、他のリソースへの不要なアクセスを防ぐことができます。IAM を使用すると、セキュリティにおける最小権限の原則を導入してリソースに対する必要なアクセス権のみを付与できます。

IAM では、IAM ポリシーを設定して、誰(どのユーザー)に、どのリソースに対するどのアクセス権(役割)を付与するかを制御できます。 IAM ポリシーは、特定の役割をユーザーに付与することで、そのユーザーに特定の権限を付与します。

このページでは、組織リソースレベルで使用可能な IAM ロールについて説明し、さらに、Cloud Resource Manager API を使用して組織リソースの IAM ポリシーを作成して管理する方法について説明します。IAM の詳細については、IAM のドキュメントを参照してください。特に、アクセス権の付与、変更、取り消しをご覧ください。

権限と役割

リソースへのアクセスを制御するために、Google Cloud では API リクエストを行うアカウントに適切な IAM ロールが必要です。IAM ロールには、ユーザーが Google Cloud リソースで特定のアクションを実行できる権限が含まれています。たとえば、resourcemanager.organizations.get 権限を持つユーザーは、自分が所属する組織リソースに関する詳細情報を取得できます。

ユーザーには権限を直接付与するのではなく、役割を割り当てます。役割には、1 つ以上の権限が組み込まれています。

同じリソースに 1 つ以上の役割を付与できます。

事前定義ロールの使用

次の表に、組織リソースのプロパティへのアクセス権を付与できる役割、この役割が行うことの説明、この役割に組み込まれている権限を示します。

ロール 権限

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 などのリスト権限と取得権限は、必ずペアで付与する必要があります。
  • カスタムロールに folders.list 権限と folders.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)

組織リソースへのアクセス権の付与

組織管理者は IAM の役割をチームメンバーに付与することにより、組織のリソースおよび API にアクセスできるようになります。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 ポリシーとは、誰がどの種類のアクセス権を持つかを定義するステートメントの集合です。

読み取り - 変更 - 書き込み: リソースのメタデータ(Policy など)を更新するための一般的なパターンです。メタデータの現在の状態を読み取り、データをローカルに更新した後、変更したデータを書き込みのために送信します。このような処理は、2 つ以上の独立したプロセスが一連の操作を同時に試行する場合に競合を引き起こすことがあります。たとえば、ある 1 つのプロジェクトにオーナーが 2 人おり、両者が同時にポリシーに対して競合する変更を行おうとする場合があります。この場合、一方のプロジェクト オーナーによって行われた変更が失敗する可能性があります。IAM は、IAM ポリシーの etag プロパティを使用してこの問題を解決します。このプロパティは、最後のリクエスト以降にポリシーが変更されたかどうかを確認するために使用します。etag 値を保持している IAM にリクエストを送信する際に、IAM はリクエスト内の etag 値と、ポリシーに関連付けられている既存の etag 値を比較し、etag 値が一致した場合にのみポリシーを書き込みます。

ポリシーを更新するときには、最初に getIamPolicy() を使用してポリシーを取得し、ポリシーを更新してから setIamPolicy() を使用してそのポリシーを書き込みます。ポリシーを設定するときに etag 値を使用するのは、GetPolicyResponse 内の対応するポリシーに 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 は、組織のリソースに適用されるリスト型制約です。この制約により、組織リソース ID のリストを指定できます。組織リソース ID は、クエリまたは Google Cloud コンソールでリソースの表示をユーザーに許可する組織リソースのセットを定義します。

プロジェクトの親組織リソースに対する 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)