CloudWatch alarm missing for S3 bucket policy changes

Monitor changes to S3 bucket access and data management settings.

Description

Changes to bucket policies, ACLs, CORS, lifecycle rules, and replication can affect data access or management. Configure notifications for the relevant CloudTrail events to identify unintended changes.

Potential impact

Without change notifications, unintended access permissions or data management settings may remain unnoticed.

Remediation

Create a log metric filter for the S3 configuration changes you need to monitor. Connect an alarm to the filter’s metric name and namespace, and configure notification recipients.

Examples

The examples narrow the filter to S3 events and connect the alarm to its metric. Configure log delivery and notification recipients separately.

Before

hcl
resource "aws_cloudwatch_log_metric_filter" "example" {
  name           = "CIS-S3BucketPolicyChanges"
  pattern        = "{ ($.eventSource = \"s3.amazonaws.com\") || (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }"
  log_group_name = aws_cloudwatch_log_group.CIS_CloudWatch_LogsGroup.name

  metric_transformation {
    name      = "CIS-S3BucketPolicyChanges"
    namespace = "CIS_Metric_Alarm_Namespace"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "example" {
  alarm_name          = "CIS-3.8-S3BucketPolicyChanges"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = "1"
  metric_name         = "XXX NOT YOUR FILTER"
  namespace           = "CIS_Metric_Alarm_Namespace"
  period              = "300"
  statistic           = "Sum"
  threshold           = "1"
}

After

hcl
resource "aws_cloudwatch_log_metric_filter" "example" {
  name           = "CIS-S3BucketPolicyChanges"
  pattern        = "{ ($.eventSource = \"s3.amazonaws.com\") && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }"
  log_group_name = aws_cloudwatch_log_group.CIS_CloudWatch_LogsGroup.name

  metric_transformation {
    name      = "CIS-S3BucketPolicyChanges"
    namespace = "CIS_Metric_Alarm_Namespace"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "example" {
  alarm_name          = "CIS-3.8-S3BucketPolicyChanges"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = "1"
  metric_name         = aws_cloudwatch_log_metric_filter.example.id
  namespace           = "CIS_Metric_Alarm_Namespace"
  period              = "300"
  statistic           = "Sum"
  threshold           = "1"
}

References