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 つ以上の役割を付与できます。
事前定義ロールを使用する
次の表に、組織リソースのプロパティへのアクセス権を付与できるロール、このロールが行うことの説明、このロールに組み込まれている権限を示します。
| ロール | 権限 |
|---|---|
組織管理者( IAM ポリシーを管理し、組織、フォルダ、プロジェクトの組織のポリシーを表示するためのアクセス権。 このロールを付与できる最下位レベルのリソース:
|
|
組織閲覧者( 組織を閲覧するための権限を付与します。 このロールを付与できる最下位レベルのリソース:
|
|
組織ポリシー管理者( 組織のポリシーによるクラウド リソースの構成制限を定義する権限を付与します。 このロールを付与できる最下位レベルのリソース:
|
|
ブラウザ( フォルダ、組織、許可ポリシーなど、プロジェクトの階層を参照するための読み取りアクセス権。この役割には、プロジェクトのリソースを表示する権限は含まれていません。 このロールを付与できる最下位レベルのリソース:
|
|
カスタムロールの作成
このトピックで説明した事前定義の役割を使用するだけでなく、必要に応じて権限を調整してカスタムロールを作成することもできます。Resource Manager で使用するカスタムロールを作成する場合には、次の点に注意してください。resourcemanager.projects.get/listなどのリスト権限と取得権限は、必ずペアで付与する必要があります。- カスタムロールに
folders.list権限とfolders.get権限を含める場合は、projects.listとprojects.getも含める必要があります。 - 組織、フォルダ、および
プロジェクト リソースに対する
setIamPolicy権限を使用すると、ユーザーに他のすべての権限も付与されます。この権限を割り当てる場合には十分に注意してください。
組織リソースの既存のアクセス権を表示する
組織リソースに対してどのような役割がユーザーに付与されているかを確認するには、そのリソースの許可ポリシーを取得します。組織リソースの許可ポリシーは、
コンソール、Google Cloud CLI、
または getIamPolicy()
メソッドを使用して表示できます。 Google Cloud
コンソール
コンソールを使用して組織リソースレベルで付与されたロールを表示するには: Google Cloud
コンソールで [リソースの管理] ページに移動します。 Google Cloud
[組織] プルダウン メニューで、組織リソースを選択します。
組織リソースのチェックボックスをオンにします。
[情報パネル] の [権限] で、[展開] をクリックして役割を表示し、その役割を持つすべてのメンバーを表示します。
gcloud
get-iam-policy コマンドを使用して組織リソースの許可ポリシーを取得します。
gcloud alpha organizations get-iam-policy <var>ORGANIZATION_ID</var> --format json >
<var>FILENAME.JSON</var>
このコマンドは、次のような許可ポリシーを出力します。
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
コンソールで [リソースの管理] ページに移動します。 Google Cloud
[組織] プルダウン メニューで、組織リソースを選択します。
組織リソースのチェックボックスをオンにします。フォルダ リソースがない場合、組織リソースは表示されません。続行するには、 IAM ページでロールを付与する手順をご覧ください。
右側の [情報パネル] が表示されていない場合は、右上隅にある [情報パネルを表示] をクリックします。
[情報パネル] の [権限] タブで、 [メンバーを追加] をクリックします。
[新しいメンバー] フィールドに、追加するチームメンバーを入力します。 ユーザー アカウントのメールアドレス、Google グループ、サービス アカウント、G Suite ドメインを指定できます。
[ロールを選択] プルダウン メニューで、チームメンバーに付与するロールを選択します。
[追加] をクリックします。
gcloud
gcloud コマンドを使用して組織リソースの許可ポリシーを設定するには:
get-iam-policyコマンドを使用して組織リソースの許可ポリシーを取得し、そのポリシーを JSON ファイルに出力します。gcloud alpha organizations get-iam-policy <var>ORGANIZATION_ID</var> --format json > <var>FILENAME.JSON</var>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="
}
- テキスト エディタで JSON ファイルを開きます。次に、
bindings配列に新しいエントリを追加して、組織管理者を定義します。たとえば、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="
}
- 次のコマンドを実行し、組織リソースの許可ポリシーを更新します。
gcloud alpha organizations set-iam-policy <var>ORGANIZATION_ID</var> 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 つ以上の独立したプロセスが同時にシーケンスを試行すると、競合が発生する可能性があります。たとえば、2 人のプロジェクト オーナーが許可ポリシーに対して競合する変更を同時に行おうとすると、一方のオーナーの変更が失敗する可能性があります。IAM は、許可ポリシーの etag プロパティを使用してこの問題を解決します。このプロパティは、最後のリクエスト以降に許可ポリシーが変更されたかどうかを確認します。etag 値を使用してリクエストを行うと、リクエスト内の etag 値と、ポリシーに関連付けられている既存の etag 値が比較されます。etag 値が一致した場合にのみ許可ポリシーを書き込みます。
許可ポリシーを更新するときには、最初に getIamPolicy() を使用して許可ポリシーを取得し、許可ポリシーを更新してから setIamPolicy() を使用してその許可ポリシーを書き込みます。許可ポリシーを設定するときに etag 値を使用するのは、GetPolicyResponse 内の対応する許可ポリシーに etag 値が含まれている場合のみです。
Python
setIamPolicy() メソッドを使用すると、許可ポリシーをリソースに接続できます。setIamPolicy メソッドでは、設定する許可ポリシーとその許可ポリシーを接続するリソースが含まれている SetIamPolicyRequest が使用されます。これにより、結果の許可ポリシーが返されます。許可ポリシーを更新する場合は、
read-modify-write パターン
に従うことをおすすめします。setIamPolicy()
組織リソースの許可ポリシーを設定するサンプルコードを次に示します。
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 Conditions を使用します。条件で
タグを使用すると、指定した
タグが付いている場合にのみリソースへのアクセス権を付与できます。たとえば、次の許可ポリシーでは、environment: dev タグが付いているリソースにのみ組織ポリシー管理者ロールを付与し、他のリソースには付与しません。
{
"bindings": [
{
"members": [
"{dynamic print variables.examples.principal_group_api}"
],
"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 と権限のセットを入力として受け取ります。ユーザーがアクセスできる権限のサブセットが返されます。
一般的に、コンソールを使用して権限を直接管理している場合、testIamPermissions()は呼び出しません。Google Cloud 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)