Missing alarm for IAM policy changes

Without a CloudWatch log filter and alarm for IAM policy changes, permission changes can be discovered late.

Description

Without a log filter and CloudWatch alarm for IAM policy creation, deletion, attachment and modification, permission changes can go unnoticed for longer. Permission policy changes are important events that can be associated with security incidents.

Storing CloudTrail logs alone does not notify the responsible team. Monitor the required policy changes and connect notifications to an operational channel.

Potential impact

  • IAM permission changes can be discovered late.
  • Excessive grants or unexpected policy changes can be missed.
  • Incident response and investigation can be delayed.

Remediation

  • Deliver CloudTrail events to CloudWatch Logs and configure a log metric filter for important IAM policy changes.
  • Connect the emitted metric name and namespace to an alarm, and configure its evaluation period, threshold and SNS delivery path.
  • Check that the required policy change events are covered, then test actual notifications with events that satisfy the alarm conditions. Notifications do not prevent the policy changes themselves.

Examples

These excerpts show the filter and metric connection. Complete the required alarm evaluation periods, statistic and period, threshold and notification actions separately. CloudTrail log delivery and SNS subscriptions are also required. The filter name equals the emitted metric name here, so the filter's id is used as the metric name.

Before

hcl
resource "aws_cloudwatch_metric_alarm" "example" {
  alarm_name          = "CIS-4.4-IAM-Policy-Change"
  metric_name         = "XXXX NOT YOUR FILTER XXXX"
  namespace           = "CIS_Metric_Alarm_Namespace"
  comparison_operator = "GreaterThanOrEqualToThreshold"
}

After

hcl
resource "aws_cloudwatch_log_metric_filter" "example" {
  name           = "CIS-4.4-IAM-Policy-Change"
  pattern        = "{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}"
  log_group_name = aws_cloudwatch_log_group.CIS_CloudWatch_LogsGroup.name

  metric_transformation {
    name      = "CIS-4.4-IAM-Policy-Change"
    namespace = "CIS_Metric_Alarm_Namespace"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "example" {
  alarm_name          = "CIS-4.4-IAM-Policy-Change"
  metric_name         = aws_cloudwatch_log_metric_filter.example.id
  namespace           = "CIS_Metric_Alarm_Namespace"
  comparison_operator = "GreaterThanOrEqualToThreshold"
}

Explanation:

  • Before: The alarm's metric name is not connected to the policy change filter's metric.
  • After: Selected policy change events produce a metric that is connected to the alarm. Complete the omitted alarm settings and delivery path, then verify operation.

References