はじめの Google Cloud 講座⑩サービスアカウントキーを使用せずに特定のGitHub リポジトリからGoogle Cloudにアクセスする方法について説明します!

クラウド

Google Cloudと他サービスを連携する場合、以前は、サービスアカウントキーを発行する方法が広く使用されていました。しかし、サービスアカウントキーは、パスワードみたいなもので、漏洩してしまうと、自社のGoogle Cloudにアクセスすることができるようになってしまいます。

そうした、危険性を回避するために考えられたサービスがWorklod Identity 連携です。Workload Identity 連携は、IDプールと条件式を使用することで、Google Cloudへのアクセス元を限定することができます。また、IAMを使用することでアクセスできるリソースの操作を限定することができます。

今回の記事では、サービスアカウントキーの危険性とWorkload Identity 連携の設定方法について説明します。最近、私が参画したプロジェクトで、GitHubからTerraformを使用してGoogle Cloudのリソースを作成するプロジェクトに参画した経験を基に、より実践的かつセキュリティの高い構成について説明します。

ぜひ、最後までご覧いただけると嬉しいです!

Google Cloudと他クラウドやSaaSとの連携

AWSやAzureといった他クラウドやGitHubやTerraform Cloud等のSaaSとGoogle Cloudを連携したい場合、Google Cloudには、大きく2つの方法があります。

  1. サービスアカウントを作成しサービスアカウントキーを発行する
  2. Workload Identity 連携を設定する

従来は、「サービスアカウントを作成し、サービスアカウントキーを発行する方法」が使用されていました。私が、クラウドエンジニアになった当初、この方法が、広く一般的に使用されておりました。

しかし、昨年、Google Cloudがブログに投稿したある記事をきっかけに、私は、この方法を使用するのは、禁じ手に変わったと考えています。

それが、下記ブログです。

Automatically disabling leaked service account keys: What you need to know | Google Cloud Blog
Starting June 16, exposed service account keys that have been detected in services including public repos will be automa...

この記事では、以下の内容について記載されています。

漏洩したサービスアカウントキーの自動無効化

Google Cloudは、セキュリティ強化のため、2024年6月16日より、公開リポジトリなどで漏洩が検出されたサービスアカウントキーを自動的に無効化します。

主なポイント

  • 自動無効化:Google Cloudは、GitHubやGitLabなどのシークレットスキャンプログラムと連携し、公開されてしまったサービスアカウントキーを検出します。検出されたキーは自動的に無効化され、プロジェクトの所有者とセキュリティ担当者に通知が送られます。
  • オプトイン・オプトアウト:この機能は2024年6月16日から自動で有効になりますが、それ以前に手動で有効化(オプトイン)することや、現在の設定を維持するために無効化(オプトアウト)することも可能です。
  • 推奨事項:Google Cloudは、この自動無効化機能を有効にすることを強く推奨しています。

このように、サービスアカウントキーを使用した際の危険性を予防される策をGoogle Cloudが行うようになりました。

サービスアカウントキー発行の危険性

それでは、なぜ、サービスアカウントキーを発行することが危険なのかを説明します。

Google Cloudのリソースを外部環境(オンプレミスサーバー、AWSやAzureなどの他のクラウド、GitHub ActionsのようなCI/CDパイプラインなど)から利用する際、従来は「サービスアカウントキー(JSONキーファイル)」を発行し、そのキーを使って認証を行うのが一般的な方法でした。

この方法は手軽に設定できる一方で、多くの深刻なセキュリティリスクを内包しており、現在では可能な限り避けるべきアプローチとされています。なぜサービスアカウントキーの発行は危険なのでしょうか。その理由は大きく分けて3つあります。

1. 認証情報漏洩のリスク

サービスアカウントキーは、一度発行されると「永続的な認証情報」となります。これは、有効期限がなく、ローテーション(更新)や削除をしない限り、誰でもどこからでも利用できてしまうことを意味します。この「永続的な認証情報」が、漏洩のリスクを著しく高めます。

  • ソースコードへの混入:最も多い漏洩原因の一つが、誤ってキーファイルをGitリポジトリにコミットしてしまうことです。特にPublicリポジトリに公開してしまった場合、悪意のある攻撃者に即座に検知され、不正アクセスの踏み台にされてしまいます。
  • 設定ファイルや環境変数からの漏洩:アプリケーションの設定ファイルやCI/CDの環境変数にキー情報を平文で保存した場合、サーバーへの不正アクセスや設定ミスによって、キー情報が外部に漏れる可能性があります。
  • 開発者のローカル環境からの漏洩:開発者のPCにダウンロードされたキーファイルが、マルウェア感染などによって盗み出されるケースも考えられます。

一度漏洩したキーは、攻撃者にとってGoogle Cloud環境への「合鍵」となり、データの窃取、リソースの破壊、高額なコンピューティングリソースの不正利用など、甚大な被害を引き起こす可能性があります。

