Back to Checks
CloudTrail trail has delivered logs to CloudWatch Logs in the last 24 hours
cloudtrail_cloudwatch_logging_enabled
Service: cloudtrailSeverity: low
OfficialBuilt-inVerified
Categories:loggingforensics-ready
Resource Type:AwsCloudTrailTrail
CloudTrail trails are configured to send events to CloudWatch Logs, and show recent delivery within the last 24h. Trails without integration or without recent CloudWatch delivery are identified, across single-Region and multi-Region trails.
Risk
Missing or stale CloudWatch delivery weakens visibility and delays detection, impacting confidentiality and integrity. Adversaries can:
- Hide privilege escalation
- Perform unauthorized resource changes
- Exfiltrate data via API misuse
Run this check with Prowler
Run in Prowler CloudRun
prowler aws --checks cloudtrail_cloudwatch_logging_enabledRecommendation
Integrate every trail with CloudWatch Logs and maintain continuous, near-real-time delivery. Enforce least privilege on the delivery role, prefer multi-Region coverage, and implement metric filters and alerts for sensitive actions. Centralize retention to support defense in depth.
Remediation
CLI
aws cloudtrail update-trail --name <trail_name> --cloud-watch-logs-log-group-arn <cloudwatch_log_group_arn> --cloud-watch-logs-role-arn <cloudwatch_logs_role_arn>Terraform
# Terraform: enable CloudTrail delivery to CloudWatch Logs
resource "aws_cloudtrail" "<example_resource_name>" {
name = "<example_resource_name>"
s3_bucket_name = "<example_resource_name>"
cloud_watch_logs_group_arn = "<cloudwatch_log_group_arn>" # CRITICAL: sends CloudTrail events to CloudWatch Logs
cloud_watch_logs_role_arn = "<cloudwatch_logs_role_arn>" # CRITICAL: role CloudTrail assumes to deliver events
}NativeIaC
# CloudFormation: enable CloudTrail delivery to CloudWatch Logs
Resources:
<example_resource_name>:
Type: AWS::CloudTrail::Trail
Properties:
S3BucketName: "<example_resource_name>"
CloudWatchLogsLogGroupArn: "<cloudwatch_log_group_arn>" # CRITICAL: sends CloudTrail events to CloudWatch Logs
CloudWatchLogsRoleArn: "<cloudwatch_logs_role_arn>" # CRITICAL: role CloudTrail assumes to deliver eventsOther
1In AWS Console, go to CloudTrail > Trails and select the trail
2In the CloudWatch Logs section, click Edit
3Set CloudWatch Logs to Enabled
4Choose an existing Log group (or create new) and select an IAM role with permissions for CreateLogStream/PutLogEvents
5Click Save changes
6After a few minutes, verify events appear in the chosen CloudWatch Logs log group
Check Code
from datetime import datetime, timedelta, timezone
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
cloudtrail_client,
)
maximum_time_without_logging = 1
class cloudtrail_cloudwatch_logging_enabled(Check):
def execute(self):
findings = []
if cloudtrail_client.trails is not None:
for trail in cloudtrail_client.trails.values():
if trail.name:
report = Check_Report_AWS(metadata=self.metadata(), resource=trail)
report.region = trail.home_region
report.status = "PASS"
if trail.is_multiregion:
report.status_extended = f"Multiregion trail {trail.name} has been logging in the last 24h."
else:
report.status_extended = f"Single region trail {trail.name} has been logging in the last 24h."
if trail.latest_cloudwatch_delivery_time:
last_log_delivery = (
datetime.now().replace(tzinfo=timezone.utc)
- trail.latest_cloudwatch_delivery_time
)
if last_log_delivery > timedelta(
days=maximum_time_without_logging
):
report.status = "FAIL"
if trail.is_multiregion:
report.status_extended = f"Multiregion trail {trail.name} has not been logging in the last 24h."
else:
report.status_extended = f"Single region trail {trail.name} has not been logging in the last 24h."
else:
report.status = "FAIL"
if trail.is_multiregion:
report.status_extended = f"Multiregion trail {trail.name} has not been logging in the last 24h or is not configured to deliver logs."
else:
report.status_extended = f"Single region trail {trail.name} has not been logging in the last 24h or is not configured to deliver logs."
findings.append(report)
return findings