運用技術

スプレッドシートでCloud Runを活用:Apps ScriptからCloud Runへの認証方法

運用技術

ペパボ研究所 研究員の酒井(@tshk_sakai)です。 今回は、Google Sheets(以下、スプレッドシートと書きます)でCloud Runを活用するため、OpenID Connect仕様のIDトークンを用いて、Google Apps Script(以下、Apps Scriptと書きます)からCloud Runへの認証を行う方法についてご紹介します。

背景

業務において、スプレッドシートの情報を元に、処理を行い、その処理結果をシートへ反映したいことがあります。 この場合、スプレッドシート内で処理が完結することが望ましいですが、スプレッドシート単体では実現が難しいこともあります。 そこで、スプレッドシート内の情報を入力として、外部で処理を実施し、その結果をシートへ出力する方法を検討しました。

構成

スプレッドシート内の情報を入力として、外部で処理を行うには、外部にAPIサーバを構築する方法があります。 その場合、実装を可能な限り最小限とし、コストをかけずに構築することが望ましいです。 そこで、今回はCloud RunにAPIサーバを立て、Apps ScriptでCloud Runへアクセスするアーキテクチャを構築することにしました。

構成は以下の通りです。

構成

Apps Scriptのコードからスプレッドシートの情報を取得した上で、Cloud Runへ認証及びhttpsアクセスを行い、処理結果をスプレッドシートへ追記します。 本記事では、Apps ScriptからCloud Runへの認証方法について説明します。

Apps ScriptからCloud Runへの認証

Apps ScriptからCloud Runへの認証を行うには、以下が必要となります。

  • (Apps Script): OpenID Connectの仕様に準拠したIDトークンの取得
  • (Apps Script): OAuthスコープの設定
  • (Google Cloud): OAuth同意画面の設定
  • (Apps Script): Cloudプロジェクトの変更
  • (Cloud Run): OAuthクライアント情報の反映

ここからは具体的な手順について説明します。

OpenID Connectの仕様に準拠したIDトークンの取得

Cloud Runでは、IAMのCloud Run起動元ロールとしてallUsersを付与すると、認証を行わずにアクセス可能です。 しかし、今回は、Cloud Runへのアクセスを特定のアカウントに限定したかったため、アクセスを行うアカウントにroles/run.invokerロールを付与しました。

Cloud Runでは、Googleによって署名されたIDトークンAuthorization: Bearer ヘッダーの後に付与することで、認証を行います。IDトークンは、OpenID Connectの仕様に準拠したJWT(JSON Web Token)です。 例えば、Cloud StorageのJSON APIに対するリクエストは、OAuth2.0アクセストークンで認証が可能ですが、Cloud RunはOAuth2.0アクセストークンではなくIDトークンを利用します。 Apps Scriptでは、ScriptApp.getIdentityToken()でOpenID Connectに準拠したIDトークンを取得することができます。しかし、そのままScriptApp.getIdentityToken()を用いるだけでは、まだCloud Runへの認証は通りません。

OAuthスコープの設定

Apps Scriptの実行に必要な権限をOAuthスコープとして定義します。 Apps Scriptの設定画面からappsscript.jsonを編集可能にする設定及びappsscript.jsonの編集を行います。 具体的には、appsscript.jsonのoauthScopesは以下のように設定します。


  "oauthScopes": [
    "openid",
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/spreadsheets"
  ]

それぞれのスコープの設定理由について、以下で説明します。

OAuth同意画面の設定

Apps ScriptのCloudプロジェクトを変更するためには、CloudプロジェクトでOAuth同意画面の設定を終わらせておく必要があります。 OAuth同意画面では、ユーザへ表示する情報を設定することができます。今回であれば、Apps Scriptを実行するユーザへ表示する情報を設定します。表示する情報を手順に従って、作成しておきます。このOAuth同意画面の設定を終えていないと、Apps ScriptのCloudプロジェクト変更時にOAuth同意画面を設定しなければならない旨のエラー(In order to change your project, you will need to configure the OAuth consent screen. Configure your OAuth Consent details.)が表示されます。

Apps ScriptのCloudプロジェクト変更

Apps Scriptプロジェクトを作成するとデフォルトのCloudプロジェクトが作成されます。しかし、今回は既存にあるCloudプロジェクトに作成したCloud RunとApps Scriptを紐づけたいため、デフォルトのCloudプロジェクトではなく既存のCloudプロジェクト(標準のCloudプロジェクト)への変更が必要となります。まだCloudプロジェクトを作成していない場合は、新規作成し、APIの有効化を行います。既存のCloudプロジェクトへの変更自体はApps Scriptの設定画面で行います。 Apps Scriptの設定画面の「Google Cloud Platform(GCP) Project」で行うことができます。

Cloudプロジェクト変更画面

この画面で変更させたいCloudプロジェクトの番号を入力してください。入力後に(Project does not exist or you need edit access to it.)のエラーが出る場合は、Cloudプロジェクト自体が存在しないか、連携可能な権限がアカウントに付与されていません。権限の問題であれば、roles/editorロールを持つアカウントであれば、変更可能です。

Apps ScriptのCloudプロジェクトをデフォルトから変更することで、Cloudプロジェクトの、APIとサービス>認証情報のOAuth2.0クライアントIDの項目に新しくOAuth認証情報が作成されます。 Cloudプロジェクトの変更前後でScriptApp.getIdentityToken()のbodyの値をデコード1した値を見ると、audクレームの値が変化します。Cloudプロジェクト変更後は、audクレームの値が新しく作成されたOAuth2.0クライアントIDの値と一致します。

Cloud RunへのOAuthクライアント情報の反映

ここまででScriptApp.getIdentityToken()で有効なOpenID Connectに準拠したIDトークンが取得できるようになりました。しかし、まだApps ScriptからCloud Runへの認証は通りません。最後に新規作成したOAuth2.0クライアントIDの情報をCloud Runに反映する必要があります。(この後にCloud Runを新規に作成する場合は本手順は不要です)

反映するためにはCloud Runのリビジョン更新やインスタンスの新規作成を行う必要があります。以下のいずれかの方法で反映されることを確認済みです。

  • Terraformでの削除(terraform destroy)、作成(terraform apply)※ TerraformでCloud Runを構築している場合
  • 設定変更(gcloud run services update
  • インスタンスの削除(gcloud run services delete)、作成(gcloud run deploygcloud run services add-iam-policy-binding

以上を行うことで、Apps ScriptからCloud Runへの認証を通すことができます。

まとめ

本記事では、スプレッドシートでCloud Runを活用するため、OpenID Connect仕様のIDトークンを用いたApps ScriptからCloud Runへの認証方法についてご紹介しました。

Apps Scriptで、OpenID Connect仕様のIDトークンを取得するためには、OAuthスコープの設定やCloudプロジェクトの変更が必要となります。 Cloudプロジェクトの変更には、Google Cloudで、OAuth同意画面の設定が必要となります。 上記設定後、Cloud RunへOAuthクライアント情報の反映を行うことで、Apps ScriptからCloud Runへの認証が通るようになります。

  1. デコードするためのコードは、getIdentityToken()のドキュメントに記載されています。 


【PR】パートナー積極採用中!

ペパボ研究所では、新しいパートナーを求めています。詳細については、当研究所のトップページをご覧ください。