はじめに
第1回では Cloud Run・Cloud Workflows・Firestore を中心に、サーバーレス設計を解説しました。
本稿では、そのシステムを「守る」ための設計に踏み込みます。
- IAP:アプリのコードを変更せずに認証・認可を実現する
- VPC + Private Google Access:Firestore への通信をインターネットに出さない
- Workload Identity Federation:CI/CD でサービスアカウントキーを持たない
設計方針を一言で表すと「アプリケーション層の外側でセキュリティを完結させる」です。
認証ロジックをアプリに書かない、サービスアカウントキーを発行しないという方針が、コードをシンプルに保ちながら高いセキュリティレベルを実現します。
Identity-Aware Proxy(IAP)
課題
本システムは社内限定ツールです。アクセスできるのは特定のメンバーに限定する必要があります。
従来の実装では、アプリにログイン画面を作り、セッション管理を実装し、権限チェックを各 API に差し込む——という作業が必要でした。
IAP が解決すること
IAP は Cloud Run の前段に配置し、リクエストをインターセプトするプロキシです。
ユーザーが URL にアクセスすると、IAP が Google ログイン画面へリダイレクトし、認証済みユーザーのみを通過させます。

アプリケーション側は認証を一切意識しません。
Cloud Run に届くリクエストは「すでに認証済みのユーザーからのもの」が保証されています。
こちらのブログも併せてご覧ください!
1クリックで社内アプリを保護:Cloud RunのIAP認証がとにかく便利!
実装上のポイント
アクセス許可は IAM ポリシーで管理
IAP のアクセス制御は IAM の roles/iap.httpsResourceAccessor ロールで管理します。
メンバーの追加・削除はコンソールまたは Terraform で行い、アプリのコードには手を触れません。
本システムでは開発者アカウントと iPad 用の共有アカウントのみを許可しています。
Cloud Run の Ingress 設定は「すべて許可」
一見すると意外ですが、IAP を有効化する場合、Cloud Run 側の Ingress は「すべてのトラフィックを許可」に設定します。
IAP 自体がリクエストをインターセプトするため、Cloud Run レベルで IP 制限をかける必要がありません。
セキュリティは IAP と IAM ポリシーの組み合わせで担保します。
ユーザー情報はヘッダーで受け取る
IAP を通過したリクエストには x-goog-authenticated-user-email ヘッダーが付与されます。
アプリはこのヘッダーを参照するだけでログイン中のユーザーを特定できます。
セッション管理の実装が不要になります。
Cloud Workflows との組み合わせ
第1回で解説した Cloud Workflows(定期バッチのオーケストレーター)も、Cloud Run の前段にある IAP を通過してAPIを呼び出します。
Workflows はサービスアカウントを使って署名付き JWT を自動生成し、IAP の認証を通過します。
人間のユーザーと同じ認証フローを、コードなしで実現できる点が Google Cloud の IAM エコシステムの強みです。
VPC
なぜ VPC が必要か
Cloud Run はサーバーレスであり、デフォルトではパブリックインターネット経由で外部サービスにアクセスします。
Firestore も firestore.googleapis.com というパブリックエンドポイントを持っており、アクセスは暗号化されていますが、トラフィックが一度インターネットに出ることになります。
非機能要件として「GCP 内の通信はプライベートサブネット内で完結させる」を掲げているため、VPC を構成して Firestore へのアクセスをプライベート経路に閉じています。
構成の全体像

Direct VPC Egress
Cloud Run は通常 VPC の外側で動作します。
Direct VPC Egress を設定することで、Cloud Run のコンテナが VPC サブネットのネットワークインターフェースを持ち、VPC 経由でトラフィックをルーティングできるようになります。
本システムでは Egress タイプを ALL_TRAFFIC に設定しています。
これにより Firestore への通信も Slack への通信も、すべて一度 VPC を経由します。
経路の一元化がセキュリティポリシーの適用を単純にします。
Private Google Access + Cloud DNS:Firestore への非公開経路
VPC 内から firestore.googleapis.com にアクセスする際、通常の DNS 解決ではパブリック IP が返ります。
Private Google Access と Cloud DNS を組み合わせることで、VPC 内からのアクセスをプライベート IP に向けることができます。
設定の仕組みは以下のとおりです。
① サブネットで Private Google Access を有効化
VPC サブネットの設定で Private Google Access を有効にします。
これにより、そのサブネット内のリソースがパブリック IP なしで Google API にアクセスできます。
② Cloud DNS でプライベートゾーンを作成
VPC に紐付いたプライベート DNS ゾーンを作成します。
| DNS 名 | レコードタイプ | 解決先 |
|---|---|---|
private.googleapis.com. |
A | 199.36.153.8/30(Google の VIP 範囲) |
*.googleapis.com. |
CNAME | private.googleapis.com. |
*.googleapis.com をワイルドカードで private.googleapis.com に CNAME しておくことで、firestore.googleapis.com も calendar.googleapis.com も、VPC 内からのアクセスはすべてプライベート VIP に解決されます。
199.36.153.8/30 は Google が Private Google Access 用に予約している IP 範囲であり、トラフィックは Google の内部ネットワーク経由でルーティングされます。
③ 通信の結果
Cloud Run → VPC → プライベート DNS → 199.36.153.8/30 → Google 内部ネットワーク → Firestore。パブリックインターネットを一切経由しません。
Cloud NAT
Direct VPC Egress で ALL_TRAFFIC を VPC 経由にすると、Slack API などの外部インターネットへの通信も VPC を経由します。
VPC 内のリソースはプライベート IP しか持たないため、そのままではインターネットへ出ていけません。
ここで Cloud NAT が必要になります。

