Check ID: cloudwatch_log_metric_filter_root_usage
Provider: AWS
Service: cloudwatch
Severity: MEDIUM
Categories: logging
Resource type: AwsCloudWatchAlarm

What this check verifies

CloudTrail logs in CloudWatch include a metric filter for root account activity ({ $.userIdentity.type = "Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != "AwsServiceEvent" }) and a linked CloudWatch alarm that triggers when the filter matches.

Risk

Without alerting on root activity, full-privilege actions can proceed unnoticed, impacting:
  • confidentiality via data access/exfiltration
  • integrity via policy/config tampering
  • availability via deletions or shutdowns Delayed detection increases blast radius and persistence.

Recommendation

Enable real-time alerts for root activity using a log metric filter and a high-priority alarm with notifications. Reduce exposure: enforce least privilege, keep root for break-glass with MFA, disable root access keys, and route alerts into incident response for defense in depth.

Remediation

# CloudWatch Logs metric filter for root account usage
resource "aws_cloudwatch_log_metric_filter" "<example_resource_name>" {
  name           = "<example_resource_name>"
  log_group_name = "<example_resource_name>"
  pattern        = "{ $.userIdentity.type = \"Root\" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != \"AwsServiceEvent\" }" # CRITICAL: detects root user actions

  metric_transformation {
    name      = "<example_resource_name>"     # CRITICAL: metric used by the alarm
    namespace = "<example_resource_name>"
    value     = "1"
  }
}

# Alarm on the root usage metric
resource "aws_cloudwatch_metric_alarm" "<example_resource_name>" {
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  metric_name         = "<example_resource_name>"   # CRITICAL: matches metric filter
  namespace           = "<example_resource_name>"
  period              = 300
  statistic           = "Sum"
  threshold           = 1
}

References

Where this check fires

This check runs on every scheduled scan against your AWS account. Findings appear at Cloud Security → Findings filterable by Check ID = cloudwatch_log_metric_filter_root_usage. To re-evaluate after a fix, hit Run now on the account’s schedule under Cloud Security → Schedules — the next scan re-checks this control and marks the finding fixed or keeps it persistent.
← Back to AWS checks