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を有効化します。

  1. Google Cloud Consoleにログイン
  2. Kubernetes Engineセクションに移動
    • 左側のナビゲーションメニューから「Kubernetes Engine」→「クラスタ」を選択
    • 対象のクラスタ名をクリック
  3. クラスタの編集
    • 「詳細」タブで「セキュリティ」セクションを確認
    • 「Workload Identity」の横にある編集(鉛筆)アイコンをクリック
  4. Workload Identityを有効化
    • 「Workload Identityを有効にする」にチェックを入れる
    • ワークロードプールは自動的にPROJECT_ID.svc.id.googに設定される
    • 「変更を保存」をクリック
  5. 既存のノードプールを更新(重要!)
    • 既存のノードプールは自動的に更新されないため、手動で更新が必要
    • 各ノードプールに対して以下を実行:
      • ノードプール名をクリック
      • 「編集」をクリック
      • 「セキュリティ」セクションで「GKE メタデータサーバーを有効にする」にチェックを入れる
      • 変更を保存
  6. アプリケーションの設定
    • 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]"
}

 

アプリケーションでの使用方法

  1. 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

 

  1. 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機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。

参考情報

Google Cloud公式ドキュメント

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る