Cloud NAT はパブリック IP アドレスを自動割り当てします。
Slack 側でアクセス元 IP を制限したい場合は、Cloud NAT に固定 IP を割り当てることで IP アドレスベースのアクセス制御も可能になります。
セキュリティ上のメリット整理
この VPC 構成によって得られるセキュリティ上の利点をまとめます。
| 利点 | 実現方法 |
|---|---|
| Firestore への通信がインターネットを経由しない | Private Google Access + プライベート DNS |
| 外部への通信が一元管理される | Cloud NAT による SNAT |
| VPC 外からプライベート DNS を利用できない | DNS ゾーンの可視性をプライベート(VPC 内限定)に設定 |
Workload Identity Federation:CI/CD でキーを持たない
サービスアカウントキーの問題
GitHub Actions から Google Cloud へデプロイする際、従来はサービスアカウントキー(JSON ファイル)を GitHub Secrets に保存する方法が一般的でした。
この方法には課題があります。
- キーが漏洩すると GCP プロジェクトへの不正アクセスが可能になる
- キーの有効期限管理・ローテーションが必要
- 誤って履歴に含めてしまうリスクがある
Workload Identity Federation の仕組み
Workload Identity Federation は、外部の ID プロバイダー(GitHub Actions の場合は GitHub の OIDC)を Google Cloud IAM と連携させる仕組みです。
サービスアカウントキーを発行・管理することなく、GitHub Actions から GCP リソースにアクセスできます。

GitHub Actions 側では id-token: write パーミッションを付与するだけです。
実行時に GitHub が発行する短命の OIDC トークンを Google Cloud が検証し、条件に合致する場合のみサービスアカウントの権限を一時的に付与します。
条件の設定例
| 条件 | 設定 |
|---|---|
| リポジトリ | repo:org/repo-name:* のみ許可 |
| ブランチ | refs/heads/develop または refs/heads/main のみ許可 |
この条件により、同じ組織でも別リポジトリからの不正な利用を防ぎます。
IAP との連携
ここで第1回・第2回を通じた構成全体を振り返ると、キーを一切持たない設計が完成していることがわかります。
| コンポーネント | キーレス認証の方法 |
|---|---|
| ユーザー → Cloud Run | IAP + Google Workspace アカウント |
| Cloud Workflows → Cloud Run | サービスアカウントによる署名付き JWT(キー不要) |
| Cloud Run → Firestore | Workload Identity(Cloud Run のサービスアカウントが自動付与) |
| GitHub Actions → GCP | Workload Identity Federation(OIDC トークン) |
サービスアカウントキーの JSON ファイルが一切登場しない構成です。
まとめ
本稿では IAP・VPC・Workload Identity Federation を中心に、「アプリの外側でセキュリティを完結させる」設計を解説しました。
ポイントをまとめると:
- IAP を Cloud Run の前段に配置することで、認証・認可ロジックをアプリに書かず、ユーザー管理を IAM に一元化
- VPC + Private Google Access + Cloud DNS の組み合わせで、Firestore への通信経路をインターネットから切り離す。
*.googleapis.comを CNAME でまとめることで、Google API 全体をプライベート経路に向けられる - Cloud NAT で外部インターネットへの出口を一元管理し、必要に応じて固定 IP によるアクセス制御を可能にする
- Workload Identity Federation でサービスアカウントキーをなくし、OIDC トークンベースの一時的な権限委譲に切り替える
次回(第3回)は、データ分析基盤と DevOps を解説します。Firebase Extensions による Firestore → BigQuery のゼロ運用データパイプライン、Cloud Monitoring をはじめとしたオブザーバビリティ設計などを取り上げます。