Google Cloud で休眠状態のサービスアカウントを見つける
🤖 サービスアカウントって?
Fairy Devices で Google Cloud をちょくちょく使っている asari3 です。
Google Cloud を使っていると、 サービスアカウント をよく使いますよね。
サービスアカウントは、一言でいうと、 (人間でなく) アプリケーションや仮想マシン (VM) といった機械向けに発行する Google アカウント です。人間のアカウントにするのと同様に、サービスアカウントにもロール (役割) を与えて、「このストレージへの書き込みを許可」「このプロジェクトの Cloud Logging にログを流すのを許可」「このスプレッドシートの読み書きを許可」といった細かい制御を行います。
🌿 サービスアカウント増えがち
これが本当に増えます。
Google のドキュメントでは、サービスアカウントは 単一目的のものを作って使うべき としています。最小権限の原則を守るのにも良いし、監査のためにも良いということですね。
わたしたち Fairy Devices も、このベストプラクティスに従って、 デフォルトのサービス アカウントへの自動的なロール付与を使用しない ように組織ポリシーを変更しています [1] 。
ということで、仕方ないことではありますが、何かやろうとするたびにサービスアカウントが増えることになります。
- VM がなにかのリソースにアクセスしようとすると増える
- Terraform でなにか構築しようとすると増える
- Cloud Run Jobs でなにかをバッチ処理しようとすると増える
- それらを Cloud Scheduler で定期実行しようとすると増える
🪹 休眠状態のサービスアカウントを見つける
サービスアカウント、使い終わったら消せばよいのですが、いかにも消し忘れが発生しそうですよね。定期的に 休眠状態のサービスアカウントを見つける のがよさそうです。
上記の記事にあるとおり、サービスアカウントが単一目的で使われていない可能性がある場合は、 Activity Analyzer というのを使うのがよさそうです。
gcloud policy-intelligence query-activity --activity-type=ACTIVITY_TYPE \
--project=PROJECT_ID --limit=LIMIT
簡単ですね! PROJECT_ID にプロジェクト ID [2] 、 ACTIVITY_TYPE に serviceAccountLastAuthentication または serviceAccountKeyLastAuthentication を入れて実行する [3] と、それぞれサービスアカウントの利用状況、サービスアカウントキーの利用状況がわかります。
gcloud コマンドでは、出力形式に CSV や TSV も選べます。たとえば、ここでは serviceAccountLastAuthentication の出力に CSV を選んで、適当に置換をしてプロジェクト名を見やすくしてみます。
gcloud policy-intelligence query-activity \
--activity-type=serviceAccountLastAuthentication \
--project=myproject \
--format='csv(fullResourceName, activity.lastAuthenticatedTime)' \
--limit=unlimited | \
sed 's|^full_resource_name|project,full_resource_name|;s|^.*/\([^/]*\)/serviceAccounts/|\1,|'
(出力例)
project,full_resource_name,last_authenticated_time
myproject,sa0@myproject.iam.gserviceaccount.com,2025-08-01T07:00:00Z
myproject,sa1@myproject.iam.gserviceaccount.com,2025-08-01T07:00:00Z
myproject,sa2@myproject.iam.gserviceaccount.com,2025-08-01T07:00:00Z
:
すばらしい!
この Activity Analyzer は Preview ということで、これを使うための将来の料金体系などはわからないのですが、相当便利です。これまでも Cloud Logging などを使って同様の分析を行うことができましたが、今ひとつ遅かったり、複数のコマンドを実行する必要があったりして、やや面倒でした。ありがたい。
わたしたちは、このようにしてスプレッドシートを作成したのち、関係者に回覧したり、そこにメモを付けたりして、実際に使われていないサービスアカウントを消しています。
🐕 見つかったサービスアカウントの正体とは…
さて、このようにして見つかった休眠サービスアカウントは、いったいどんなものだったのでしょうか。少しだけご紹介します。
- 廃止された社内サービスのためのアカウント: 社内ツールで定期的に使われていたが、そのツールを使わなくなったあとも取り残されたアカウント。
- Terraform 実行用アカウント: Terraform で Google Cloud リソースを作成・削除するために、
roles/ownerなどの強い権限を一時的に割り当てたサービスアカウント。 - 設定ミスで使われなかったアカウント: 「このサービスで使おう」と思って作成したのに、デプロイ時に別のアカウントを指定してしまい、実際には一度も使われなかった悲しいアカウント。
急にホラーな話になったと思いましたか? そう、使われていないアカウントは、それ自体がセキュリティホールと強く結びついています。定期的に棚卸しの予定を入れたり、自動化したりして、セキュアな Google Cloud 生活を送っていきましょう!
✅ サービスアカウントの管理のベストプラクティス
さきほどから個別のトピックでちょくちょくリンクを挙げていた記事ですが、 Google Cloud 公式の サービス アカウントの使用に関するベスト プラクティス はとてもいい記事です。長いですが、読みにくくはなく、どれも納得のいく内容で、一読をおすすめします。
特に、サービスアカウントを使うのはどんなときか のフローチャートを見て、サービスアカウントのキーを使うのを避けていくことはとても重要だと思います。
わたしたちのサービスアカウントの棚卸しでは、サービスアカウントの名前と説明は規則に従うようにする をもう少しやっておきたいと思いました。「アプリケーション名を付ける」「Google Cloud の外部でキーが使われるものには onprem- を付ける」くらいはやりやすそうです。
セキュリティ、地道なことも多いですよね。長い道のりですが、やっていきましょう。
-
2024 年ごろから Google のデフォルトの組織ポリシーが secure-by-default に変更されたのに合わせた動きでもあります。 ↩︎
-
プロジェクト ID の一覧の取得は
gcloud projects list --filter="parent.id=<組織ID>"のようにしてできます。組織の Browser (roles/browser) のようなロールが必要です。 ↩︎ -
Activity Analyzer の実行には、 Activity Analysis Viewer
(roles/policyanalyzer.activityAnalysisViewer) のようなロールが必要です。 ↩︎
Discussion