これは ZOZO Advent Calendar 2024 カレンダー Vol.9 の 8日目の記事です。
はじめに
本記事では、IAM Deny Policyを導入する際に、特定のドメインを持つアカウントのみを対象にルールを適用する方法をご紹介します。
ここではGoogle WorkspaceやCloud Identityを利用してGoogleアカウントを管理し、Googleアカウントが特定のドメインを持つケースを前提としています。
IAM Deny Policyとは
Identity and Access Management(IAM)のDeny Policyを導入すると、指定したGoogle Cloudリソースへのアクセスにガードレールを設定できます。
例えば、Organiaztion全体で特定のリソースに対する特定の権限を拒否するDeny Policyを導入したとします。Deny Poilcyの導入によりOrganization配下のProject内で権限が付与されていたとしても、権限を使用できないという状態になります。
IAM Deny Policyについての詳細は公式ドキュメントをご参照ください。
特定ドメインを持つアカウントにDeny Poilcyを適用する方法
IAM v1 APIとIAM v2 APIの違い
通常のAllow Policy(権限付与)の適用にはIAM v1 APIを利用します。一方で、Deny Policy(権限拒否)を適用するには、IAM v2 APIを利用する必要があります。
IAM v1 APIとIAM v2 APIではプリンシパルタイプごとの識別子が異なります。
IAM v1 APIでは特定のドメインを指定することが可能ですが、IAM v2 APIでは直接的にドメインを指定することができません。
例えば、OrganizationのGoogleアカウントがhoge.comというドメインを持っていたとします。この場合、IAM v1 APIを利用するAllow Policyでは次のように適用対象として特定ドメインを持つアカウントを指定可能です。
domain:hoge.com
IAM v2 APIで特定のドメインに紐づくGoogleアカウントを対象とする場合は、ドメインの代わりにCloud IdentityのCUSTOMER_IDを指定する必要があります。このCUSTOMER_IDはGoogle WorkspaceやCloud Identityに申し込むとアカウントに対して一意に割り当てられるようになっています。
IAM v2 APIを利用するDeny Policyでは。次のように対象のドメインに紐付くCUSTOMER_IDを適用対象とすることで、特定ドメインを持つアカウントを指定可能です。
principalSet://goog/cloudIdentityCustomerId/<CUSTOMER_ID>
またCUSTOMER_IDは次のコマンドで確認可能です。
gcloud organizations list
# ↓出力例
DISPLAY_NAME ID DIRECTORY_CUSTOMER_ID
hoge.com <ORGANIZATION_ID> <CUSTOMER_ID>
特定ドメインへのDeny Policyの適用
特定ドメインへのDeny PolicyのTerraformでの適用例が以下になります。
ここではgcloud CLIのコマンドで取得したCUSTOMER_IDをCloud Secret Managerに保存し、dataリソースとして参照しています。
Organization自体はgoogle_organizationリソースとして参照でき、リソースの属性としてCUSTOMER_IDを取得することもできるので、どちらの方法も取れるかと思います。
resource "google_secret_manager_secret" "organization-customer-id" {
secret_id = "organization_customer_id"
replication {
auto {}
}
}
data "google_secret_manager_secret_version" "organization_customer_id" {
secret = google_secret_manager_secret.organization-customer-id.id
version = "latest"
}
resource "google_iam_deny_policy" "deny-bigquery-run-job" {
for_each = toset([
"apply-deny-policy-target-project-id",
])
parent = urlencode("cloudresourcemanager.googleapis.com/projects/${each.value}")
name = "deny-bigquery-run-job"
display_name = "Deny BigQuery Run Job"
rules {
deny_rule {
denied_principals = ["principalSet://goog/cloudIdentityCustomerId/${data.google_secret_manager_secret_version.organization_customer_id.secret_data}"]
denied_permissions = [
"bigquery.googleapis.com/jobs.create",
]
}
}
}
上記をapplyすると対象プロジェクト内で特定ドメインを持つアカウントにIAM Deny Policyを導入できます。
ここではapply-deny-policy-target-project-idのProject内では、指定したCUSTOMER_IDに紐付くドメインを持つGoogleアカウントはBigQueryのJobを作成することができなくなります。