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

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

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

このページでは、組織リソースで使用可能な IAM ロールと、Cloud Resource Manager API を使用して組織リソースの許可ポリシーを作成して管理する方法について説明します。詳細については、プロジェクト、フォルダ、組織へのアクセスを管理するをご覧ください。

権限とロール

リソースへのアクセスを制御するために、 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

iam.policybindings.*

  • iam.policybindings.get
  • iam.policybindings.list

orgpolicy.constraints.list

orgpolicy.policies.list

orgpolicy.policy.get

resourcemanager.capabilities.*

  • resourcemanager.capabilities.get
  • resourcemanager.capabilities.update

resourcemanager.folders.createPolicyBinding

resourcemanager.folders.deletePolicyBinding

resourcemanager.folders.get

resourcemanager.folders.getIamPolicy

resourcemanager.folders.list

resourcemanager.folders.searchPolicyBindings

resourcemanager.folders.setIamPolicy

resourcemanager.folders.updatePolicyBinding

resourcemanager.organizations.*

  • resourcemanager.organizations.createPolicyBinding
  • resourcemanager.organizations.deletePolicyBinding
  • resourcemanager.organizations.get
  • resourcemanager.organizations.getIamPolicy
  • resourcemanager.organizations.searchPolicyBindings
  • resourcemanager.organizations.setIamPolicy
  • resourcemanager.organizations.updatePolicyBinding

resourcemanager.projects.createPolicyBinding

resourcemanager.projects.deletePolicyBinding

resourcemanager.projects.get

resourcemanager.projects.getIamPolicy

resourcemanager.projects.list

resourcemanager.projects.searchPolicyBindings

resourcemanager.projects.setIamPolicy

resourcemanager.projects.updatePolicyBinding

roles/resourcemanager.organizationViewer

組織を閲覧するための権限を付与します。

このロールを付与できる最下位レベルのリソース:

  • 組織

resourcemanager.organizations.get

(roles/orgpolicy.policyAdmin)

組織のポリシーによるクラウド リソースの構成制限を定義する権限を付与します。

このロールを付与できる最下位レベルのリソース:

  • 組織

cloudasset.assets.analyzeOrgPolicy

cloudasset.assets.exportResource

cloudasset.assets.listResource

cloudasset.assets.searchAllResources

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

recommender.orgPolicyInsights.*

  • recommender.orgPolicyInsights.get
  • recommender.orgPolicyInsights.list
  • recommender.orgPolicyInsights.update

recommender.orgPolicyRecommendations.*

  • recommender.orgPolicyRecommendations.get
  • recommender.orgPolicyRecommendations.list
  • recommender.orgPolicyRecommendations.update

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 権限を使用すると、ユーザーに他のすべての権限も付与されます。この権限を割り当てる場合には十分に注意してください。

組織リソースに対する既存のアクセス権の表示

組織リソースに対してどのような役割がユーザーに付与されているかを確認するには、そのリソースの許可ポリシーを取得します。組織リソースの許可ポリシーを表示するには、 Google Cloud コンソール、Google Cloud CLI、または getIamPolicy() メソッドを使用します。

コンソール

Google Cloud コンソールを使用して組織リソースレベルで付与されたロールを表示するには:

  1. Google Cloud コンソールで [リソースの管理] ページに移動します。

    [リソースの管理] ページを開く

  2. [組織] プルダウン リストで組織リソースを選択します。

  3. 組織リソースのチェックボックスをオンにします。

  4. 右側の [情報パネル] の [権限] で、役割をクリックして展開しその役割を持つすべてのユーザーを表示します。

gcloud

get-iam-policy コマンドを使用して、組織リソースの許可ポリシーを取得します。

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 グループ、サービス アカウント、または G Suite のドメインに役割を付与できます。ロールの付与には、 Google Cloud コンソール、gcloud CLI、または setIamPolicy() メソッドを使用できます。

コンソール

Google Cloud コンソールを使用して組織リソースレベルでアクセス制御を設定するには:

  1. Google Cloud コンソールで [リソースの管理] ページに移動します。

    [リソースの管理] ページを開く

  2. [組織] プルダウン リストで組織リソースを選択します。

  3. 組織リソースのチェックボックスをオンにします。フォルダ リソースがない場合、組織リソースは表示されません。続行するには、IAM ページでロールを付与する手順をご覧ください。

  4. 右側の [情報パネル] が表示されていない場合は、右上隅にある [情報パネルを表示] をクリックします。

  5. [情報パネル] ペインの [権限] タブで、[メンバーを追加] をクリックします。

  6. [新しいメンバー] フィールドに、追加するチームメンバーを入力します。ユーザー アカウントのメールアドレス、Google グループ、サービス アカウント、または G Suite ドメインを指定できます。

  7. [ロールを選択] プルダウン リストで、チームメンバーに付与する役割を選択します。

  8. [追加] をクリックします。

gcloud

gcloud コマンドを使用して組織リソースの許可ポリシーを設定するには:

  1. get-iam-policy コマンドを使用して組織リソースの許可ポリシーを取得し、そのポリシーを 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="
}
  1. テキスト エディタで 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="
}
  1. 次のコマンドを実行して、組織リソースの許可ポリシーを更新します。
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() メソッドを使用すると、許可ポリシーを組織リソースにアタッチすることによって、ユーザーにロールを付与できます。許可ポリシーは、定義するバインディングのコレクションです。

Read-Modify-Write: 許可ポリシーなどのリソースのメタデータを更新するための一般的なパターンです。メタデータの現在の状態を読み取り、データをローカルに更新した後、変更したデータを書き込みのために送信します。このような処理は、2 つ以上の独立したプロセスが一連の操作を同時に試行する場合に競合を引き起こすことがあります。たとえば、ある 1 つのプロジェクトにオーナーが 2 人おり、両者が同時に許可ポリシーに対して競合する変更を行おうとする場合があります。この場合、一方のプロジェクト オーナーによって行われた変更が失敗する可能性があります。IAM は、許可ポリシーの etag プロパティを使用してこの問題を解決します。このプロパティは、最後のリクエスト以降に許可ポリシーが変更されたかどうかを確認するために使用されます。etag 値を使用してリクエストを送信すると、リクエスト内の 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 の下にあるプロジェクトを組織リソースに移行することをおすすめします。組織リソースへのプロジェクトの移行については、プロジェクトの移動をご覧ください。

組織のポリシーの設定については、制約の使用をご覧ください。

条件付きアクセスを許可する

組織ポリシー管理者(roles/orgpolicy.policyAdmin)などの特定の IAM ロールは、組織リソースにのみ付与できます。ポリシーの継承により、通常、このロールは組織内のすべてのリソースに継承されます。

ロールが付与されるリソースをより細かく制御するには、IAM 条件を使用します。条件付きでタグを使用すると、指定されたタグが付いている場合にのみリソースへのアクセス権を付与できます。たとえば、次の許可ポリシーでは、environment: dev タグのあるリソースにのみ組織のポリシー管理者のロールが付与され、他のリソースには付与されません。

{
  "bindings": [
    {
      "members": [
        "group:my-group@example.com"
      ],
      "role": "roles/orgpolicy.policyAdmin",
      "condition": {
          "title": "Dev_environment_only",
          "description": "Only granted in the development environment",
          "expression":
            "resource.matchTag('123456789012/env', 'dev')"
      }
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 3
}

権限のテスト

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)