|

2025-06-20

Tips

Google Cloud のローカル開発等でサービスアカウントの権限を使いたいときの対応パターン

Google Cloud

Google Cloud におけるサービスアカウント権限借用パターン

サービスアカウントとユーザーアカウント

Google Cloudに限った話ではないですが、 クラウド上のリソースを使うプロダクトに対してローカル環境などで開発しているとき、 「何の権限でサービスにアクセスしているか」は意識しておくべきことの一つ かと思います。

 

たとえば、 Google Cloud の場合、 CLI から

gcloud auth login

でログインしたとき、その 「ユーザーアカウント」 の認証情報が取得され、そのユーザーとして色々なコードやコマンドを実行できるわけですが、 本番環境では実行者として 「サービスアカウント」 を割り当てて、その権限を使ってリソースにアクセスすることが多いです。

 

それゆえに、ローカル環境でユーザーアカウントの認証情報を使って開発してうまくいっているコードを そのまま本番環境に持っていくと、サービスアカウントの権限が不足していてうまく動かない なんてことは誰しもが一度は通った道だと思います。

 

サービスアカウントの権限借用

では、そういった場合にどうするのかというと、 「サービスアカウントの権限のもとでコードを動かす」 行為が必要になります。

 

そのために一番手っ取り早い方法としては「サービスアカウントの認証情報(credentials)のJSONファイル等をダウンロードし、使用する」方法がありますが、 認証情報のファイルを管理する必要性が出てきますし、もちろん、漏洩のリスクも伴います。

 

そういった煩わしさから解放されるためには、「ユーザーアカウント」に対して、「サービスアカウントの権限を借りる」権限を付与し、 「サービスアカウント」のフリをしてコードを動かしていく 、という方法が有効です。

 

本記事では Python の場合にどのように権限借用処理するコードパターンがあるかについて紹介します。

 

権限借用のための権限

Google Cloudにおける権限借用については、 公式ドキュメント「サービス アカウントの権限借用」のページが参考になります。

アプリケーションの開発もそうですが、権限テストや一時的な権限付与にも使えると記載があったりして、なるほど…となりますね。

Google Cloud サービス アカウントの権限借用は、AssumeRole などのアマゾン ウェブ サービス(AWS)Security Token Service API メソッドに似ています。

と、Google Cloud 公式ドキュメント的には珍しく(?)AWSの類似メソッドに対しての言及があるのも見所です。

 

それはさておき、権限借用をするためにももちろん権限が必要です。

ドキュメント中に記載がありますが、 iam.serviceAccounts.getAccessToken です。

こういった、権限を含むロールを見つけたいときは IAM roles and permissions index をつかいます。 ちなみにこれはGoogle Cloudを使っているならブックマーク必須の超重要ページです。 (そのわりに辿り着きにくい印象もあります。。)

 

ここにパーミッションをそのまま打ち込めば、ボタンが現れて… Monosnap_IAM_roles_and_permissions_index____IAM_Documentation____Google_Cloud_2025-06-20_09-22-24

クリックすれば簡単に該当ロールが出てきます。 image

本当にこれは便利なのでめっちゃ使ってます。

 

ということで、本題に戻ると、多くの場合は roles/iam.serviceAccountTokenCreator を付与するとよいかと思います。

日本語でいうところの、 サービス アカウント トークン作成者 ですね。

これを借用したいユーザーに付与します。 (※借用するのはユーザーなので、ユーザー側への権限付与です)

 

実際に権限借用する場合のパターン

そしてここからは、具体的にPythonの場合にどのようなコードで権限借用するかです。

(※ 先ほどの公式ドキュメントにもあるとおり、CLIコマンドでは --impersonate-service-account などで指定可能です)

credentials を取得するパターン

まず、認証情報を取得するパターンです。これが最も使うことになるとおもいます。

import google.auth import google.auth.impersonated_credentials user_credentials = google.auth.default() sa_credentials = google.auth.impersonated_credentials.Credentials( source_credentials=user_credentials, target_principal=[ターゲットのサービスアカウント: **@**.iam.gserviceaccount.com], target_scopes=[認証スコープ], lifetime=300, )

先ほどの権限を付与したユーザーアカウントの認証情報をもとに

google.auth.impersonate_credentials.Credentials によって取得出来ます。

 

target_principal はターゲットのサービスアカウントのアドレスを入力し、

認証スコープは、たとえば

AUTH_SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]

のような形で指定できます。

 

ID トークンを取得するパターン

そしてもう一つ、 impersonate とはまた微妙に違う話にはなりますが、たまに、サービスアカウントのIDトークンがほしくなるときがあります。

Cloud Run で認証が必要なURLエンドポイントを公開しているときなどが該当します。

この場合は、

import google.auth from googleapiclient.discovery import build user_credentials = google.auth.default() iam_credentials = build("iamcredentials", "v1", credentials=user_credentials) response = iam_credentials.projects().serviceAccounts().generateIdToken( name="projects/-/serviceAccounts/[サービスアカウントのアドレス]", body={ "audience": [リクエスト対象URL], "includeEmail": True } ).execute() id_token = response["token"]

のようにしてIDトークンの取得が可能です。

Method: projects.serviceAccounts.generateIdToken を叩きに行く形ですね。

 

こちらはそこまで登場しないですが、そのぶん、あまりインターネット上に方法が載っていないので、どなたかの参考になっていれば幸いです。

 

まとめ

今回はサービスアカウントの権限借用まわりの話でした。

めんどくさくなってくると、 権限をモリモリにしたサービスアカウントを作ってしまったり、credentials の JSON をダウンロードして雑に管理してしまったり、なんて事例もよくみますが…

やはりきちんとガバナンスを効かせる上では最小権限の原則に則った上で、むやみやたらに認証情報をファイルとして取り寄せないようにしておきたいですね。

 


この記事の著者

プロフィール画像

伴 拓也

朝日放送グループホールディングス株式会社 DX・メディアデザイン局 デジタル・メディアチーム

アプリケーションからインフラ、ネットワーク、データエンジニアリングまで幅広い守備範囲が売り。最近はデータ基盤の構築まわりに力を入れて取り組む。 主な実績として、M-1グランプリ敗者復活戦投票システムのマルチクラウド化等。