2. 鍵管理の煩雑な運用負荷

漏洩リスクを低減するためには、サービスアカウントキーを定期的にローテーション(古いキーを無効化し、新しいキーを発行して入れ替える)することが不可欠です。しかし、この鍵管理は非常に大きな運用負荷を伴います。

  • 手動ローテーションの形骸化:システムの数が少ないうちは手動でも管理できるかもしれませんが、規模が拡大するにつれて、どのキーがどのシステムで利用されているのかを正確に把握することが困難になります。結果として、ローテーション作業が忘れられたり、サービス停止を恐れて古いキーを削除できなくなったりするケースが頻発します。
  • 自動化の複雑さ:ローテーションを自動化する仕組みを自前で構築することも可能ですが、その開発・維持にもコストがかかります。

このように、鍵管理の運用は複雑で手間がかかり、ヒューマンエラーが発生しやすいポイントです。管理されていない「野良キー」が増えるほど、セキュリティホールが増え続けることになります。

3. 過剰な権限付与と監査の困難さ

サービスアカウントには、IAM(Identity and Access Management)を通じてロール(権限)が付与されます。キーが漏洩した際の被害を最小限に抑えるためには、「最小権限の原則」に従い、そのキーに紐づくサービスアカウントには必要最小限の権限のみを与えるべきです。

しかし、実際には開発の便宜上、本来必要な権限よりも広い権限(例えば「編集者」ロールなど)を付与してしまうことが少なくありません。この状態でキーが漏洩すると、攻撃者はその強力な権限を行使し、プロジェクト全体に深刻なダメージを与えることができます。

また、キーが一度外部のシステムに渡ってしまうと、そのキーを「誰が」「いつ」「どこから」利用しているのかをGoogle Cloud側から正確に追跡することが難しくなります。不正な利用を検知したり、インシデント発生時に原因を特定したりすることが困難になるのです。

Workload Identity 連携について

ここまで見てきたように、サービスアカウントキーを利用した認証は、漏洩、管理、権限、監査という多岐にわたる深刻なリスクを抱えています。これらのリスクは、人為的なミスや運用負荷の高さに起因することが多く、注意深く運用しても完全になくすことは困難です。

では、私たちはキーを発行するという危険な行為をやめ、どのようにして外部ID(AWSのロール、GitHub Actionsのジョブなど)にGoogle Cloudへのアクセスを許可すれば良いのでしょうか?

その答えがWorkload Identity 連携です。Workload Identity 連携は、サービスアカウントキーのような永続的な認証情報を使わずに、外部IDに対して短期間だけ有効なアクセストークンを発行することで、安全な認証を実現する仕組みです。

次の章では、このWorkload Identity 連携がどのようにしてサービスアカウントキーのリスクを根本的に解決するのか、具体的な設定方法を詳しく解説していきます。

Workload Identity 連携の設定方法

それでは、Workload Identity 連駅の設定方法についてご説明します。

今回、GitHubの特定のリポジトリからGoogle Cloudにアクセスする方法を設定します。GitHub ActionsでCI/CDを構築する際、特定のリポジトリからのCI/CDを許可する設定になります。

IDプールの作成

Google Cloudコンソールのサイドバーから「IAM と管理」→「Workload Identity 連携」を選択します。

Workload Identity プールの画面で、「開始」を選択します。

名前を任意で設定します。今回は、githubと接続するので、githubにしています。

  • 名前:github(任意)
  • 説明:任意
入力後、「続行」を選択します。

以下の設定を行います。プロバイダの選択と発行元(URL)は正しく選択、入力してください。

  • プロバイダの選択:OpenID Connect (OIDC)
  • プロバイダ名:GitHub(任意)
  • 発行元:https://token.actions.githubusercontent.com
  • オーディエンス:デフォルトとのオーディエンス

上記設定は、以下、GitHubのドキュメントを参考にしています

Google Cloud Platform での OpenID Connect の構成 - GitHub Docs
ワークフロー内で OpenID Connect を使用して、Google Cloud Platform での認証を行います。

入力後、「続行」を選択します。

GitHubのRepository IDの調べ方

次の「プロバイダの属性を構成する」を行う前に、GitHub リポジトリのRepository IDの調べ方について説明します。

GItHubで、Terraformのコードを保存するリポジトリに移動します。

Chormeのメニューバーの「表示」→「開発/管理」→「ソースを表示」を選択します。

ソースが表示されたら、検索窓を表示し、「repository_id」で検索してください。

repository_idの次に表示されているcontent=に表示されている数字がRepository IDになります。

以上で、GitHub リポジトリのRepository IDの調べ方は以上になります。

IDプールの作成(続き)

それでは、IDプールの作成の続きを行っていきます。

次は、プロバイダの属性条件を構成します。以下の設定を行います。(属性条件については、後で説明します。)

  • OIDC 1:assertion.sub
  • Google 2:attribute.repository_id
  • OIDC 2:assertion.repository_id
  • 条件CEL:assertion.repository_id == ‘Repository ID’
    ※Repository IDは、先程調べたGitHub リポジトリのRepository IDを入力します。

