Back to Checks
Cloud Storage log sink bucket has a retention policy with Bucket Lock enabled
cloudstorage_bucket_log_retention_policy_lock
Service: cloudstorageSeverity: high
OfficialBuilt-inVerified
Categories:loggingforensics-ready
Resource Type:storage.googleapis.com/Bucket
Cloud Storage log sink buckets have a configured retention period with Bucket Lock applied, ensuring the retention policy cannot be shortened or removed.
Risk
Without a locked retention policy, exported logs can be deleted early or retention reduced, undermining log integrity and availability. An attacker or malicious insider could purge evidence to evade detection, hindering forensics and weakening non-repudiation across the environment.
Run this check with Prowler
Run in Prowler CloudRun
prowler gcp --checks cloudstorage_bucket_log_retention_policy_lockRecommendation
Set a retention policy on every log sink bucket and enable Bucket Lock. Choose durations that meet investigative and regulatory needs. Enforce least privilege and separation of duties for bucket and logging administration, and apply defense in depth so no single actor can weaken log retention.
Remediation
CLI
gcloud storage buckets lock-retention-policy gs://<LOG_BUCKET_NAME>Terraform
resource "google_storage_bucket" "<example_resource_name>" {
name = "<example_resource_name>"
location = "<LOCATION>"
retention_policy {
retention_period = 86400 # Required: enable a retention policy (1 day)
is_locked = true # CRITICAL: locks the retention policy (Bucket Lock) to pass the check
}
}Other
1In Google Cloud Console, go to Storage > Buckets and open the bucket used by your Logs Router sink
2Click the Configuration tab
3Under Retention policy, click Edit, set any required retention duration, and click Save
4Click Lock retention policy, type LOCK to confirm, and confirm to permanently lock it
Check Code
from prowler.lib.check.models import Check, Check_Report_GCP
from prowler.providers.gcp.services.cloudstorage.cloudstorage_client import (
cloudstorage_client,
)
from prowler.providers.gcp.services.logging.logging_client import logging_client
class cloudstorage_bucket_log_retention_policy_lock(Check):
"""
Ensure Log Sink buckets have a Retention Policy with Bucket Lock enabled.
- PASS: Log sink bucket has a retention policy and is locked.
- FAIL: Log sink bucket has no retention policy, or it has one but is not locked.
"""
def execute(self) -> list[Check_Report_GCP]:
findings = []
# Get Log Sink Buckets
log_buckets = []
for sink in logging_client.sinks:
if "storage.googleapis.com" in sink.destination:
log_buckets.append(sink.destination.split("/")[-1])
for bucket in cloudstorage_client.buckets:
if bucket.name in log_buckets:
report = Check_Report_GCP(metadata=self.metadata(), resource=bucket)
report.status = "FAIL"
report.status_extended = (
f"Log Sink Bucket {bucket.name} has no Retention Policy."
)
if bucket.retention_policy:
report.status = "FAIL"
report.status_extended = f"Log Sink Bucket {bucket.name} has a Retention Policy but without Bucket Lock."
if bucket.retention_policy.is_locked:
report.status = "PASS"
report.status_extended = f"Log Sink Bucket {bucket.name} has a Retention Policy with Bucket Lock."
findings.append(report)
return findingsReferences
- https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/gcp/CloudStorage/retention-policies-with-bucket-lock.html
- https://docs.cloud.google.com/storage/docs/bucket-lock
- https://docs.cloud.google.com/storage/docs/using-bucket-lock
- https://docs.cloud.google.com/storage/docs/samples/storage-lock-retention-policy
- https://docs.cloud.google.com/logging/docs/export/configure_export_v2