パイプラインでサービス アカウントを使用するためのベスト プラクティス

デプロイ パイプラインを使用すると、コードまたはビルド済みアーティファクトを取得して Google Cloud 環境にデプロイするプロセスを自動化できます。また、Google Cloud コンソールまたは Google Cloud CLI などの対話型ツールを使用する代わりになります。

デプロイ パイプラインは、Google Cloud コンソールや gcloud CLI などの対話型ツールと Identity and Access Management の相互作用方法が異なります。Google Cloud リソースを保護する場合は、これらの違いを考慮する必要があります。

Google Cloud は、ユーザーがリソースにアクセスする前にアクセス チェックを行います。このチェックを実行するために、IAM は通常、次のことを考慮します。

  • ユーザー ID
  • アクセスしようとしているリソースと、その IAM の許可ポリシーと拒否ポリシー
  • リクエストのコンテキスト(場合により日時や場所など)

デプロイ パイプラインでは、Google Cloud APIs を直接呼び出すことはあまりありません。代わりに、ツールを使用して Google Cloud リソースにアクセスします。Google Cloud コンソールや gcloud CLI などのツールでは、まず、リソースにアクセスするためのツールを承認する必要があります。この承認を行うことで、API 呼び出しを行うときに ID を使用する権限がツールに付与されます。

Google Cloud コンソールや gcloud CLI と同様に、デプロイ パイプラインはユーザーに代わって動作します。つまり、ソースコードとして表された変更を Google Cloud にデプロイします。ただし、Google Cloud コンソールや gcloud CLI とは異なり、デプロイ パイプラインは通常、デプロイの実行に ID を使用しません。

  1. 通常、ユーザーはデプロイ パイプラインを直接操作しません。代わりに、コードの変更をソース リポジトリに push するか、コードレビューを承認することで、ソース管理システム(SCM)を操作します。

  2. デプロイ パイプラインは、送信されたコード変更を SCM システムから読み取り、Google Cloud にデプロイします。

    デプロイを行う場合、デプロイ パイプラインは通常、次の理由によりユーザーの ID を使用できません。

    1. ソースコードとそのメタデータは、作成者であることを示さないかもしれませんし、作成者情報が改ざん防止されていない場合もあります(Git commit が署名されていない場合など)。
    2. ソースコードの送信に使用した ID が Google ID と異なり、2 つの ID をマッピングできない場合があります。

    したがって、ほとんどのデプロイ パイプラインは、サービス アカウントを使用して独自の ID でデプロイを行います。

  3. デプロイ パイプラインが Google Cloud にアクセスする場合、IAM は、ユーザー アカウントの ID ではなく、パイプラインで使用されるサービス アカウントの ID のみに基づいてアクセスを許可または拒否します。

デプロイ パイプライン

デプロイ パイプラインでサービス アカウントを使用して Google Cloud にアクセスできるようにすると、次のようなメリットがあります。

  • サービス アカウントのライフサイクルは、ユーザー アカウントのライフサイクルから切り離されます。サービス アカウントを使用するようにパイプラインを構成すると、コードの作成者が組織内にいない場合でも、コードをデプロイできます。
  • デプロイ パイプラインを使用してリソースを管理する場合、リソースへのアクセス権をユーザーに付与する必要はありません。また、権限を読み取り専用アクセスに制限することもできます。このアプローチにより、IAM ポリシーの管理が容易になり、デプロイ パイプラインを使用してユーザーにすべての変更を行わせることができます。

ただし、サービス アカウントを使用すると、新たな脅威も生まれます。たとえば、次のようなものが挙げられます。

  • なりすまし: 不正な行為者はデプロイ パイプラインの ID を偽装したり、リソースにアクセスするための認証情報を盗んだりする可能性があります。
  • 権限昇格: パイプラインがだまされて想定外のアクションの実行をしてしまい、事実上混乱した代理になる可能性があります。
  • 否認防止: パイプラインがオペレーションを実行した後、その操作が行われた理由や、どのデベロッパーまたはコードの変更によってトリガーされたのかを再構築するのが難しい場合があります。
  • 改ざん: クラウド環境の整合性やセキュリティが侵害され、パイプラインが悪用される可能性があります。
  • 情報開示: 不正な行為者がデプロイ パイプラインを使用して機密データを抽出しようとする可能性があります。

なりすましの脅威からの保護

