日々のあれこれφ(..)

もっぱら壁打ち

Google Cloud APIsの認証の種類と使い分けについて

以前まではAWS環境で開発を行うことが多かったのですが、最近ではGCP環境も結構触っています。

Google Cloud APIを使ったプロジェクトの開発を行う際、私はいつもサービスアカウントキー を作成してそれを読み込ませる形でローカル環境を構築していたのですが、別の人はOAuth 2.0クライアント認証を用いるやり方で開発をしていたと聞きました。

このようにGoogle Cloud APIを使う際には認証のやり方が複数あるのですが、どれをどういう思想で使い分けすればいいのか、はたまた開発者自由でいいのか、認証の設計思想に理解が浅い状態だったので腰を据えてドキュメントを読んだ時のメモです。

Authentication overview  |  Google Cloud

今回の話のスコープ

Google Cloud APIの話になります。Google Maps Platform APIのようなGCP外のサービスは含みません。

認証を知るにあたって出てくる概念

プリンシパル

プリンシパルをうまく和訳して説明するのが難しいのですが、APIを使う主語にあたるものをさしているという認識です。プリンシパルはもっぱら人間か人間以外のもの(サーバーやbotなど)によるアクセスかで種類が分かれます。

  • User accounts
    • 想定: 人間によるアクセス
    • 管理: Googleアカウントを使って行う
  • Service accounts
    • 想定: 人間以外からのアクセス(システムなど)
    • 管理: IAM

アプリケーション

プリンシパルが「"誰が"リクエストをするか」にあたる部分とするなら、アプリケーションは「"どこで"リクエストをするか」にあたる部分を示しています。具体的にはGCEやGAE、GKEやGCP外(誰かのローカル環境)などの実行環境を示すものと思われます。

3種類の認証情報の種類

これらの概念を踏まえた上で、認証の方法としては3種類用意されています。

APIキー

これは一番分かり易いもので、プリンシパルは識別せず、アプリケーションのみを識別するものです。

例えば、そのAPIキーを持っていたら、誰でもGCSの特定のオブジェクトにアクセスできるというようなことを実現できます。

OAuth 2.0クライアント認証

認証時にGoogleアカウントが必要になる、プリンシパルがUser accounts(人間によるアクセス)を想定した認証になっているようです。

サービスアカウントキー

認証時にサービスアカウントと紐づけられたサービスアカウント キーが必要になる、プリンシパルがService accounts(人間以外からのアクセス)を想定した認証になっているようです。認証情報に個人のGoogleアカウントを必要としないので、本番環境のシステムやCICDのような共有しているものに対して使えます。

サービスアカウント には厳密には二種類存在します。

  • デフォルトサービスアカウント
    • GCPのコンピュート系のリソース(GCEやGAE等)にデフォルトで付与されているもので、GCP環境内からAPIを実行するときはサービスアカウント の付与が不要になります。これはGoogle Cloud Client Libraries(Google Cloud APIを呼び出すためのクライアントライブラリ。各言語のものが一通り用意されている)は、サービスアカウントの認証情報を自動的に検索して使用するようになっているためです
  • サービスアカウント
    • デフォルトでないものは全部こちらです。IAMからユーザーが必要に応じて作成します。サービスアカウント キーとは、ここで作ったサービスアカウントで作成または登録をしたキーを、Google Cloud Client Librariesライブラリに読み込ませることで認証を行います

使い分けの戦略について

アプリケーションに必要な実行権限と実行場所を基に何を使うか決めるのが良さそうとのことで、一例が以下のようになります。

  • APIキー
    • 公開データへの匿名アクセス
  • OAuth 2.0クライアント認証
    • エンドユーザーに代わって個人データにアクセスする
  • サービスアカウントキー
    • GoogleCloud環境外のサービスアカウントに代わって個人データにアクセスする
  • デフォルトサービスアカウント(認証情報を渡さなくてもいい)
    • GoogleCloud環境内のサービスアカウントに代わって個人データにアクセスする

おわりに

APIキーはさておき、OAuth 2.0クライアント認証とサービスアカウントキー、開発時はどちらを使うのが好ましいのかわからなかったのですが、ドキュメントを見たところどちらでも良さそうでした。

強いて挙げるとしたら、サービスアカウント にはリソースに対して実行できるアクションを絞ることができるので、権限の検証をしたいときはサービスアカウント キーを設定し、それ以外は開発者個人のGoogleアカウントを使ってOAuth 2.0クライアント認証を行うのがよいのでしょうか。

ただOAuth2.0クライアント認証を使う場合、アクションに制限をつけるためにOAuth scopesの定義が求められたりして、ソースの書き方が変わってくるケースもあるかと思うので本番とできるだけ差異を小さくするのであればサービスアカウント キーを使うようにした方がよいのかなと個人的には思っていたりもします。

開発を行っていくにあたってこういった重要な周辺リソースの思想はちゃんと知っておきたいものです。