Google Cloud(GCP)の運用において、サービスアカウントの不適切な管理は、認証情報の漏洩や過剰な権限付与によるセキュリティリスクに直結します。特に、サービスアカウントキー(JSONファイル)のローカル保存やGitへの誤コミットは、重大なインシデントの原因となります。
本記事では、実務でサービスアカウントを安全に管理・運用するための具体的な手法、キーレス認証(Workload Identity)の設定例、およびセキュリティチェックリストを解説します。
対象読者
- Google Cloud環境の設計・構築を行うインフラエンジニア、セキュリティ担当者
- サービスアカウントのキー管理に不安があり、安全な代替手段を探している開発者
1. サービスアカウント管理における「アンチパターン」と「推奨パターン」
実務でよく見られる不適切な設定と、それを改善するための推奨パターンの比較です。
| 項目 | アンチパターン(避けるべき設計) | 推奨パターン(安全な設計) |
|---|---|---|
| 認証情報の管理 | サービスアカウントキー(JSON)を発行してローカルやサーバーに配置する | Workload Identity やサービスアカウントの権限借用(Impersonation)を使用する |
| 権限の付与範囲 | プロジェクト全体に対して「編集者(Editor)」や「オーナー(Owner)」を付与する | 最小権限の原則に従い、必要なリソースに対してカスタムロールや定義済みの最小ロールを付与する |
| キーのライフサイクル | 一度作成したキーを無期限で使い続ける | キーの作成を組織ポリシーで禁止し、やむを得ず使用する場合は自動ローテーションを導入する |
2. キーレス認証の実装:Workload Identity 連携の設定手順
外部環境(GitHub Actionsなど)からGoogle Cloudリソースにアクセスする場合、サービスアカウントキーを発行せず、OIDC(OpenID Connect)を用いた「Workload Identity 連携」を使用することが推奨されます。
以下に、GitHub ActionsからGoogle Cloudの特定リソースにアクセスするための設定手順を示します。
2.1. gcloudコマンドによる設定例
環境変数として以下の値を定義した上で実行してください。
# 環境変数の定義(実際の環境に合わせて変更してください)
export PROJECT_ID="your-gcp-project-id"
export WORKPOOL_NAME="github-actions-pool"
export PROVIDER_NAME="github-actions-provider"
export GITHUB_REPO="your-github-username/your-repo-name"
export SA_NAME="github-actions-sa"
# 1. Workload Identity プールの作成
gcloud iam workload-identity-pools create "${WORKPOOL_NAME}" \
--project="${PROJECT_ID}" \
--location="global" \
--display-name="GitHub Actions Pool"
# 2. Workload Identity プロバイダの作成
gcloud iam workload-identity-pools providers create-oidc "${PROVIDER_NAME}" \
--project="${PROJECT_ID}" \
--location="global" \
--workload-identity-pool="${WORKPOOL_NAME}" \
--display-name="GitHub Actions Provider" \
--issuer-uri="https://token.actions.githubusercontent.com" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository"
# 3. 専用のサービスアカウントを作成
gcloud iam service-accounts create "${SA_NAME}" \
--project="${PROJECT_ID}" \
--display-name="GitHub Actions Service Account"
# 4. サービスアカウントとWorkload Identityプロバイダの紐付け(特定のGitHubリポジトリのみに権限を制限)
gcloud iam service-accounts add-iam-policy-binding "${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/$(gcloud projects describe ${PROJECT_ID} --format='value(projectNumber)')/locations/global/workloadIdentityPools/${WORKPOOL_NAME}/attribute.repository/${GITHUB_REPO}"
2.2. GitHub Actions ワークフローでの利用例
上記の設定完了後、GitHub ActionsのYAMLファイルで以下のように google-github-actions/auth を使用して認証します。
name: Deploy to Google Cloud
on:
push:
branches:
- main
permissions:
contents: read
id-token: write # OIDCトークンの取得に必要
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: 'projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider'
service_account: 'github-actions-sa@<PROJECT_ID>.iam.gserviceaccount.com'
- name: Run gcloud CLI
run: |
gcloud s3-like-storage-or-other-services (実際の操作コマンド)
※ <PROJECT_NUMBER> および <PROJECT_ID> は、ご自身の環境の値に置き換えてください。
3. 組織ポリシーによるサービスアカウントキー発行の禁止
組織全体、または特定のフォルダ・プロジェクト配下で、サービスアカウントキー(JSON)の新規作成を強制的に禁止することができます。これにより、開発者が誤ってキーを発行するリスクを根本から防ぎます。
設定方法(gcloudコマンド)
プロジェクトレベルでキーの作成を禁止する場合、以下のコマンドを実行します。
gcloud resource-manager org-policies disable-enforce \
iam.disableServiceAccountKeyCreation \
--project="your-gcp-project-id"
# 注意: 完全に禁止を有効化する場合は、enable-enforce または set-policy を使用します。
組織ポリシーを適用する際は、既存のシステムでサービスアカウントキーが使用されていないか事前に確認し、段階的に移行を行ってください。
4. サービスアカウント安全管理チェックリスト
本番環境や検証環境のセキュリティ水準を維持するために、以下の項目を定期的に確認してください。
- キーの原則禁止: 新規のサービスアカウントに対して、JSONキーを発行していないか?
- Workload Identityの利用: 外部サービス(GitHub Actions, AWS, Azure等)との連携にWorkload Identityを使用しているか?
-
最小権限の原則: サービスアカウントに「オーナー」や「編集者」などの広範なロールではなく、業務に必要な最小限のロール(例:
roles/storage.objectViewerなど)のみを付与しているか? -
権限借用(Impersonation)の活用: 開発者がローカル環境から操作する際、直接キーを使用せず、
gcloud config set auth/impersonate_service_accountを使用して一時的に権限を借用しているか? - 不要なアカウントの無効化: 過去90日以上使用されていないサービスアカウントや、退職・異動した開発者に関連するアカウントが残っていないか?(Recommender API等で確認可能)
5. 導入時の注意点とトラブルシューティング
5.1. 権限借用(Impersonation)時のエラー
事象: gcloud コマンドでサービスアカウントの権限借用を設定した際、Permission denied エラーが発生する。
原因: 操作を実行するユーザー(または元のサービスアカウント)に、対象サービスアカウントに対する roles/iam.serviceAccountTokenCreator(サービス アカウント トークン作成者)ロールが付与されていない可能性があります。
対策: 以下のコマンドで、操作元ユーザーに対して権限を付与してください。
gcloud iam service-accounts add-iam-policy-binding "target-sa@${PROJECT_ID}.iam.gserviceaccount.com" \
--member="user:developer@example.com" \
--role="roles/iam.serviceAccountTokenCreator"
5.2. API仕様の変更に関する注意
Google CloudのIAM仕様やGitHub Actionsの仕様は変更される可能性があります。本番環境への導入にあたっては、必ず最新の Google Cloud IAM 公式ドキュメント を確認してください。
まとめ
サービスアカウントキーの管理は、Google Cloudのセキュリティにおいて最も重要な要素の一つです。Workload Identity 連携やサービスアカウントの権限借用を標準の設計パターンとして採用し、組織ポリシーでキーの発行を制限することで、安全なクラウド運用を実現してください。