Cloud Storageの保持ポリシーの設定手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、 「どうやって直すのか?」 という具体的な修復手順(コンソール、gcloud CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、Cloud Storageバケットで保持ポリシーが未設定の場合のリスクと対策を解説します。

ポリシーの説明
Cloud Storageバケットの保持ポリシーは、オブジェクトが削除または上書きされることを防ぐ最小保持期間を設定する機能です。これにより、規制要件への準拠や重要データの誤削除防止が可能になります。
リスク
保持ポリシーが未設定の場合、以下のリスクが発生します:
- 重要なデータや監査ログが誤って削除される可能性
- 規制要件(GDPR、HIPAA、金融規制など)の保持期間要件を満たせない
- 内部不正による意図的なデータ削除を防げない
- インシデント調査時に必要な証跡が失われる可能性
- ランサムウェア攻撃によるデータ削除を防げない
修復方法
コンソールでの修復手順 Google Cloud コンソールを使用して、Cloud Storageバケットに保持ポリシーを設定します。
- Google Cloud Consoleで「Cloud Storage」→「バケット」を開きます

- 対象のバケット名をクリックします
- 「保護」タブを選択します
- 「保持ポリシー」セクションで「編集」をクリックします

- 保持期間を設定します:
- 日数、月数、または年数で指定
- 例:監査ログは7年、バックアップは30日など
- 「保存」をクリックして設定を適用します
- (オプション)保持ポリシーをロックする場合:
- 「保持ポリシーをロック」をクリック
- 警告メッセージを確認し、バケット名を入力
- 「ポリシーをロック」をクリック
- 注意:ロック後は保持期間の短縮や削除ができません
Terraformでの修復手順
Cloud Storageバケットに保持ポリシーを設定するTerraformコードと、主要な修正ポイントを説明します。
# プロジェクトデータソース
data "google_project" "current" {}
# 基本的な保持ポリシー設定
resource "google_storage_bucket" "example" {
name = "retention-policy-bucket-${data.google_project.current.project_id}"
location = "US"
force_destroy = false
# 保持ポリシーの設定(30日間)
retention_policy {
retention_period = 2592000 # 30日(秒単位)
is_locked = false # ロックしない(後で変更可能)
}
# バージョニングを有効化(推奨)
versioning {
enabled = true
}
# 均一なバケットレベルアクセスを有効化
uniform_bucket_level_access {
enabled = true
}
# パブリックアクセスを防止
public_access_prevention = "enforced"
labels = {
purpose = "general-storage"
managed_by = "terraform"
}
}
# 監査ログ用バケット(長期保持・ロック付き)
resource "google_storage_bucket" "audit_logs" {
name = "audit-logs-retention-${data.google_project.current.project_id}"
location = "US"
force_destroy = false
# 7年間の保持ポリシー(規制要件対応)
retention_policy {
retention_period = 220752000 # 7年(秒単位)
is_locked = true # ポリシーをロック(変更不可)
}
# イベントベースの保持を有効化
default_event_based_hold = false
versioning {
enabled = true
}
uniform_bucket_level_access {
enabled = true
}
public_access_prevention = "enforced"
# 暗号化設定(CMEKを使用)
encryption {
default_kms_key_name = google_kms_crypto_key.bucket_key.id
}
labels = {
purpose = "audit-logs"
compliance = "required"
retention = "7-years"
}
}
# バックアップ用バケット(短期保持)
resource "google_storage_bucket" "backups" {
name = "backups-retention-${data.google_project.current.project_id}"
location = "US"
# 90日間の保持ポリシー
retention_policy {
retention_period = 7776000 # 90日(秒単位)
is_locked = false
}
# ライフサイクルルールと組み合わせ
lifecycle_rule {
condition {
age = 365 # 1年後に削除(保持期間後)
}
action {
type = "Delete"
}
}
versioning {
enabled = true
}
labels = {
purpose = "backups"
retention = "90-days"
}
}
# 法的保持用バケット(イベントベース保持)
resource "google_storage_bucket" "legal_hold" {
name = "legal-hold-${data.google_project.current.project_id}"
location = "US"
# 基本的な保持ポリシー
retention_policy {
retention_period = 31536000 # 1年(秒単位)
is_locked = false
}
# デフォルトでイベントベース保持を有効化
default_event_based_hold = true
versioning {
enabled = true
}
labels = {
purpose = "legal-hold"
compliance = "required"
}
}
# KMS暗号鍵(保持ポリシーと組み合わせて使用)
resource "google_kms_key_ring" "bucket_keyring" {
name = "bucket-keyring"
location = "us"
}
resource "google_kms_crypto_key" "bucket_key" {
name = "bucket-crypto-key"
key_ring = google_kms_key_ring.bucket_keyring.id
rotation_period = "7776000s" # 90日ごとにローテーション
lifecycle {
prevent_destroy = true
}
}
# 保持ポリシーの監視アラート
resource "google_monitoring_alert_policy" "retention_policy_violation" {
display_name = "Bucket Retention Policy Violation"
combiner = "OR"
conditions {
display_name = "Retention policy removed"
condition_threshold {
filter = <<-EOT
resource.type="gcs_bucket"
protoPayload.methodName="storage.buckets.patch"
protoPayload.request.retentionPolicy.retentionPeriod="0"
EOT
duration = "0s"
comparison = "COMPARISON_GT"
threshold_value = 0
}
}
notification_channels = [google_monitoring_notification_channel.email.id]
alert_strategy {
auto_close = "86400s" # 24時間後に自動クローズ
}
}
# 通知チャンネル
resource "google_monitoring_notification_channel" "email" {
display_name = "Security Team Email"
type = "email"
labels = {
email_address = "security-team@example.com"
}
}
# 保持ポリシーの使用例:オブジェクトの作成
resource "google_storage_bucket_object" "example" {
name = "important-document.pdf"
bucket = google_storage_bucket.example.name
source = "path/to/document.pdf"
# オブジェクトレベルでイベントベース保持を設定
event_based_hold = true
metadata = {
retention_reason = "legal_requirement"
created_date = timestamp()
}
}
最後に
この記事では、Cloud Storageバケットで保持ポリシーが未設定の場合のリスクと対策を解説しました。
適切な保持ポリシー設定により:
- 規制要件への確実な準拠
- 重要データの誤削除防止
- ランサムウェア攻撃からの保護
- 法的証拠の保全
- 内部不正からのデータ保護
を実現できます。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。