👋

Google Cloud における認証・認可の仕組みがこれを見ればおおよそわかる

2024/06/21に公開

はじめに

こんにちは、最近運動不足が気になり chocoZAP に通い始めた SRE 部門の 潘 (Han) です。今回は、Google Cloud で使われている様々な認証・認可の仕組みと推奨方法をまとめました。

概要

Google Cloud では基本の IAM をはじめとしてプリンシパル (ユーザーやサービスアカウントのこと) を認証・認可する仕組みがいくつか存在しています。

アプリケーションから Google Cloud 上のリソースにアクセスするためのクレデンシャルを取得する手段もいくつか存在しています。

どの方法が最も推奨される方法なのか、 ケース毎のベストプラクティスを本記事でまとめさせていただきました。

前提

前提として知っておいていただきたい、IAMApplication Default Credentials (ADC) という仕組みについてまず説明します。

  • IAMについて

IAM はプリンシパル (ユーザーアカウントやサービスアカウント) と、そのプリンシパルに許可する権限 (またはロール) を紐づけることでアカウントベースでのアクセス制御を可能する Google Cloud の最も基本的なアクセス管理の機能です。

大前提、IAM の機能がベースとなりクライアントの認証・認可が実施されているということを抑えておきましょう。

https://cloud.google.com/iam/docs/overview?hl=ja

  • Application Default Credentials (ADC) について

Application Default Credentials (以下 ADC) とはアプリケーションが Google Cloud 上のリソースにアクセスする際のクライアント認証情報を取得するための仕組みです。

ADC を使用することで、アプリケーションが Google Cloud のサービスや API にアクセスするために必要な認証情報を自動的に取得できます。

取得した認証情報が IAM で許可されているものと一致した場合、Google Cloud 上のリソースにアクセスできるようになります。

ADC が認証情報を検出する順序があるのでこちらをしっかり抑えておきましょう。
以下の優先順位で認証情報を取得します。

  1. 環境変数: GOOGLE_APPLICATION_CREDENTIALS 環境変数が設定されている場合、そのパスに指定された「認証情報が記された JSON ファイル」を使用します。
  2. ユーザークレデンシャル: gcloud auth application-default login コマンドで設定されたユーザー認証情報を使用します。
  3. メタデータサーバからコードが実行されている場所に接続されたサービスアカウントがないか探索し、認証情報の検出を行います。

https://cloud.google.com/docs/authentication/application-default-credentials?hl=ja

ケース毎のソリューション

それでは各ケースに応じた認証方法をご紹介していきます。
本記事では以下 4 つのケースについて述べていきます。

1. Google Cloud コンソールにアクセスする際のユーザーの認証
2. ローカルのアプリケーションから Google Cloud 上のリソースにアクセスする際の認証
3. Google Cloud 内でホストされているアプリケーションから Google Cloud 上の別リソースにアクセスする際の認証
4. Google Cloud の外部でホストされているアプリケーションから Google Cloud 上のリソースにアクセスする際の認証

1. Google Cloud コンソールにアクセスする際のユーザーの認証・認可

一つ目は Google Cloud コンソールにアクセスする際のユーザーの認証方法を説明します。

Google Cloud のコンソールの IAM の画面からアクセスを許可するユーザーの Google アカウントに対して適切なロールを割り振ることで、ユーザーが認証・認可されます。

前提の項目でも申し上げた通り、これ以降の各ケース毎の認証・認可についても、IAM によってクライアントの認証が実施されています。

2. ローカルのアプリケーションから Google Cloud 上のリソースにアクセスする際の認証・認可

続いて、ローカルのアプリケーションから Google Cloud 上のリソースにアクセスする際の認証方法についてです。
開発期においては、ローカルからアプリケーションを実行して Google Cloud 上のリソースにアクセスできるか検証したい場合もあると思います。

このケースでは以下二つのパターンについて述べます。

  • パターン A : ユーザーアカウントとしてアプリを実行したい
  • パターン B : サービスアカウントとしてアプリを実行したい

パターン A : ユーザーアカウントとしてアプリを実行したい

パターン A では、アプリケーションを実行する際にクライアントをユーザーアカウントとして認証させたい場合を想定しています。

