はじめに
※ 本記事はCloud Run services(HTTPリクエストを処理するサービス)を対象としています。Cloud Run jobs(バッチ処理)やCloud Run worker pools(pull-based処理)には適用されません。
Cloud Runは「コンテナをデプロイすれば即座にHTTPSエンドポイントが手に入る」手軽さが魅力ですが、エンタープライズ環境では 「どこまで公開するのか?」「誰を通すのか?」 という設計が不可欠です。
しかし、アクセス制御は「Ingress(ネットワーク)」と「IAM(認証)」、さらに「Load Balancer(エッジ)」が重なり合っており、初見では混乱しがちです。本記事では、これらをレイヤーごとに分解し、セキュアな構成を作るための技術的基礎を解説します。
1. 全体像:2つの独立した「壁」
Cloud Runへのリクエストは、以下の2つの独立したチェックを順番に、かつ両方クリアする必要があります。
| レイヤー | 問い | 設定箇所 |
|---|---|---|
| ネットワーク層 (Ingress) | 「物理的に到達できるか?」 | Ingress設定 |
| アイデンティティ層 (IAM) | 「そのリクエストは許可されているか?」 | roles/run.invoker |
重要: これらは「AND条件」です。例えば、IAMで allUsers(全員許可)にしていても、Ingressを「内部」に制限していれば、インターネットからは到達できません。逆に、Ingressが「すべて」でも、IAM権限がなければ 403 Forbidden になります。
2. 第1の壁:ネットワーク層(Ingress)
Ingress設定は、Cloud Runサービスが「どの経路からのトラフィックを受け入れるか」を制御します[1]。
Ingress設定の比較
| 設定 | アクセス可能な経路 | Cloud Scheduler | 主な用途 | 直接アクセス防止 |
|---|---|---|---|---|
| すべて | インターネット全体 | ✓ 可能 | 公開Webサイト、外部API | ✗ |
| 内部 | VPC内のリソースのみ | ✓ 可能 ※ | マイクロサービス間通信 | ✓ |
| 内部とLB | VPC内 + Cloud Load Balancer | ✓ 可能 ※ | WAF/IAP利用時 | ✓ |
※ 同じプロジェクト内であればアクセス可能(OIDC認証が必要)。詳細は後述[1][2]。
A. すべて (All)
- 挙動: インターネット全体からの直接アクセスを許可します。
- 用途: 公開Webサイト、外部API。
-
注意:
run.appのURLが公開されます。後述するIAMで制限をかけないと、誰でも実行できてしまいます。
B. 内部 (Internal)
-
挙動: インターネットからの直接アクセスを遮断。以下のソースからのみ到達可能です[1][2]:
- 同一プロジェクト内のVPCネットワーク
- 設定されたShared VPCネットワーク
- VPC Service Controlsペリメータ内のリソース(※1)
- 同じプロジェクト/ペリメータ内の特定のGCPサービス(Cloud Scheduler、Cloud Tasks、Eventarcなど)
- 用途: マイクロサービス間通信など、VPC内部での利用に限定したい場合。
※1 ペリメータ: 複数のプロジェクトやリソースを囲むセキュリティ境界。境界内のリソースは相互にアクセス可能。
C. 内部と Cloud Load Balancing (Internal and Cloud Load Balancing)
- 挙動: VPC内部リソースと、Cloud Load Balancer (LB) からのトラフィックのみを許可します[1]。
- 用途: WAF (Cloud Armor) や IAP を使用する場合。
-
メリット: 攻撃者が
run.appの直URLを使用してLoad Balancerを迂回することを完全に防げます[1][5]。これにより、Cloud ArmorやIAPなどのセキュリティ機能を確実に適用できます。
【補足】Cloud Schedulerからの呼び出しに関する注意
Cloud SchedulerやCloud Tasksから「内部」または「内部とLB」に設定されたCloud Runを呼び出す場合、同じプロジェクト内であればアクセス可能ですが、適切な認証設定が必要です[2][3]。
必要な設定(同じプロジェクト内の場合):
- Cloud Scheduler用のサービスアカウントを作成し、
roles/run.invokerを付与[4] - Cloud SchedulerジョブでOIDC(OpenID Connect)トークン認証を設定[3]
その他の選択肢:
- 推奨(シンプル): Ingressを「すべて」に設定し、IAM権限で呼び出し元のサービスアカウントを制限する
- Cloud Schedulerの場合、HTTPターゲットではなくPub/Sub経由で連携する
3. 第2の壁:アイデンティティ層(IAM)
ネットワーク的に到達できても、適切な roles/run.invoker(呼び出し元)ロールがなければ実行できません[4]。
公開設定:allUsers
- 認証なしで誰でもアクセス可能です。
-
組織ポリシーの注意: 企業環境では組織ポリシー(
iam.allowedPolicyMemberDomains)により、allUsers への付与が禁止されている場合があります[9]。その場合は、特定のGoogleグループやドメインを指定する必要があります。
非公開設定:特定のIDに制限
- システム対システム: 呼び出し元(Cloud Scheduler等)のサービスアカウントに権限を付与します。リクエスト時に Authorization: Bearer <ID_TOKEN> ヘッダーが必要です[4]。
- 人対システム: ブラウザからアクセスさせる場合、Cloud Run単体ではログイン画面がないため、後述する IAP と組み合わせるのが一般的です。
4. エッジでの高度な保護:Cloud Armor と IAP
より高度な制御が必要な場合、Cloud Runの前段に機能を配置します。現在、特に IAP に関しては2つの構成パターンが存在します。
A. ロードバランサー連携型 (外部ALB + IAP)
Cloud Armorやマルチリージョン統合管理が必要な場合の構成です。カスタムドメイン(api.example.com など)の運用にも対応できます[5]。
- メリット: Cloud Armor(WAF: Web Application Firewall)を併用して、IP制限やGeo制限、SQLi対策が可能[6]。
- デメリット: ロードバランサーの基本料金が発生する。
- Ingress設定: 「内部と Cloud Load Balancing」を選択[1][5]。
【補足】403 Forbidden エラーの回避方法
LB連携型IAPを有効にした際、Cloud Run側のIAMに個人のGoogleアカウントを追加しても 403 Forbidden になることがあります。
なぜこの問題が起きるのか:
IAPはユーザー認証を行い、認証されたユーザー情報をヘッダー(X-Goog-IAP-JWT-Assertion)に埋め込みますが[7]、Cloud Runへのリクエストには別途認証が必要です。IAPからCloud Runへの呼び出しはシステム間通信であり、ユーザーの認証情報とは別のレイヤーで動作します。
必要なIAM設定:
- IAPサービスエージェント(
service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com)にroles/run.invokerを付与[8] - エンドユーザーに
roles/iap.httpsResourceAccessorを付与してIAP経由でのアクセスを許可[8] - Cloud Run側のIAMには個人のアカウントを直接登録する必要はありません(IAPが「人」を、IAPサービスエージェントが「システム」を認証する役割分担になります)
B. Cloud Run 直接適用型 (IAP for Cloud Run)
Googleが推奨する構成で、2025年4月にPreview(プレビュー版)として提供されました[8][10]。なお、Load Balancer経由のIAP構成は2023年にGA(一般提供)されています[10]。
-
メリット: LB不要で低コスト。設定が非常にシンプル。
run.appを直接保護[8]。 - デメリット: Cloud Armorが併用できない。マルチリージョン統合管理が不可。Preview版のため、本番環境での利用は慎重に検討する必要があります。
- Ingress設定: 原則「すべて」を選択。
必要なIAM設定:
- IAPサービスエージェント(
service-[PROJECT-NUMBER]@gcp-sa-iap.iam.gserviceaccount.com)にroles/run.invokerを付与[8] - エンドユーザーに
roles/iap.httpsResourceAccessorを付与[8]
5. 構成の選び方:要件別ガイド
| 要件 | Ingress設定 | IAM設定 | 推奨エッジ機能 |
|---|---|---|---|
| 完全公開Web | すべて | allUsers | なし (直接公開) |
| 内部マイクロサービス | 内部 | 呼び出し元サービスアカウント | なし (VPC内通信) |
| WAF/IP制限をかけたい | 内部とLB | 署名用サービスアカウント ※1 | Cloud Armor |
| 安価に社内限定公開 | すべて | 適切に制限 ※2 | IAP (直接適用型) |
| カスタムドメインで社内公開 | 内部とLB | 署名用サービスアカウント | LB + IAP |
※1:理論的には allUsers でも Cloud Armor で保護されますが、最小権限の原則に従い署名用サービスアカウントを指定することを推奨します。
※2:組織ポリシーで allUsers が禁止されている場合は、特定のGoogleグループ(例:group:employees@example.com)やドメイン全体(domain:example.com)を指定します。
6. トラブルシューティング
よくあるエラーと解決方法
以下は、Cloud Runのアクセス制御で遭遇する代表的なエラーと解決方法です[11]。
| エラー | 原因 | 解決方法 |
|---|---|---|
| 403 Forbidden | IAM権限不足 | 呼び出し元に roles/run.invoker を付与 |
| 404 Not Found | Ingress設定で到達不可 | Ingress設定を確認(内部→すべて、またはLB経由に変更) |
| Cloud Schedulerから呼べない | 内部Ingressで到達不可 | 同一プロジェクト内か確認(同プロジェクトならOIDC認証設定を確認)。別プロジェクトの場合はIngressを「すべて」にしてIAMで制限、またはVPC Connector使用 |
| IAPで認証後に403 | IAPサービスエージェントへのIAM権限不足 | IAPサービスエージェントに roles/run.invoker 権限が付与されているか確認(セクション4-A参照) |
7. まとめ
Cloud Runのセキュリティは、 「Ingressで経路を絞り、IAMで人を絞る」 という2段構えが基本です。この基盤の上に、要件に応じてCloud Armor(WAF/IP制限)やIAP(社内限定公開)といったエッジ保護を追加することで、セキュアな構成を実現できます。
まずはセクション5の要件別ガイドを参考に、自分のユースケースに最適な構成を選択しましょう。設定後に問題が発生した場合は、セクション6のトラブルシューティングを確認してください。
参考文献
- Restrict network ingress for Cloud Run | Google Cloud
- Private networking and Cloud Run | Google Cloud
- Running services on a schedule | Google Cloud
- Authenticating service-to-service | Google Cloud
- Set up a global external Application Load Balancer with Cloud Run | Google Cloud
- Google Cloud Armor overview | Google Cloud
- Getting the user's identity | Identity-Aware Proxy | Google Cloud
- Enabling IAP for Cloud Run | Google Cloud
- Restricting identities by domain | Resource Manager | Google Cloud
- IAP release notes | Identity-Aware Proxy | Google Cloud
- Troubleshoot Cloud Run issues | Google Cloud