Google Cloudサービス アカウントをセキュアに管理するためのtips
--
この記事は Eureka Advent Calendar 2022 の 13日目の記事です。
こんにちは。エウレカ SREチームのyucattyです。
突然ですが、IAMの管理、大変ですよね。
そもそも数が多く、オーナー・用途が不明なものがある、長期間キーローテーションされていない、過剰な権限が付与されている、などなど、長期間運用しているとどうしてもこのような問題が発生してしまいがちです。
私は今年Backend EngineerからSREにロールチェンジし、Google Cloudを触る機会が増えたので、今日はGoogle Cloudサービス アカウントに焦点を当てて、セキュアに管理する方法を考えてみようと思います。
∘ サービス アカウントの種類
∘ サービス アカウントのベストプラクティス
∘ 1. 未使用リソースを特定し、無効化する
∘ 1.1 サービス アカウント・サービス アカウント キーの使用状況を取得する
∘ 1.2 不要リソースの無効化
∘ 2.サービス アカウント キーからサービス アカウントへの移行
∘ 3. サービス アカウント キーのローテーションを行う
∘ 4. 定期的な棚卸を実施する
∘ まとめ
サービス アカウントの種類
サービスア カウントはGoogle CloudのIAMにおけるプリンシパルの一つです。(Google Cloud IAMの概要はこちら)サービス アカウントを管理するにあたりいくつか種類があり、「ユーザー管理」と呼ばれるものが対象になるのと、サービス アカウントを識別するメールアドレスの特徴を知っておきたいので、簡単に触れておきます。まず、サービス アカウントは3種類あります。
ユーザー管理のサービス アカウント
- ユーザー自身の責任で管理するアカウントです。
- サービス アカウントを識別するメールアドレスに次の形式で表示されます。
- {service-account-name}@{project-id}.iam.gserviceaccount.com
デフォルトサービス アカウント
- App Engine/Compute Engine、またはそれらを利用するサービスを有効化する際に自動作成されるユーザーアカウントです。
- 自動で作成されますが、管理はユーザー自身になります。
- デフォルトのサービス アカウントが作成されると、プロジェクトに対する編集者ロール(roles/editor)が自動的に付与されますが、最小権限の原則に従い、自動的なロール付与を無効にすることが推奨されています。(参考)
- App Engineのデフォルトサービス アカウント → {project-id}@appspot.gserviceaccount.com
- Compute Engineのデフォルトサービス アカウント → {project-number}-compute@developer.gserviceaccount.com
Google マネージド サービス アカウント
- Google Cloudサービス内部で利用されるサービス アカウントです。
- Google Cloud コンソールの [サービス アカウント] ページには、Google マネージド サービス アカウントは表示されません。
続いて、サービス アカウント キーは2種類あります。サービス アカウント キーはサービス アカウントに紐付きます。サービス アカウント キーは、ユーザー名やパスワードと同様に認証情報の一つです。有効なサービス アカウント キーにアクセスできるユーザーは、この鍵を使用して認証を行い、サービス アカウントにアクセス権のあるリソースを使用できます。
ユーザー管理のサービス アカウント キー
- サービス アカウントに最大10個のサービス アカウント キーを作成することができます。
- サービス アカウントのユーザー管理鍵ペアを作成し、各鍵ペアの秘密鍵を使用して Google API で認証できます
- 作成し、ダウンロードしたサービス アカウント キーには有効期限がありません。
Google管理のサービス アカウント キー
- Google が管理する鍵ペアは、Service Account Credentials API や、Google Cloud サービス(App Engine や Compute Engine など)によって使用され、有効期間が短いサービス アカウント認証情報を生成します。
- 自動的にローテーションされます。
サービス アカウントのベストプラクティス
サービス アカウントを操作するためのベスト プラクティスに指針が示されていますが、今回はサービス アカウント キーを使用しないことに焦点を当ててお話ししたいと思います。サービス アカウント キーは外部に漏洩すると誰でもサービス アカウントに付与されている権限が実行できてしまうセキュリティリスクと、有効期限がなく定期的にキーローテーションを行う必要があるという、管理の煩雑さから、ユーザー管理のサービス アカウント キーを使用せず、可能な限り別の方法でサービス アカウントの認証を行うことが推奨されています。
具体的には、Google Cloudのコンピューティングリソースにデプロイされたアプリケーションであれば、コンピューティングリソースとサービス アカウントを接続することでアプリケーションはサービス アカウントのトークンを取得し、そのトークンを使用して Google Cloud APIs とリソースにアクセスできます。また、オンプレミスまたは他のクラウド プロバイダで実行されているアプリケーションがサービス アカウントを利用するための仕組みとしてWorkload Identity 連携 があります。
それではここからは、既存のサービス アカウントリソースに対し、具体的にどのようにベストプラクティスを適用していくか考えていこうと思います。
1. 未使用リソースを特定し、無効化する
まずは各サービス アカウントの使用状況を把握するため、サービス アカウントの棚卸を実施します。ここで長期間利用のないサービス アカウントを無効化していきます。
1.1 サービス アカウント・サービス アカウント キーの使用状況を取得する
サービス アカウント毎の使用状況はconsoleから確認することができます。
また、Policy Analyzer APIを利用することで、プロジェクト単位で一括でサービス アカウント・サービス アカウント キーの最後の使用日時を取得できます。
1.2 不要リソースの無効化
最後のアクティビティから一定期間経過しているサービス アカウントを無効化していきます。サービス アカウントを無効化することで、サービス アカウント キーも同時に無効化されます。無効化してもIAMバインディングは残るので、万が一利用中の場合でも再有効化することで素早く復旧することができます。一定期間無効化して問題がなければ、削除します。※App Engine や Compute Engine のデフォルトのサービス アカウントなどは、このサービス アカウントの認証情報に依存しているアプリケーションが正しく動作しなくなる可能性があるため削除しないように注意しましょう。
2.サービス アカウント キーからサービス アカウントへの移行
利用中のサービス アカウント キーがある場合、サービス アカウントへ移行できないか調査します。
サービス アカウントは、AWS上のアプリケーションからBigQueryを参照するなど、Google Cloud外から利用するケースも多いと思います。
オンプレミスまたは他のクラウド プロバイダで実行されているアプリケーションからGoogle Cloudリソースにアクセスする場合、Workload Identity連携を検討します。
Workload Identity 連携はGoogle Cloud プロジェクトと外部 ID プロバイダ間の信頼関係を作成し、アプリケーションは、信頼できる ID プロバイダによって発行された認証情報を使用してサービス アカウントサービス アカウントの権限を借用する仕組みです。
例えばCI/CDにGithub Actionsを使っている場合はGithub Actions OIDCとWorkload Identity連携を行いキーレス化が実現でき、Github Actionsに強い権限のサービス アカウント キーを渡さずに済みます。
また、AWS上のアプリケーションからGoogle CloudリソースにアクセスするケースでもWorkload Identity連携を利用できます。
3. サービス アカウント キーのローテーションを行う
サービス アカウントへの移行ができず、やむを得ずサービス アカウント キーを利用する場合、サービス アカウント キーには有効期限がないため定期的にキーローテーションを行う必要があります。サービス アカウント キー作成日を把握するためには、Google Cloud コンソールの [アセット インベントリ] ページからCSVで一括ダウンロード可能ですが、全てのkeyTypeが含まれるのでIAM APIを利用してサービス アカウント キーの作成日を取得するのがおすすめです。Google が管理する鍵ペアは自動的にローテーションされるため、keyType=`SYSTEM_MANAGED`のものは対象外とします。
4. 定期的な棚卸を実施する
このような棚卸をクォーター、年次など任意のタイミングで定期イベント化するために、今回紹介したGoogle APIで、未使用サービス アカウントやローテーション対象のサービス アカウント キーの一覧をスクリプトを書いていつでも抽出できるような状態にあるのが望ましいと思いました。
さらに、一定期間経過したサービス アカウントは自動で無効化するといった仕組みを導入するのも良さそうです。
まとめ
サービス アカウントをセキュアに管理するための運用方法を考えてみました。今回お話ししたことは、ベストプラクティスの一部分であり、これだけで全てのリスクが防げているわけではありませんが、棚卸を定期イベント化するために、工数を確保して継続することが大切だと考えています。
また、今回は詳しく触れませんでしたが、「最小権限の原則」を実施するために、過去の利用履歴から未使用の権限を洗い出すGoogle APIも用意されているので、こちらも活用できるといいですね。
この運用が最適かどうかは組織の状況にもよりますが、サービス アカウントの棚卸を考えている方に少しでも役に立てたら幸いです。
明日は Hiromichi Ema さんの 「Backend-team の改善作業についてのあれこれ」についてです!!