G-gen の武井です。当記事では Google Cloud SDK の2つの認証コマンドの違いについて解説します。
はじめに
2つの認証用コマンド
gcloud auth login
と gcloud auth application-default login
はどちらも Google Cloud SDK の認証 に使用されるコマンドですが、その違いと適切な使い分けが混同されがちです。
そこで当記事では、これらコマンドの基本的な機能や使い分けを、実際の検証を交えて解説します。
- 参考 : Google Cloud SDK
gcloud auth login
gcloud auth login
を実行すると、個人の Google アカウントを使って認証し、gcloud コマンドラインツールから Google Cloud の各サービスにアクセスできるようになります。
認証に成功すると、例えば Compute Engine のインスタンスや Cloud Storage のバケットといった各サービスを gcloud コマンドで管理できます 。
- 参考 : gcloud
- 参考 : gcloud auth login
gcloud auth application-default login
gcloud auth application-default login
を実行すると、個人の Google アカウントもしくはサービスアカウントを使って認証し、任意のアプリケーションが Google Cloud API にアクセスできるようになります。
認証に成功すると、Go や Python といった言語で記述したプログラムや IaC ツールに代表される Terraform など、様々なアプリケーションが Google Cloud の API を呼び出せます。
違い
これら2つのコマンドの違いは、gcloud auth login
が gcloud コマンドラインツールのための認証を行うコマンドであるのに対し、gcloud auth application-default login
は Google Cloud SDK を使ったアプリケーションのための認証を行うコマンドである、という点です。
検証
シナリオ
検証パターン
このセクションでは gcloud auth login
と gcloud auth application-default login
の違いを理解するため、4パターンで検証を行います。
gcloud auth login
を認証1、gcloud auth application-default login
を認証2として、以下のパターンで検証を行いました。
# | 実行するツール | 認証1 | 認証2 |
---|---|---|---|
1 | コマンド (gcloud storage buckets list ) |
なし | - |
2 | コマンド (gcloud storage buckets list ) |
あり | - |
3 | プログラム (Cloud Storage API をコール) |
- | なし |
4 | プログラム (Cloud Storage API をコール) |
- | あり |
実行環境
上記検証を筆者のローカル環境で実施するにあたり、gcloud を以下のように構成しました。
$ gcloud config configurations list NAME IS_ACTIVE ACCOUNT PROJECT COMPUTE_DEFAULT_ZONE COMPUTE_DEFAULT_REGION test-prj-20240109 True test-user01@g-gen.co.jp test-prj-20240109
$ gcloud config list [core] account = test-user01@g-gen.co.jp disable_usage_reporting = True project = test-prj-20240109 Your active configuration is: [test-prj-20240109]
- 参考 : gcloud CLI の構成の管理
プログラムのソースコード
Cloud Storage API を呼び出すプログラムは Go で記述しています。
package main import ( "context" "fmt" "log" "cloud.google.com/go/storage" "google.golang.org/api/iterator" ) func main() { ctx := context.Background() client, err := storage.NewClient(ctx) if err != nil { log.Fatalf("Failed to create client: %v", err) } defer client.Close() it := client.Buckets(ctx, "test-prj-20240109") // プロジェクトIDをここに設定 for { bucketAttrs, err := it.Next() if err == iterator.Done { break } if err != nil { log.Fatalf("Failed to list buckets: %v", err) } fmt.Println(bucketAttrs.Name) fmt.Printf("Location: %s\n", bucketAttrs.Location) fmt.Printf("Creation Time: %v\n", bucketAttrs.Created) fmt.Printf("Storage Class: %s\n\n", bucketAttrs.StorageClass) } }
検証結果
パターン #1
認証1 (gcloud auth login
) を行わずに gcloud storage buckets list
を実行した際の結果です。
エラーメッセージに記されている通り、有効な認証情報がないため gcloud auth login
を実行して認証情報を取得するよう促されていることがわかります。
$ gcloud storage buckets list ERROR: (gcloud.storage.buckets.list) Your current active account [test-user01@g-gen.co.jp] does not have any valid credentials Please run: $ gcloud auth login to obtain new credentials. For service account, please activate it first: $ gcloud auth activate-service-account ACCOUNT
パターン #2
認証1 (gcloud auth login
) を行ったあとに gcloud storage buckets list
を実行した際の結果です。
認証エラーがなくなり、接続先プロジェクトにある Cloud Storage バケットの情報が表示されたことがわかります。
$ gcloud storage buckets list --- creation_time: 2024-01-09T12:38:33+0000 default_storage_class: STANDARD location: ASIA-NORTHEAST1 location_type: region metageneration: 1 name: test-prj-20240109-bucket public_access_prevention: enforced storage_url: gs://test-prj-20240109-bucket/ uniform_bucket_level_access: true update_time: 2024-01-09T12:38:33+0000
パターン #3
認証2 (gcloud auth application-default login
) を行わずにプログラムを実行した際の結果です。
エラーメッセージに記されている通り、プログラムに有効な認証情報がないため文中のリンク先に従い認証情報を取得するように促されていることがわかります。
$ go run main.go 2024/01/09 22:45:33 Failed to create client: dialing: google: could not find default credentials. See https://cloud.google.com/docs/authentication/external/set-up-adc for more information exit status 1
パターン #4
認証2 (gcloud auth application-default login
) を行ったあとにプログラムを実行した際の結果です。
認証エラーがなくなり、接続先プロジェクトにある Cloud Storage バケットの情報が表示されたことがわかります。
$ go run main.go test-prj-20240109-bucket Location: ASIA-NORTHEAST1 Creation Time: 2024-01-09 12:38:33.981 +0000 UTC Storage Class: STANDARD
まとめ
検証結果
検証の結果、ユーザーによる gcloud
コマンド実行と、プログラムによる API アクセスでは異なる認証が必要とわかりました。
# | 実行するツール | 認証1 | 認証2 | 実行結果 |
---|---|---|---|---|
1 | コマンド (gcloud storage buckets list ) |
なし | - | 失敗 |
2 | コマンド (gcloud storage buckets list ) |
あり | - | 成功 |
3 | プログラム (Cloud Storage API をコール) |
- | なし | 失敗 |
4 | プログラム (Cloud Storage API をコール) |
- | あり | 成功 |
※ 認証1:gcloud auth login
※ 認証2:gcloud auth application-default login
補足1 (認証情報の格納場所)
今回の検証で gcloud auth login
と gcloud auth application-default login
による認証を行いましたが、取得した認証情報は以下のパスに格納されます。
# ホームディレクトリ直下の隠しディレクトリ .config/gcloud に格納 $ pwd && ls -l | grep credentials. /home/test-user01/.config/gcloud -rw------- 1 test-user01 test-user01 346 Jan 9 23:10 application_default_credentials.json -rw------- 1 test-user01 test-user01 12288 Jan 9 23:05 credentials.db
# | 認証情報 | 説明 |
---|---|---|
1 | application_default_credentials.json | gcloud auth application-default login により取得 |
2 | credentials.db | gcloud auth login により取得 |
補足2 (認証コマンドの実行方法)
gcloud auth login
と gcloud auth application-default login
のどちらにおいても、コマンドを実行するだけで認証が行えます。
# gcloud auth login の場合 $ gcloud auth login Your browser has been opened to visit: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=32555940559.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&state=vfnYU3SJwjYhB5bf4Pvt0tVqda3FHn&access_type=offline&code_challenge=VYMPz-UcrhOnonDiCzim2wBV-LvOdsjFpQ1imxyc8Wo&code_challenge_method=S256
# gcloud auth application-default login の場合 $ gcloud auth application-default login Your browser has been opened to visit: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login&state=db7JI5mCJGVNnUONd7CQjKNMut9sXL&access_type=offline&code_challenge=5DznJO_rgOO_WP_dHHpwfAbrPYW1p-m7ndU5xvpXydU&code_challenge_method=S256
認証コマンドを実行すると別途 Web ブラウザが起動して認証に使用するアカウントを選択する画面が表示されます。
許可
をクリックすると認証が成功し、ブラウザ上に認証が完了した旨が表示されます。
API スコープ
Google ドライブ上の Google スプレッドシートを参照するような Python スクリプトを開発する例を考えます。このスクリプトでは、BigQuery に定義した外部テーブルを経由して、Google スプレッドシートから情報を取得していました。この記事で紹介したように gcloud auth application-default login
を用いて認証したのにも関わらず、ローカル PC でテストした際に、以下のようなエラーメッセージが表示されました。
google.api_core.exceptions.Forbidden: 403 Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials.; reason: accessDenied, location: (英数字), message: Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials.
事前に gcloud auth
コマンドを実行した Google アカウントには、間違いなく Google ドライブへの権限も、対象のシートへの権限も、もちろん BigQuery への権限も付与されています。どうしてこのエラーが起こったのでしょうか。
これは、gcloud auth
コマンドを実行する際の API スコープが関係しています。gcloud auth application-default login
を実行すると、デフォルトでは Google ドライブへのアクセス権限はスコープに含まれません。以下のように明示的に指定して、コマンドを実行します。
gcloud auth application-default login --scopes \ "https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/drive.readonly"
これにより、Google ドライブへの読み取り権限が認証情報にスコープとして含まれ、正しくスクリプトを実行することができました。API スコープの名称やそこに含まれる権限は、公式ドキュメントに記載されています。以下は、Google Drive API のドキュメントです。
- 参考 : Drive API スコープ
同様に、gcloud コマンドの認証時に Google ドライブへのアクセスを許可するには、以下のコマンドを実行します。
gcloud auth login --enable-gdrive-access
関連記事
ローカル環境で Terraform を実行する際の認証については以下の記事で解説していますのでこちらもあわせてご確認いただけると幸いです。
武井 祐介 (記事一覧)
クラウドソリューション部所属。G-gen唯一の山梨県在住エンジニア
Google Cloud Partner Top Engineer 2025 選出。IaC や CI/CD 周りのサービスやプロダクトが興味分野です。
趣味はロードバイク、ロードレースやサッカー観戦です。
Follow @ggenyutakei