【実務・中級編】 GCP IAMにおけるサービスアカウントキーの管理とローテーション – 暗号理論・認証基盤 & エンドポイントセキュリティ防御ガイド

サービスアカウントキーは「時限爆弾」だ。今すぐ「キーレス」へ移行せよ

現場でインシデント対応をしていると、いまだにGitHubのパブリックリポジトリや、Dockerイメージの中に埋め込まれた service-account-key.json を見つけてゾッとすることがある。

攻撃者にとって、サービスアカウントキーは「宝の地図」だ。一度流出すれば、君がどれほど複雑なパスワードをかけていようが、WAFで攻撃をブロックしていようが関係ない。そのキーさえあれば、彼らは「君自身」としてクラウド環境を自由に操作できるからだ。

今日は、なぜサービスアカウントキーを使い続けることがリスクなのか、そして、現代のクラウドエンジニアが選ぶべき「Workload Identity Federation(キーレス認証)」への移行戦略を、泥臭い実務の視点から解説する。

—

1. なぜ「キー」そのものが悪なのか?

公開鍵暗号(RSAや楕円曲線暗号)が堅牢なのは理解しているだろう。だが、どんなに強固な暗号化アルゴリズムも、その「鍵(秘密鍵)」を管理する運用プロセスが杜撰であれば無意味だ。

攻撃者が狙う盲点:キーのライフサイクル

サービスアカウントキーをJSONファイルとして管理する運用は、以下の3つの脆弱性を抱えている。

1. 永続性: 有効期限を無期限に設定している場合、一度流出するとキーを無効化するまで攻撃者は居座り続ける。
2. 静的性質: ローテーションを運用でカバーしようとしても、エンジニアの作業負荷が増え、結局「期限なし」や「更新忘れ」という人為的ミスが起きる。
3. 可視性: ソースコード、環境変数、CI/CDのログなど、あらゆるところにキーが露出するリスクがある。

PoCの視点:
攻撃者は、GitHubで filename:*.json "private_key_id" といったクエリを投げるだけで、世界中の漏洩キーを収集している。これを見つけた瞬間、彼らは gcloud auth activate-service-account コマンドで即座に君の環境を乗っ取る。

—

2. 脱・鍵管理:Workload Identity Federationの真髄

Workload Identity Federation(WIF)を使えば、GCP外部(GitHub ActionsやAWS、オンプレミスなど)から、「キーファイルを使わずに」GCPリソースにアクセスできる。

仕組みは簡単だ。君のシステムが信頼する「外部プロバイダー(GitHub等)」から発行されたOIDCトークンをGCPに提示し、GCP側でそのトークンを検証して短命なアクセストークンと交換する。これなら、そもそも「秘密鍵」を保存する必要がない。

実践:GitHub Actionsでのキーレス認証設定

まずはGCP側でワークロードIDプールとプロバイダーを作成し、GitHub ActionsがGCPリソースへアクセスできる権限を付与する。

GCPの設定(CLI例):

# ワークロードIDプールの作成
gcloud iam workload-identity-pools create "github-pool" \
    --location="global"

# GitHubをプロバイダーとして追加
gcloud iam workload-identity-pools providers create-oidc "github-provider" \
    --location="global" \
    --workload-identity-pool="github-pool" \
    --issuer-uri="https://token.actions.githubusercontent.com" \
    --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository"

# サービスアカウントへの権限付与(特定のレポジトリのみ許可)
gcloud iam service-accounts add-iam-policy-binding "my-sa@my-project.iam.gserviceaccount.com" \
    --role="roles/iam.workloadIdentityUser" \
    --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-pool/attribute.repository/OWNER/REPO"

—

3. アプリケーション側での実装

PythonでGCPのライブラリを使う場合、環境変数にキーパスを設定する必要はもうない。google-auth ライブラリは、環境変数 GOOGLE_APPLICATION_CREDENTIALS が指定されていない場合、自動的にWorkload Identityの認証情報を探しに行く。

Pythonサンプル(GCP Storageへのアクセス):

from google.cloud import storage

# キーファイルは不要。
# 環境でWorkload Identityが正しく設定されていれば、
# ライブラリが自動的に認証情報を取得する。
def list_buckets():
    try:
        storage_client = storage.Client()
        buckets = list(storage_client.list_buckets())
        for bucket in buckets:
            print(f"Bucket: {bucket.name}")
    except Exception as e:
        print(f"認証エラー、または権限不足: {e}")

if __name__ == "__main__":
    list_buckets()

—

4. 現場の教訓:明日からやるべきこと

私の経験上、セキュリティを強固にする最大の敵は「利便性」だ。しかし、このキーレス移行に関しては、導入すれば逆に「キーの管理から解放される」という最大のメリットがある。

エンジニアへのアクションアイテム:
1. 棚卸し: gcloud iam service-accounts keys list を実行し、現在発行されているすべてのキーをリストアップせよ。
2. 期限チェック: 1年以上更新されていないキーは、即座に削除せよ。それが君のシステムを守る最短ルートだ。
3. 移行計画: CI/CDツール(GitHub Actions, GitLab CIなど)を使っているなら、最優先でWIFへの移行をバックログに入れろ。
4. 最小権限の原則: もしキーを使わざるを得ない場合でも、そのサービスアカウントには「バケットへの読み込みのみ」など、極限まで絞ったIAMロールを付与すること。

セキュリティは「完璧な防御」を目指すのではなく、「攻撃者にとって割に合わない環境」を作ることだ。鍵というアナログな資産をクラウドから追放し、アイデンティティベースの強固な認証基盤を築いてほしい。

君のコードが、明日も安全にデプロイされることを祈っている。

コメント

タイトルとURLをコピーしました