デプロイ パイプラインに Google Cloud へのアクセス権を付与するには、通常、次の操作を行います。

  1. サービス アカウントを作成する
  2. サービス アカウントに必要なリソースへのアクセス権を付与する
  3. サービス アカウントを使用するようにデプロイ パイプラインを構成する

IAM の観点からは、サービス アカウントはデプロイ パイプラインを表しますが、デプロイ パイプラインとサービス アカウントは別々のエンティティです。適切に保護されていない場合、攻撃者が同じサービス アカウントを使用できる可能性があり、デプロイ パイプラインの ID を偽装する可能性があります。

次のセクションでは、そのような脅威のリスクを軽減するベスト プラクティスについて説明します。

CI / CD システムで使用される VM インスタンスにサービス アカウントを接続するのを回避する

Google Cloud リソースにアクセスする Compute Engine にデプロイされたアプリケーションの場合、通常は基盤となる VM インスタンスにサービス アカウントを接続します。Compute Engine VM を使用して異なるデプロイ パイプラインを実行する CI / CD システムの場合、同じ VM インスタンスを使用して異なるデプロイ パイプラインを実行すると、異なるリソースへのアクセスが必要になるため、問題が発生する可能性があります。

接続されたサービス アカウントを使用してデプロイ パイプラインからリソースにアクセスする代わりに、各デプロイ パイプラインで別々のサービス アカウントを使用します。CI / CD システムで使用される VM インスタンスにサービス アカウントを接続しないようにするか、Cloud Logging に限定するなど、重要なサービスへのアクセスを制限するサービス アカウントを接続します。

デプロイ パイプラインごとに専用のサービス アカウントを使用する

複数のデプロイ パイプラインで同じサービス アカウントを使用する場合、IAM ではパイプラインを区別できません。パイプラインは同じリソースにアクセスでき、監査ログには、どのデプロイ パイプラインがリソースへのアクセスや変更のトリガーになったかを判断するための十分な情報が含まれていない可能性があります。

このようなあいまいさを避けるため、デプロイ パイプラインとサービス アカウントの間に 1 対 1 の関係を維持します。デプロイ パイプラインごとに専用のサービス アカウントを作成し、次のことを確認します。

  • デプロイ パイプラインの名前または ID をサービス アカウントのメールアドレスに組み込みます。一貫性のある命名スキームに準拠することで、サービス パイプラインの名前からデプロイ パイプラインを判断できます(またその逆も可能です)。
  • サービス アカウントに、特定のデプロイ パイプラインに必要なリソースへのアクセス権のみを付与します。

可能な限り Workload Identity 連携を使用する

GitHub Actions や GitLab などの一部の CI / CD システムでは、デプロイ パイプラインの ID を表明する OpenID Connect 準拠のトークンをデプロイ パイプラインで取得できます。Workload Identity 連携を使用すると、デプロイ パイプラインでこれらのトークンを使用してサービス アカウントの権限を借用できます。

Workload Identity 連携を使用すると、サービス アカウント キーの使用に伴うリスクを防止できます。

VPC Service Controls を使用して認証情報の漏洩の影響を低減する

悪意のある者がデプロイ パイプラインのいずれかからアクセス トークンまたはサービス アカウント キーを盗み出すと、この認証情報を使用して、彼らが管理する別のマシンからリソースにアクセスしようとする可能性があります。

デフォルトでは、IAM はアクセス権を決定する際に位置情報、送信元 IP アドレス、送信元の Google Cloud プロジェクトを考慮しません。そのため、盗まれた認証情報はどこからでも使用できます。

プロジェクトを VPC サービス境界に配置し、上り(内向き)ルールを使用することで、Google Cloud リソースにアクセスできるソースに制限を適用できます。

  • デプロイ パイプラインを Google Cloud で実行する場合は、CI / CD システムを含むプロジェクトからのアクセスのみを許可するように、上り(内向き)ルールを構成できます。
  • デプロイ パイプラインを Google Cloud の外部で実行する場合は、特定の位置情報または IP 範囲からのアクセスのみを許可するように、アクセスレベルを作成できます。次に、このアクセスレベルを満たすクライアントへのアクセスを許可する上り(内向き)ルールを作成します。

改ざんの脅威からの保護

Google Cloud に保存するデータによっては、不正な変更や削除を防ぐことが特に重要になる場合があります。不正な変更や削除が特に問題になるデータは、整合性が重要なデータになります。

データの整合性を維持するには、そのデータの保存と管理に使用する Google Cloud リソースを安全に構成し、整合性を維持する必要があります。

