はじめに

Google Cloud の Cloud CDN および外部 Application Load Balancer(外部 ALB)に、
Private Bucket Access という機能が 2026年7月3日より GA(一般提供) となりました。
これにより、プライベートな Cloud Storage バケットに直接アクセスできるようになりました。

これまで静的コンテンツをLB経由で配信するには、バケットを allUsers に公開するか、
HMACの利用などかなりトリッキーな回避策を取るしかありませんでした。
今回のアップデートにより、バケットを非公開のまま安全にコンテンツを配信できるようになります。

従来の課題

バケットを公開する構成の問題点

LB経由でコンテンツを配信する場合でも、バケット自体は allUsers に公開する必要がありました。
これにより以下のような問題が生じていました。

課題 内容
直リンクが有効になる バケットURLへの直接アクセスが誰でも可能になり、LBを経由しないリクエストを防げない
WAFのIPフィルタリングを突破される Cloud ArmorのルールをLBに設定しても、バケットURL直打ちで完全に回避できてしまう
アクセス制御の粒度 バケット・オブジェクトレベルのIAMのみ
DDoS対策 LBを迂回されるとGoogle標準の保護のみ

セキュアにしたい場合の従来の回避策:Internet NEG + HMAC

バケットを非公開にしつつLB経由で配信するには、Backend Bucket ではなく
Internet NEG を使って Cloud Storage の API エンドポイントをバックエンドサービスとして登録し、
HMAC キーによる署名付きリクエストを LB が中継する構成が必要でした。

クライアント
│
▼
Cloud Load Balancer(バックエンドサービス)
│ └─ Internet NEG(storage.googleapis.com)
│ └─ カスタムヘッダーにHMAC署名を付与
▼
Cloud Storage(非公開バケット)

この構成はNEGの設定・HMACキーの管理・ローテーション対応など運用コストが高く、
Terraformによる再現性の担保も難しいものでした。

新機能:Private Bucket Access

今回追加された Private Bucket Access により、外部 ALB の Backend Bucket にプライベートなバケットをそのまま設定できるようになりました。
バケットを非公開にしたままLBからのアクセスが通ります。

クライアント
│ HTTPS
▼
外部 Application Load Balancer
│ ├─ Cloud Armor(WAF・IPフィルタリング)
│ └─ Cloud CDN
▼
Backend Bucket
▼
Cloud Storage(非公開バケット)
└─ バケットURLへの直接アクセスは403

LBを経由しないバケットURLへの直接アクセスはブロックされるため、
Cloud Armor のルールを確実に通すことができます。

対応ロードバランサー

Private Bucket Access が利用できるロードバランサーは以下の通りです。

  • Global external Application Load Balancer
  • Classic Application Load Balancer
    • 日本語表記:アプリケーション(クラシック) / 従来のアプリケーションロードバランサー

今回は Classic Application Load Balancer でも検証しましたが、問題なくアクセスできました。
※Regional系は未対応です。

LB と Storage の繋ぎ方

設定自体は従来と変わりません。Cloud Storage バケットをバックエンドバケットとして定義し、
ロードバランサーのバックエンドに指定するだけです。

resource "google_compute_backend_bucket" "static" {
name = "static-backend-bucket"
bucket_name = google_storage_bucket.static_content.name
enable_cdn = true
}

Private Bucket Access で新たに必要になった設定:HTTP LB への IAM 権限付与

従来のバックエンドバケット設定からの唯一の追加点がこの IAM 設定です。
逆に言えば、この1点を押さえるだけでプライベートバケットへの配信が実現できます。

LB が非公開バケットにアクセスするために、Google が自動で払い出す専用のサービスアカウントへ
roles/storage.objectViewer を付与する必要があります。

HTTP LB 用のGoogle管理サービスアカウント

service-{PROJECT_NUMBER}@https-lb.iam.gserviceaccount.com

このサービスアカウントは利用したことがない場合、プロジェクトの IAM 画面に表示されないことがあります
「Google提供のロール付与を含む」をONにすると確認できる可能性もありますが、付与作業はコンソールよりも
gcloud コマンドの方が確実です。

gcloud コマンドで権限付与

# プロジェクト番号を確認
gcloud projects describe YOUR_PROJECT_ID --format="value(projectNumber)"

# LB のサービスアカウントに objectViewer を付与
gcloud storage buckets add-iam-policy-binding gs://YOUR_BUCKET_NAME \
--member="serviceAccount:service-PROJECT_NUMBER@https-lb.iam.gserviceaccount.com" \
--role="roles/storage.objectViewer"

これらを設定することで、ロードバランサー経由でバケットの静的ファイルにアクセス可能になります。

権限がない場合の挙動

権限が付与されていない状態でバケットを非公開にすると、LB 経由のアクセスが 403 で返ります。
キャッシュが残っている可能性があるので、下記を参考にしてください。

Cloud CDN キャッシュのクリア方法

Cloud CDN を有効にしている場合、設定を更新してもキャッシュが残ることがあります。
コンテンツを即時反映させたい場合はキャッシュを手動で無効化します。

gcloud コマンドで無効化

# ワイルドカードで一括クリア
gcloud compute url-maps invalidate-cdn-cache URL_MAP_NAME \
--path "/*"

注意点

  • キャッシュの無効化は即時反映されますが、世界中のエッジに伝播するまで数分かかる場合があります。
  • /* で全キャッシュを削除すると一時的にオリジン(Cloud Storage)へのリクエストが集中するため、大規模なコンテンツ更新時は段階的なクリアを検討してください。

まとめ

Private Bucket Access の登場により、従来は複雑な回避策が必要だった「LB経由でプライベートバケットを配信する」構成が、
シンプルかつ安全に実現できるようになりました。

  • バケットを非公開のまま外部 ALB・Cloud CDN 経由で配信できる
  • Cloud Armor の WAF・IPフィルタリングをバイパスされるリスクがなくなる
  • 設定の肝は service-{PROJECT_NUMBER}@https-lb.iam.gserviceaccount.com への objectViewer 付与

セキュリティ要件の高い静的コンテンツ配信を検討している方は、ぜひ試してみてください。