はじめに
※ 本記事ではFirebaseにおいて異なるプロジェクト間における権限管理を題材にしています
大学院生エンジニアをやっているtsukaちゃんと申します。二ヶ月ほど前、アルバイト先の社長から「弊社で使っている何個かのサービスでLINEメッセージ配信機能を使いたいんだよね」という要望があり、複数プロジェクトで横断できるLINE Messaging APIを用いた配信アプリを開発しました。その際に問題となった異なるアプリ間でのデータの受け渡しについて自分が思うに最も簡単でセキュアな方法を共有したいと思います。
-
対象読者
Firebase / GCP を使ってマイクロサービス化(プロジェクト分割)しつつ、BigQuery / Firestore など別プロジェクトのデータへ セキュアに アクセスしたい人 -
まず結論
サービスアカウント + IAM で実現可能
原則サーバー経由(Cloud Run / Functions)で最小権限付与
プロジェクト構成
アーキテクチャ
- App A/B/C: フロント( Nuxt3 ), サーバー( Firebase functions )
- Message Sender Service: 共通の送信サービス(LINE配信アプリ)
- Analytics A/B/C: 各サービスのBigQuery / Firestore
- アプリ → 共通サービス →(サービスアカウント権限で)Analytics へのアクセス
権限モデル(IAM 付与の考え方)
ここではBigQueryを例に説明します。BigQueryとは、Google Cloud Platform (GCP) が提供するフルマネージド型のデータウェアハウス (DWH) サービスです。
- 付与先は “ターゲット側プロジェクト”(データを保持するプロジェクト)
- 付与対象は “呼び出し元のサービスアカウント”(Cloud Run/Functions の実行 SA)
- rolesで渡したい権限を付与 ( dataViewer: 参照権限, user: クエリ実行権限 )
- フロントから直接 BigQueryへ行かない(鍵の漏洩リスク&ルールで守りきれない)
リクエストの流れ(Sequence)
実践:IAM 付与コマンド(BigQuery)
🔒 原則: 付与は “データを持つプロジェクト” 側で行う。
👤 member は “呼び出し元の実行サービスアカウント”
プロジェクトのサーバーアカウントどこにある問題
ここを探すのを少し苦労しました。「IAMと管理 -> サービス アカウント」に飛びます。
「@developer.gserviceaccount.com」のアドレスを有するアカウントがこのプロジェクトのサーバー側のService Accountになります。

Message Sender Service に権限付与
以下のコードでMessage Sender Serviceから複数プロジェクトのBigQueryが参照できるようになります。
gcloud projects add-iam-policy-binding ${TARGET_PROJECT_ID}@appspot.gserviceaccount.com \
--member="serviceAccount:${CALLER_Servie_Account}" \
--role="roles/bigquery.dataViewer" # クエリ参照権限
--role="roles/bigquery.user" # クエリ実行権限
注意: Firestore を “別プロジェクト” からクライアントSDK(ブラウザ)で直接読む構成は避け、必ずサーバー経由で、サービスアカウント権限の範囲で読み出す
フロントエンドから直接アクセスしない理由と回避策
- ブラウザに サービスアカウント鍵を置けない(置いた瞬間に漏洩)
- Firebase Security Rules は “同一プロジェクトのFirestore/Storage” を守る仕組みであり、他プロジェクトのBigQueryは守れない
問題点
問題点1: デバッグ環境での権限確認が難しい
本番環境に権限を付与しているため、デプロイしないとサーバー側の挙動確認ができません。
そのため開発環境ではローカルで他サービスの serviceAccountKey を参照する構成にしており、開発者全員に鍵を共有する必要なのが手間であり、漏洩リスクにもつながります。
問題点2: BigQueryの参照権限の制約
roles/bigquery.dataViewer のみで参照はできても SELECT 文を実行できません。
読み取りだけを許可したい場合、サーバー側で SELECT文以外を受け付けない制御を入れる必要があります。
まとめ
BigQuery権限早見表
| ユースケース | 最小ロール例 | 補足 |
|---|---|---|
| 読み取りだけ(BI出力等) | roles/bigquery.dataViewer + roles/bigquery.user | サーバー側で SELECT文以外を拒否(SQLバリデーション必須) |
| 既存テーブルのクエリだけ | roles/bigquery.dataViewer + roles/bigquery.user |
dataViewer は参照、user はジョブ実行 |
| 新規テーブル作成も必要 | 上記 + roles/bigquery.dataEditor(限定) or dataset単位権限 | プロジェクトではなく データセット単位 で付与推奨 |
SQL の簡易バリデーション(SELECT のみ許可)
export function assertSelectOnly(sql: string) {
const s = sql.trim().toLowerCase();
if (!s.startsWith('select')) throw new Error('Only SELECT is allowed');
const forbidden = ['insert', 'update', 'delete', 'merge', 'drop', 'alter', 'create'];
if (forbidden.some(k => s.includes(k))) throw new Error('Mutating statements are not allowed');
}
最低限の注意点
- 注意点1: “serviceAccountKeyをsecret managerで管理すれば?” → 公式ドキュメント非推奨
- 注意点2: “フロントから直接 BigQuery にアクセスできないか?” → 鍵管理の観点でNG
- 注意点3: 呼び出し元プロジェクトでロールを付ける → データのある側で付与が正解
- 注意点4: プロジェクト単位で広く付与 → まずは データセット単位 で最小権限
感想
- Firebase のマイクロサービス化は プロジェクト分割 + IAM + 実行SA が鍵
- 異プロジェクト間アクセスは サーバー経由 で 最小権限 を徹底
- セキュアだが開発者に負担があるので、プロダクト横断で “安全に再利用” できる基盤 or 他にいい方法があるならコメントお待ちしております

