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

What this check verifies

CloudWatch Logs for CloudTrail include a metric filter that matches unauthorized API errors ($.errorCode="*UnauthorizedOperation" or $.errorCode="AccessDenied*") and a linked alarm that triggers when events match the filter.

Risk

Without alerting on unauthorized API calls, permission probing and failed access by compromised identities can go unnoticed. Attackers can enumerate services, pivot, and attempt privilege escalation, threatening data confidentiality and integrity.

Recommendation

Enable real-time alerting by adding a CloudWatch Logs metric filter for unauthorized errors (*UnauthorizedOperation, AccessDenied*) and associating it with an alarm that notifies responders.
  • Enforce least privilege to reduce noise
  • Integrate with IR tooling for defense in depth

Remediation

# Terraform: Metric filter and alarm for unauthorized API calls
resource "aws_cloudwatch_log_metric_filter" "unauthorized" {
  name           = "unauthorized_api_calls_metric"
  log_group_name = "<example_resource_name>"
  pattern        = "{($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\")}"  # Critical: detects unauthorized/denied API calls

  metric_transformation {
    name      = "unauthorized_api_calls_metric"
    namespace = "CISBenchmark"
    value     = "1"
  }
}

resource "aws_cloudwatch_metric_alarm" "unauthorized" {
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  metric_name         = "unauthorized_api_calls_metric"   # Critical: alarm on the metric from the filter
  namespace           = "CISBenchmark"
  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_unauthorized_api_calls. 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