ユースケースとして、例えばローカルから terraform のコードを検証する際に、ユーザーアカウントの権限で terraform apply を実行したい時などがあります。こういったケースでは ADC が のユーザークレデンシャルをソースとすることで、ユーザー権限による実行を可能にします。

以下のようにまず gcloud auth application-default login で明示的にユーザーとして認証させた後 terraform apply を実行してください。

$ gcloud auth application-default login
$ terraform apply

パターン B : サービスアカウントとしてアプリを実行したい

パターン B のケースでは、サービスアカウントの権限借用を使用することで Google Cloud 側ではクライアントがサービスアカウントとして認証・認可されます。

先述と同様の例で、 terraform apply をローカルから今度はサービスアカウントの権限で実行する場合を考えます。

以下のようにまず gcloud auth application-default login --impersonate-service-account {SERVICE_ACCT_EMAIL} で明示的にサービスアカウントとして認証させた後 terraform apply を実行してください。

$ gcloud auth application-default login --impersonate-service-account {SERVICE_ACCT_EMAIL}
$ terraform apply

3. Google Cloud 内でホストされているアプリケーションから Google Cloud 上の別リソースにアクセスする際の認証

Google Cloud のサービス間連携はサービスアカウントを使って認証・認可が実施されます。

Google Cloud のアプリケーションホスティングサービス (Google Compute Engine, App Engine, Cloud Run など ) はサービスアカウントと接続されています。

接続されているサービスアカウントの認証情報を ADC が自動的に検出することでアプリケーションから別リソース (GCS, BigQuery など ) へのアクセスを可能にしています。

このケースにおける認証情報の取得方法は若干くせがあるため、追加で少し詳細な説明をします ( 少々応用的な内容であるため、ここまでの説明で十分であれば本項目は飛ばしても構いません ) 。

使用言語によるクレデンシャル取得方法の違い

ADC が別サービスにアクセスするためのアクセストークンを自動的に取得するには、実行されているコードの言語が Cloud クライアントライブラリによってサポートされている必要があります。

例えば、Rust などの Cloud クライアントライブラリにサポートされていない言語を使用している場合、直接メタデータサーバにクレデンシャル取得のリクエストを送る必要があります。

そこから得られた一時的なアクセストークンを HTTP リクエストの Authorization ヘッダに設定すると、サービスアカウントキーを発行することなくサービス間認証・認可が実施されます。

以下はメタデータサーバへアクセストークンを取得するリクエストです。

curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" --header "Metadata-Flavor: Google"

4. Google Cloud の外部でホストされているアプリケーションから Google Cloud 上のリソースにアクセスする際の認証

Google Cloud の外部で実行されるアプリケーションと、Google Cloud 上のリソースとの間で連携をしたい場合の認証情報の取得方法について説明します。

最も推奨される方法としては、Workload Identity 連携を使用して、外部のアプリケーションと連携する方法です。

Workload Identity 連携を使用すると、サービスアカウントキーを発行せず一時的なアクセストークンを払い出すことで、外部のワークロードと Google Cloud 上のリソースを連携でき、セキュアにワークロード連携ができます。

Workload Identity 連携は、以下で使用可能です。

  • AWS と Azure で実行されるワークロード
  • オンプレミスの Active Directory、GitHub や GitLab などのサービス
  • OpenID Connect(OIDC)または Security Assertion Markup Language(SAML)V2.0 をサポートする任意の ID プロバイダ(IdP)

Google Cloud サービスと連携したいアプリケーションが Workload Identity 連携が使える場所でホストされているか確認し、使用不可となった場合は最終手段としてサービスアカウントキーを発行するという流れになるでしょう。

以下は Workload Identity 連携の公式ドキュメントです。

https://cloud.google.com/iam/docs/workload-identity-federation?hl=ja

まとめ

以上が ADC を用いたアプリからの認証情報取得の仕組みと、各ケースに応じたソリューションでした。Google Cloud は以下のように最適な認証方法を選択できるよう以下リンク先のフローチャートを用意しています。

なるべくサービスアカウントキーを発行しないようにすることで、セキュリティインシデントのリスクを軽減し、セキュアにアプリ運用していきましょう。
https://cloud.google.com/docs/authentication?hl=ja#auth-decision-tree

Discussion