デプロイ パイプラインはデータとリソースの整合性を維持するのに役立ちますが、リスクもあります。いずれかのコンポーネントのパイプラインが管理するリソースの整合性要件を満たしていない場合は、デプロイ パイプラインが弱点となり、悪意のある人物がデータやリソースを改ざんする可能性があります。

次のセクションでは、改ざんのリスクを軽減するベスト プラクティスについて説明します。

セキュリティ制御へのアクセスを制限する

Google Cloud にあるデータとリソースのセキュリティと整合性を確保するため、次のようなセキュリティ制御を行います。

  • 許可ポリシーと拒否ポリシー
  • 組織のポリシーの制約
  • VPC Service Controls の境界、アクセスレベル、上り(内向き)ポリシー

これらのセキュリティ制御はそれ自体がリソースです。セキュリティ制御が改ざんされると、セキュリティ管理が適用されるリソースの整合性が侵害される可能性があります。そのため、セキュリティ制御の整合性は、その適用対象となるリソースの整合性と少なくとも同等に考慮する必要があります。

デプロイ パイプラインでセキュリティ制御を管理できるようにする場合、セキュリティ制御の整合性を維持するのはデプロイ パイプラインとなります。したがって、デプロイ パイプライン自体の整合性は、管理するセキュリティ制御と、それらが適用されるリソースの整合性と少なくとも同等に考慮する必要があります。

デプロイ パイプラインがリソースの整合性に与える影響を制限するには、次のようにします。

  • デプロイ パイプラインに許可ポリシー、拒否ポリシー、他のセキュリティ制御へのアクセスを許可せず、他のリソースへのアクセスを制限する
  • 特定のセキュリティ制御(特定のリソースやプロジェクトを許可ポリシーや拒否ポリシーなど)のみにアクセス権を付与する一方で、複数のリソースやプロジェクトに影響する広範なコントロールへのアクセス権を付与することはできません。

デプロイ パイプラインとそのコンポーネント、および基盤となるインフラストラクチャが特定のセキュリティ制御の整合性要件を満たさない場合は、デプロイ パイプラインがこれらのセキュリティ制御を管理しないようにすることをおすすめします。

否認防止の脅威からの保護

どこかの時点で、不審なアクティビティが Google Cloud 上のリソースに影響を及ぼすことがあります。そのような場合、アクティビティについて詳細を確認し、理想的には、それにつながるイベント チェーンを再構築できるようにする必要があります。

Cloud Audit Logs では、リソースにアクセスまたは変更された日時と、関与したユーザーを確認できます。Cloud Audit Logs は不審なアクティビティを分析するための出発点となりますが、これらのログによって提供される情報では不十分な場合があります。また、デプロイ パイプラインを使用する場合は、Cloud Audit Logs とデプロイ パイプラインによって生成されたログを関連付けできる必要があります。

このセクションでは、Google Cloud とデプロイ パイプライン全体の監査証跡を保持するうえで有用なベスト プラクティスについて説明します。

デプロイ パイプラインのログと Cloud Audit Logs の関連付けを確実にする

Cloud Audit Logs には、アクティビティを開始したユーザーに関する情報とタイムスタンプが記録されています。各デプロイ パイプライン専用のサービス アカウントを使用している場合、この情報により、アクティビティを開始したデプロイ パイプラインを特定できます。また、問題の原因となった可能性のあるコードの変更やパイプラインの実行を絞り込むこともできます。ただし、アクティビティに関連する正確なパイプライン実行とコード変更を特定するには、Cloud Audit Logs とデプロイ パイプラインのログを関連付けるための詳細情報が必要です。

Cloud Audit Logs は、次のような複数の方法でより多くの情報を含むように拡充できます。

  • Terraform を使用している場合は、CI / CD パイプラインの実行を示すリクエストの理由を指定します。
  • API リクエストに X-Goog-Request-Reason HTTP ヘッダーを追加し、デプロイ パイプライン実行の ID を渡します。
  • デプロイ パイプラインの実行 ID を埋め込むカスタム User-Agent を使用します。

次のように、デプロイ パイプラインによって出力されるログを拡充することもできます。

  • CI / CD パイプラインが実行されるたびに、ログ API リクエストを実行する。
  • API がオペレーション ID を返すたびに、CI / CD システムのログに ID を記録する。

デプロイ パイプライン ログと Cloud Audit Logs の保持期間を一致させる

