GCP GKEクラスタでのWorkload Identityの有効化手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、 「どうやって直すのか?」 という具体的な修復手順(コンソール、gcloud CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、GKEクラスタでWorkload Identity機能が無効化されている問題について、リスクと対策を解説します。

ポリシーの説明
GKEクラスタでWorkload Identity Federation(旧Workload Identity)が有効になっているかをチェックします。Workload Identityは、GKEワークロードがGoogle Cloudサービスに安全にアクセスするためのGoogleの推奨方法です。この機能により、サービスアカウントキーの管理が不要になり、きめ細かいアクセス制御が可能になります。
修復方法
コンソールでの修復手順
Google Cloud コンソールを使用して、Workload Identityを有効化します。
- Google Cloud Consoleにログイン
- Google Cloud Consoleにアクセス
- 対象のプロジェクトを選択
- Kubernetes Engineセクションに移動
- 左側のナビゲーションメニューから「Kubernetes Engine」→「クラスタ」を選択
- 対象のクラスタ名をクリック
- 左側のナビゲーションメニューから「Kubernetes Engine」→「クラスタ」を選択
- クラスタの編集
- 「詳細」タブで「セキュリティ」セクションを確認
- 「Workload Identity」の横にある編集(鉛筆)アイコンをクリック
- Workload Identityを有効化
- 「Workload Identityを有効にする」にチェックを入れる
- ワークロードプールは自動的に
PROJECT_ID.svc.id.goog
に設定される - 「変更を保存」をクリック
- 既存のノードプールを更新(重要!)
- 既存のノードプールは自動的に更新されないため、手動で更新が必要
- 各ノードプールに対して以下を実行:
- ノードプール名をクリック
- 「編集」をクリック
- 「セキュリティ」セクションで「GKE メタデータサーバーを有効にする」にチェックを入れる
- 変更を保存
- アプリケーションの設定
- Kubernetesサービスアカウントを作成し、Google Cloudサービスアカウントにバインド
- Podでそのサービスアカウントを使用するよう設定
Terraformでの修復手順
Workload Identityを有効化したGKEクラスタを作成するTerraformコードです。
# 必要なAPIを有効化
resource "google_project_service" "required_apis" {
for_each = toset([
"container.googleapis.com",
"iamcredentials.googleapis.com"
])
service = each.key
disable_on_destroy = false
}
# Workload Identity対応のGKEクラスタ
resource "google_container_cluster" "primary" {
name = "secure-gke-cluster"
location = var.region
# Workload Identityをクラスタレベルで有効化
workload_identity_config {
workload_pool = "${var.project_id}.svc.id.goog"
}
# デフォルトノードプールを削除
remove_default_node_pool = true
initial_node_count = 1
# プライベートクラスタ設定(推奨)
private_cluster_config {
enable_private_nodes = true
enable_private_endpoint = false
master_ipv4_cidr_block = "172.16.0.0/28"
}
depends_on = [google_project_service.required_apis]
}
# Workload Identity対応のノードプール
resource "google_container_node_pool" "primary_nodes" {
name = "primary-pool"
location = var.region
cluster = google_container_cluster.primary.name
node_count = var.node_count
node_config {
# ノードでWorkload Identityを有効化
workload_metadata_config {
mode = "GKE_METADATA"
}
# レガシーメタデータエンドポイントを無効化
metadata = {
disable-legacy-endpoints = "true"
}
machine_type = var.machine_type
# 最小権限のカスタムサービスアカウントを使用
service_account = google_service_account.node_sa.email
oauth_scopes = [
"<https://www.googleapis.com/auth/cloud-platform>"
]
# Shielded VMの設定
shielded_instance_config {
enable_secure_boot = true
enable_integrity_monitoring = true
}
}
management {
auto_repair = true
auto_upgrade = true
}
}
# ノード用サービスアカウント(最小権限)
resource "google_service_account" "node_sa" {
account_id = "gke-node-sa"
display_name = "GKE Node Service Account"
}
# ノードサービスアカウントに必要最小限の権限を付与
resource "google_project_iam_member" "node_sa_roles" {
for_each = toset([
"roles/logging.logWriter",
"roles/monitoring.metricWriter",
"roles/monitoring.viewer",
])
project = var.project_id
role = each.key
member = "serviceAccount:${google_service_account.node_sa.email}"
}
# アプリケーション用のGoogle Cloudサービスアカウント例
resource "google_service_account" "app_sa" {
account_id = "app-workload-sa"
display_name = "Application Workload Service Account"
}
# アプリケーションに必要な権限を付与
resource "google_project_iam_member" "app_sa_role" {
project = var.project_id
role = "roles/storage.objectViewer" # 例:Cloud Storage読み取り権限
member = "serviceAccount:${google_service_account.app_sa.email}"
}
# Kubernetesサービスアカウント(KSA)とGoogle Cloudサービスアカウント(GSA)のバインディング
resource "google_service_account_iam_member" "workload_identity_binding" {
service_account_id = google_service_account.app_sa.name
role = "roles/iam.workloadIdentityUser"
member = "serviceAccount:${var.project_id}.svc.id.goog[default/app-ksa]"
}
アプリケーションでの使用方法
- Kubernetesサービスアカウントの作成
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-ksa
namespace: default
annotations:
iam.gke.io/gcp-service-account: app-workload-sa@PROJECT_ID.iam.gserviceaccount.com
- Podでサービスアカウントを使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: workload-identity-app
spec:
replicas: 1
selector:
matchLabels:
app: wi-app
template:
metadata:
labels:
app: wi-app
spec:
serviceAccountName: app-ksa # 作成したKSAを指定
containers:
- name: app
image: gcr.io/PROJECT_ID/my-app:latest
# アプリケーションは自動的にGSAの権限でGoogle Cloud APIにアクセス可能
まとめ
この記事では、GCP GKEクラスタでWorkload Identity機能が無効化されている問題について、リスクと対策を解説しました。
既存からの切り替えについては一定ののコストがかかりますが、サービスアカウントキーを利用しなくて良くなり、最小権限でのアクセスが実現できるためメリットは大きいと考えられます。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。