6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ソニックガーデン プログラマAdvent Calendar 2024

Day 21

Cloud Functionsのサービスアカウントを指定しよう。

Last updated at Posted at 2024-12-20

この記事は「ソニックガーデン プログラマ - Qiita Advent Calendar 2024」21 日目の記事です。


はじめに

Cloud Functions for Firebase(以下 Functions) は実行する際にサービスアカウントというアカウントを用いて実行されます。これは一般的な Google Cloud のユーザーではなく、Google Cloud のサービスを実行する専用の特別なアカウントで、固有のメールアドレスを持っています。

Functions をから Firebase のサービスを利用する場合は Firebase Admin SDK を使うので意識しなくてもよいですが、Google Cloud の API にアクセスしようとすると Functions を実行しているサービスアカウントに Google Cloud の API を実行するための権限を追加で付与する必要がある場合もあります。

Functions で使われるサービスアカウント

デフォルトで使用されるサービスアカウントは Functions の第 1 世代・第 2 世代で異なります。それぞれ以下のサービスアカウントが実行時に利用されます。

  • Functions 第 1 世代: [プロジェクトID]@appspot.gserviceaccount.com
  • Functions 第 2 世代: [プロジェクトID(数値)]-compute@developer.gserviceaccount.com

このように実行する Functions の世代によって使われるサービスアカウントは異なりますが、権限としてはどちらも「編集者」ロールが付与されているので、できることは同じになります。

では「編集者」ロールでは何ができるのか確認してみると、なんと 9133 個もの権限が付与されています。説明にもある通り「ほとんどの Google Cloud リソースを表示、作成、更新、削除」できるそうです。

CleanShot 2024-12-19 at 21.25.23@2x.png

つまりデフォルトのサービスアカウントでほとんど全てのことができるので問題ないですね!
...とはなりません。

このサービスアカウントのアクセスキーが万が一漏れてしまった場合、「ほとんどの Google Cloud リソースを表示、作成、更新、削除」される可能性があります。そもそも Functions を動かすにあたって、9133 個の権限は明らかに過剰です。必要最小限の権限で Functions を動かすようにすれば、もし万が一アクセスキーが漏れてしまっても影響範囲を最小限にすることができるので、不要な権限は持たせないようにしましょう。

サービスアカウントを作成する

サービスアカウントは自分で作成することもできます。
Google Cloud の[IAM と管理] - [サービスアカウント]を開き、「サービスアカウントを作成」ボタンから作成することができます。

CleanShot 2024-12-19 at 21.45.34@2x.png

作成後、ロールを設定できますが一旦なにも設定せずに完了します。

CleanShot 2024-12-19 at 21.50.29@2x.png

これでまっさらなサービスアカウントを作成することができました。

作成したサービスアカウントを Functions で利用する

作成したサービスアカウントを使用して Functions から BigQuery にアクセスしてみましょう。
以下のように、BigQuery の Dataset の有無を返す単純な onRequest 関数を作成してみます。1 この時、onRequest のオプションにserviceAccountとして先ほど作成したサービスアカウントのメールアドレスを設定します。これでこの関数を実行する際は指定したサービスアカウントで動作するようになります。

import { BigQuery } from '@google-cloud/bigquery';
import { onRequest } from 'firebase-functions/v2/https';

export const datasetExists = onRequest(
  { serviceAccount: 'cloud-functions@[プロジェクトID].iam.gserviceaccount.com' },
  async (request, response) => {
    const bigQuery = new BigQuery();
    const dataset = bigQuery.dataset('sample_dataset');
    const [isExists] = await dataset.exists();
    response.status(200).send(isExists);
  }
);

この関数を実行するとエラーになります。エラーメッセージにあるようにbigquery.datasets.get権限が不足していますね。

Error: Access Denied: Dataset [プロジェクトID]:sample_dataset: Permission bigquery.datasets.get denied on dataset [プロジェクトID]:sample_dataset (or it may not exist).

サービスアカウントにbigquery.datasets.get権限を含むロールを付与してあげましょう。ここでは「BigQuery データ閲覧者」を付与します。

CleanShot 2024-12-19 at 22.29.36@2x.png

この後、改めて関数を実行するとtrueが返ってきて、BigQuery へのアクセスができたことがわかります。

まとめ

Functions ではserviceAccountに自作のサービスアカウントを設定し、必要最低限の権限(ロール)を付与しましょう!


次回、「ソニックガーデン プログラマ - Qiita Advent Calendar 2024」22 日目は @interu です。お楽しみに!

  1. 事前に Google Cloud で BigQuery API を有効にし、sample_datasetというデータセットを作成しておきます。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?