デプロイ パイプラインに関連する不審なアクティビティを分析するには、通常、管理アクティビティ監査ログデータアクセス監査ログ、デプロイ パイプラインのログなど、複数のログのタイプが必要です。

Cloud Logging は、一定期間のみログを保持します。デフォルトでは、データアクセスの監査ログのほうが管理アクティビティ監査ログよりも保持期間が短くなります。デプロイ パイプラインを実行するシステムで、一定期間が経過した後にログが破棄されることもあります。デプロイ パイプラインの性質と、デプロイ パイプラインが管理するリソースの重要度によっては、これらのデフォルトの保持期間が不十分であったり、不適切な場合があります。

必要なときにいつでもログを利用できるように、さまざまなシステムで使用されるログの保持期間を調整し、十分な長さを確保してください。

必要であれば、データアクセス監査ログの保持期間をカスタマイズするか、カスタム シンクを設定してログをカスタム ストレージ ロケーションに転送します。

情報開示の脅威からの保護

デプロイ パイプラインのサービス アカウントが機密データにアクセスできる場合、攻撃者がデプロイ パイプラインを使用してそのデータを盗み出す可能性があります。デプロイ パイプラインによるデータへのアクセスは、直接的または間接的に行うことができます。

  • 直接的: デプロイ パイプラインのサービス アカウントに、Cloud Storage や BigQuery などの場所から機密データを読み取る権限が付与されている場合があります。このアクセス権は意図的に付与されている可能性がありますが、アクセス権の付与が過剰になっている可能性もあります。

    悪意のある者が機密性の高いデータへの直接アクセス権を持つデプロイ パイプラインへのアクセス権を取得すると、サービス アカウントのアクセス トークンを使用してデータにアクセスし、流出させようとする可能性があります。

  • 間接的: 構成または新しいソフトウェア バージョンをデプロイするために、デプロイ パイプラインのサービス アカウントに、VM インスタンス、Cloud Run アプリケーション、他のコンピューティング リソースを作成または再デプロイする権限が付与されている場合があります。これらのコンピューティング リソースの中には、機密データへのアクセス権を付与するサービス アカウントが接続されているものがあります。

    この場合、不正な行為者がデプロイ パイプラインの不正使用を試みて、コンピューティング リソースの 1 つに悪意のあるコードをデプロイし、そのコードによって機密データが流出する可能性があります。

このセクションでは、機密データが漏洩するリスクを限定するうえで有用なベスト プラクティスをご紹介します。

機密データへの直接アクセスを許可しないようにする

インフラストラクチャ、構成、新しいソフトウェア バージョンをデプロイするために、デプロイ パイプラインで既存のデータにアクセスする必要がないことが少なくありません。多くの場合、データを含まないリソースや、少なくとも機密データを含まないリソースへのアクセスに限定するだけで十分です。

機密情報の可能性がある既存データへのアクセスを最小限に抑えるには、次のような方法があります。

  • デプロイ パイプラインのサービス アカウントにプロジェクト全体へのアクセス権を付与するのではなく、特定のリソースにのみアクセス権を付与します。
  • 読み取りアクセス権を許可せずに作成アクセス権を付与します。たとえば、ストレージ オブジェクト作成者のロール(roles/storage.objectCreator)を付与すると、サービス アカウントは Cloud Storage バケットに新しいオブジェクトをアップロードできますが、既存データを読み取ることはできません。
  • Infrastructure as Code(IaC)を機密性の低いリソースに限定します。たとえば、IaC は VM インスタンスやネットワークの管理には使用しますが、機密性の高い BigQuery データセットの管理には使用しません。

VPC Service Controls を使用してデータ漏洩を防ぐ

VPC Service Controls の境界に Google Cloud リソースをデプロイすると、間接的なデータ漏洩のリスクを軽減できます。

デプロイ パイプラインが Google Cloud の外部で実行されている場合、または別の境界の一部である場合は、上り(内向き)ルールを構成することで、パイプラインのサービス アカウントに境界へのアクセスを許可できます。可能であれば、デプロイ パイプラインで使用される IP アドレスからのアクセスのみを許可し、デプロイ パイプラインで実際に必要なサービスに対するアクセスのみを許可するように、上り(内向き)ルールを構成します。

権限昇格の脅威からの保護

