WAF-SUS-050 โ Storage Lifecycle & Data Minimization
Description
All storage resources (S3 buckets, EBS volumes, Azure Blob Storage, GCS buckets) MUST have lifecycle policies defined. Data MUST be automatically tiered to cost- and energy-efficient cold storage after defined activity thresholds. Log data MUST have retention limits. Temporary data (build artifacts, test data, cache) MUST have explicit expiration. Unattached EBS volumes and unused snapshots MUST be detected and purged. Organizations MUST apply the principle of data minimization: store only what is needed, for as long as needed, in the most efficient tier.
Rationale
| Risk | Description |
|---|---|
Risk |
Unstructured storage lifecycles leave data on expensive, energy-intensive tiers. |
Risk |
Missing tiering strategies prevent automatic migration of less-used data. |
Requirements
-
All storage resources (S3 buckets, EBS volumes, Azure Blob Storage, GCS buckets) MUST have lifecycle policies defined.
-
Data MUST be automatically tiered to cost- and energy-efficient cold storage after defined activity thresholds.
-
Log data MUST have retention limits.
-
Temporary data (build artifacts, test data, cache) MUST have explicit expiration.
-
Unattached EBS volumes and unused snapshots MUST be detected and purged.
-
Organizations MUST apply the principle of data minimization: store only what is needed, for as long as needed, in the most efficient tier.
Implementation Guidance
-
Document the requirement in a version-controlled policy or standard.
-
Assign ownership and establish a review cadence (e.g., quarterly).
-
Implement the required configuration as code in Terraform or equivalent IaC.
Maturity Levels
| Level | Name | Criteria |
|---|---|---|
L1 |
Ad hoc โ control not consistently applied |
* Manual evidence exists for some workloads, but coverage is unknown. |
L2 |
Standardised โ policy defined and communicated |
* A version-controlled policy, ADR, or standard describes the requirement. |
L3 |
Integrated โ automated validation in CI/CD |
* Terraform checks run automatically on pull requests and report results. |
L4 |
Auditable โ metrics and exceptions tracked |
* Control coverage, failures, and approved exceptions are reported quarterly. |
L5 |
Optimised โ continuous improvement based on data |
* Control effectiveness is measured and iteratively improved. |
Checks
waf-sus-050.tf.aws.s3-lifecycle-required
Engine: terraform | Provider: aws | Automated: Yes
S3 buckets must have lifecycle configuration
Every S3 bucket must have an associated aws_s3_bucket_lifecycle_configuration resource with at least one transition and expiration rule. Buckets without lifecycle rules accumulate data indefinitely in the highest-energy storage tier.
Scope: resource โ aws_s3_bucket_lifecycle_configuration
Assertions:
* rule not empty โ S3 lifecycle configuration has no rules defined.
Remediation: Add lifecycle rules to all S3 buckets. Minimum recommended configuration: Transition to STANDARD_IA after 30 days, GLACIER after 90 days, expire after retention-policy-defined period. Enable S3 Intelligent-Tiering for unpredictable access pattern buckets as an alternative.
resource "aws_s3_bucket_lifecycle_configuration" "app_data" {
bucket = aws_s3_bucket.app_data.id
rule {
id = "data-lifecycle"
status = "Enabled"
transition {
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 90
storage_class = "GLACIER"
}
expiration {
days = 730 # 2 years โ adjust per data retention policy
}
}
rule {
id = "expire-incomplete-multipart"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 7
}
}
}
resource "aws_s3_bucket" "app_data" {
bucket = "acme-app-data"
# No lifecycle configuration โ WAF-SUS-050 Violation
}
waf-sus-050.tf.aws.ebs-no-orphan
Engine: terraform | Provider: aws | Automated: Yes
EBS volumes should be set to delete on instance termination
EBS volumes must have delete_on_termination = true unless there is a specific need for data persistence beyond instance lifetime. This prevents orphaned volumes from accumulating energy consumption after instances are terminated.
Scope: resource โ aws_instance
Assertions:
* root_block_device.delete_on_termination is true โ Root EBS volume should be set to delete on termination to prevent orphaned volumes.
Remediation: Set delete_on_termination = true on root_block_device for EC2 instances unless you have an explicit requirement to retain root volumes. For data volumes, use separate aws_ebs_volume resources with lifecycle management.
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu_arm.id
instance_type = "m7g.large"
root_block_device {
volume_size = 20
volume_type = "gp3"
delete_on_termination = true # prevent orphaned volumes
}
}
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = "m4.large"
root_block_device {
volume_size = 20
delete_on_termination = false # WAF-SUS-050 Warning: orphaned volume risk
}
}
waf-sus-050.tf.azurerm.blob-lifecycle
Engine: terraform | Provider: azurerm | Automated: Yes
Azure storage accounts should have blob lifecycle management policies
Azure Storage accounts must have lifecycle management policies to tier blobs to Cool and Archive tiers after appropriate activity thresholds. This reduces energy consumption in hot storage tiers.
Scope: resource โ azurerm_storage_management_policy
Assertions:
* rule not empty โ Azure storage management policy has no lifecycle rules.
Remediation: Add lifecycle management rules to Azure Storage accounts. Transition blobs to Cool tier after 30 days, Archive tier after 90 days. Configure delete rules based on data retention policy. Use azurerm_storage_management_policy resource.
resource "azurerm_storage_management_policy" "app_data" {
storage_account_id = azurerm_storage_account.app.id
rule {
name = "data-lifecycle"
enabled = true
filters {
blob_types = ["blockBlob"]
}
actions {
base_blob {
tier_to_cool_after_days_since_modification_greater_than = 30
tier_to_archive_after_days_since_modification_greater_than = 90
delete_after_days_since_modification_greater_than = 730
}
}
}
}
resource "azurerm_storage_account" "app" {
name = "acmeappstorage"
resource_group_name = var.resource_group_name
location = var.location
account_tier = "Standard"
account_replication_type = "LRS"
# No lifecycle policy โ WAF-SUS-050 Violation
}
waf-sus-050.tf.google.storage-lifecycle
Engine: terraform | Provider: google | Automated: Yes
GCS buckets must have lifecycle rules to transition or expire objects
Google Cloud Storage buckets must define lifecycle rules that transition objects to cheaper storage classes and expire stale objects to reduce storage emissions and cost.
Scope: resource โ google_storage_bucket
Assertions:
* lifecycle_rule not empty โ GCS bucket must have at least one lifecycle rule to manage object retention.
Remediation: Add lifecycle_rule blocks to google_storage_bucket with age-based transitions to NEARLINE, COLDLINE, ARCHIVE and expiration for old objects.
resource "google_storage_bucket" "data" {
name = "acme-data"
location = "EU"
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = 30
}
}
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 2555
}
}
}
resource "google_storage_bucket" "data" {
name = "acme-data"
location = "EU"
# No lifecycle rules configured
}
Evidence
| Kind | Required | Description |
|---|---|---|
|
Required |
Terraform configuration implementing the control. |
|
Required |
Policy, ADR, or standard documenting the requirement. |
|
Optional |
Cloud console or API output confirming runtime state. |
Related Controls
-
WAF-REL-050 == Regulatory Mapping
| Framework | Controls |
|---|---|
EU CSRD (Corporate Sustainability Reporting Directive) |
* ESRS E1 โ Climate Change โ resource efficiency in IT operations |
GDPR |
* Article 5(1)(e) โ Storage limitation principle * Article 25 โ Data protection by design and by default |
GHG Protocol |
* Scope 3 Category 11 โ reducing storage-related cloud emissions |
Green Software Foundation |
* Hardware Efficiency โ minimize data stored in high-energy tiers * Energy Efficiency โ data tiering and lifecycle management |