上記入力後、保存を選択します。

CEL式については、以下URLを参照してください。

Workload Identity 連携  |  IAM Documentation  |  Google Cloud

正常にIDプールが作成されると以下の画面のようになります。

属性条件

上記で設定した属性条件について、説明します。属性条件とは、アクセスを許可する相手が、本当に信頼できる相手かどうかを細かく見極めるためのルールです。

Workload Identity 連携では、外部のIDプロバイダ(IdP)が発行する「IDトークン」という一種の身分証明書を使って認証を行います。属性条件は、この身分証明書に書かれている情報(属性)をチェックして、「この条件を満たしていなければ、アクセスは許可しない」という関所のような役割を果たします。

属性条件の具体例

属性条件は、IDトークンに含まれる「属性」と呼ばれる情報を使って設定します。GitHub Actionsを例に、よく使われる属性と条件式の例を説明します。

IDトークンには、以下のような情報が含まれています。

  • repository:リクエスト元のリポジトリ名 (例:my-github/my-repository)
  • ref:ブランチ名やタグ名 (例:refs/heads/main)
  • repository_owner:リポジトリのオーナー名 (例::my-github)
  • repository_id:リポジトリのID (例:0123456789)

これらの属性を使って、以下のような条件式を作成します。

例1:特定のリポジトリからのアクセスのみを許可する
attribute.repository == 'my-github/my-repository'

この条件は、「my-githubという組織のmy-repositoryというリポジトリからのアクセス以外は拒否する」というルールです。これにより、他のテスト用リポジトリなどからのアクセスを防ぎます。

例2:特定の組織の、mainブランチからのアクセスのみを許可する
attribute.repository_owner == 'my-github' && attribute.ref == 'refs/heads/main'

この条件は、「my-githubという組織」の、かつ「mainブランチ」からのアクセスのみを許可するという、より厳しいルールです。本番環境へのデプロイなど、特に重要な操作を特定のブランチからのみに限定したい場合に有効です。

属性条件のまとめ

Workload Identity連携における属性条件は、単なる認証の一歩先を行く、アクセス元の正当性を厳密に検証するための重要なセキュリティ機能です。

  • 関所のように、信頼できる相手かを見極めるルール
  • 最小権限の原則を実現し、意図しないアクセスを防止する
  • 「どのリポジトリから」「どのブランチから」といった具体的な条件でアクセスを制御できる

この属性条件を正しく設定することで、外部サービスとの連携をセキュアに保ち、安心してシステムを運用することができます。Workload Identity 連携を利用する際は、必ずこの属性条件を活用するようにしましょう。

IAMの設定

次は、作成したIDプールにIAMの設定を行います。以前は、Worklod Identity 連携用のサービスアカウントを作成する必要がありましたが、バージョンアップしたことで、IDプール自体にIAMの設定を行うことができます。

VPC Service Controlsを使用している場合は、サービスアカウント使用して、そのサービスアカウントに対してIAMの設定を行う必要があります。こちらについては、また別のブログで紹介しようと思います。

IAMを設定するリソースを開きます。今回は、プロジェクトに対してIAMの設定をします。

作成したIDプールをコピーします。

プロジェクトのIAMを開き、「アクセスを許可」を選択します。

新しいプリンシパルに、先程コピーしたIDプールをペーストで貼り付け、必要なロールを選択し保存します。

正常にIAMの設定ができました。

これで、GitHubのリポジトリからCI/CDでアクセスした際、Google CloudのIAMを使用してリソースを操作できます。なお、今回は説明のため、IDプールに閲覧者ロールを付与しています。閲覧者ロールの場合、リソースの閲覧しかできませんので、Terraform等でリソースを作成する場合は、リソースの管理者ロール等を付与してください。

以上で、Workload Identity 連携の設定方法は終わりになります。Workload Identity 連携を使用することでサービスアカウントキーを発行せず、Google Cloudの各種操作を行うことができます。

まとめ

今回は、下記3点についてお話しました。

  1. Google Cloudと他クラウドやSaaSとの連携
  2. サービスアカウントキー発行の危険性
  3. Workload Identity 連携の設定方法

Workload Identity 連携 を利用することで、サービスアカウントキーを発行することなく、他のクラウドやSaaSと安全に連携できます。サービスアカウントキーを使用すると、意図せぬ情報漏えいにより、自社の Google Cloud 環境からデータが盗まれるリスクがありますが、Workload Identity 連携 によりそのリスクを大幅に軽減できます。セキュリティ強化の観点からも、ぜひ本記事で紹介した設定方法を参考に、導入を検討してみてください。

これからも、Macのシステムエンジニアとして、日々、習得した知識や経験を発信していきますので、是非、ブックマーク登録してくれると嬉しいです!

それでは、次回のブログで!

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