デプロイ パイプラインがサービス アカウントを使用して Google Cloud リソースにアクセスする場合、コードの作成や構成の変更を行ったデベロッパーまたはユーザーに関係なく、このようなアクセスが行われます。パイプラインのサービス アカウントとデベロッパー ID との分離により、デプロイ パイプラインが混乱した代理攻撃を受ける可能性が高くなります。この攻撃では、不正な行為者がパイプラインを欺いて、本来許可されていない操作やパイプラインで想定されていない操作を実行しようとします。

このセクションでは、権限昇格でデプロイ パイプラインが悪用されるリスクを軽減するためのベスト プラクティスについて説明します。

デプロイ パイプラインとすべての入力へのアクセスを制限する

ほとんどのデプロイ パイプラインは、ソースコード リポジトリを主要な入力ソースとして使用し、特定のブランチ(main ブランチなど)でコードの変更を検出すると、自動的にトリガーされます。通常、デプロイ パイプラインでは、ソースコード リポジトリにあるコードと構成が信頼できるものかどうかを確認できません。このアーキテクチャのセキュリティは次の条件に依存します。

  • デプロイ パイプラインで使用されるリポジトリとブランチにコードと構成を送信できるユーザーの制御。
  • 変更の commit 前に満たす必要がある基準(成功したコードレビュー、静的分析、自動テストなど)の適用。

こうした制御を効果的に行うには、不正な行為者が次のことを行い、制御を回避できないようにする必要があります。

  • ソースコード リポジトリまたはデプロイ パイプラインの構成を変更。
  • デプロイ パイプラインの基礎となるインフラストラクチャ(VM やストレージなど)の改ざん。
  • ソースコード リポジトリの外部で入力(パッケージ、コンテナ イメージ、ライブラリなど)の変更または置換。

Google Cloud のリソースがデプロイ パイプラインによって管理される場合、これらのリソースの保護レベルは、デプロイ パイプライン、その構成、インフラストラクチャ、入力と同程度になります。したがって、こうしたコンポーネントを保護するだけでなく、Google Cloud のリソースも保護する必要があります。

デプロイ パイプラインでポリシーを変更できないようにする

ほとんどのリソースタイプに対して IAM は RESOURCE_TYPE.setIamPolicy 権限を定義します。この権限により、ユーザーはリソースの IAM 許可ポリシーを変更して、他のユーザーにアクセス権を付与したり、自分のアクセス権を変更して権限を拡張できます。ユーザーまたはサービス アカウントに *.setIamPolicy 権限を付与すると、拒否ポリシーによる制約がない限り、リソースに対する完全アクセス権が付与される可能性があります。

可能な限り、デプロイ パイプラインでリソースへのアクセス権を変更しないでください。パイプラインのサービス アカウントに Google Cloud リソースへのアクセス権を付与する場合は、*.setIamPolicy 権限を含まないロールを使用し、基本ロールの編集者とオーナーは使用しないようにします。

一部のデプロイ パイプラインでは、許可ポリシーの変更権限や拒否ポリシーを変更する権限の付与が回避できない場合があります。たとえば、デプロイ パイプラインの目的が、新しいリソースを作成することや、既存のリソースへのアクセスを管理することなどです。これらのシナリオでは、次の方法でデプロイがアクセスを変更できる範囲を制限できます。

  • *.setIamPolicy 権限は、プロジェクト全体ではなく、特定のリソースにのみ付与します。
  • IAM 拒否ポリシーを使用して、付与できる権限のセットを制限したり、付与できるプリンシパルを制限します。
  • IAM Conditions を使用して、パイプラインで付与できるロールを制限し、*.setIamPolicy 権限を含まないロールのみを許可します。

ログにサービス アカウントの認証情報を表示しない

デプロイ パイプラインによって生成されたログは、多くの場合、パイプラインの構成を変更する権限を持たないユーザーを含む、より多くのユーザー グループにアクセスできます。次のものを表示することで、これらのログから認証情報が漏洩する可能性があります。

  • 環境変数の内容
  • コマンドライン引数
  • 診断出力

ログに誤ってアクセス トークンなどの認証情報が記録されていた場合、不正な行為者が認証情報を悪用し、権限を昇格させる可能性があります。ログから認証情報が漏洩しないようにするには、次の方法があります。

  • アクセス トークンやその他の認証情報をコマンドライン引数として渡さないようにする
  • 認証情報を環境変数に格納しない
  • トークンとその他の認証情報を自動的に検出してマスク(該当する場合)するように CI / CD システムを構成する

次のステップ