Back to Checks
aws

CloudTrail trail logs management events for read and write operations

cloudtrail_multi_region_enabled_logging_management_events
Service: cloudtrailSeverity: low
OfficialBuilt-inVerified
Categories:loggingforensics-ready
Resource Type:AwsCloudTrailTrail

CloudTrail trails record management events (read and write) in every AWS region and are actively logging, using a multi-region trail or per-region coverage.

Risk

Without region-wide management event logging, changes to identities, networking, and audit settings can go untracked.

Adversaries can operate in overlooked regions to create resources, modify permissions, or disable logging, undermining integrity, confidentiality, and incident response.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks cloudtrail_multi_region_enabled_logging_management_events

Recommendation

Enable a multi-region CloudTrail that logs management events for read and write in all regions.

Centralize logs in a separate, locked-down account; apply least privilege, encryption, retention, and integrity validation; and protect trails and storage with tamper-evident, deny-delete controls for defense-in-depth.

Remediation

Terraform

# Terraform: enable multi-region and log management events (read & write)
resource "aws_cloudtrail" "<example_resource_name>" {
  name           = "<example_resource_name>"
  s3_bucket_name = "<example_resource_name>"

  is_multi_region_trail = true  # CRITICAL: apply the trail to all regions

  event_selector {
    include_management_events = true  # CRITICAL: log management events
    read_write_type           = "All" # CRITICAL: log both read & write
  }
}

NativeIaC

# CloudFormation: enable multi-region and log management events (read & write)
Resources:
  <example_resource_name>:
    Type: AWS::CloudTrail::Trail
    Properties:
      S3BucketName: <example_resource_name>
      IsMultiRegionTrail: true  # CRITICAL: apply the trail to all regions
      EventSelectors:
        - IncludeManagementEvents: true  # CRITICAL: log management events
          ReadWriteType: All             # CRITICAL: log both read and write

Other

1In the AWS Console, go to CloudTrail > Trails and select your trail
2Click Edit
3Set Apply trail to all regions to Yes
4Under Management events, set Read/write events to All
5Click Save changes
6If Logging is Off, click Start logging

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.cloudtrail.cloudtrail_client import (
    cloudtrail_client,
)


class cloudtrail_multi_region_enabled_logging_management_events(Check):
    def execute(self):
        findings = []
        if cloudtrail_client.trails is not None:
            for region in cloudtrail_client.regional_clients.keys():
                report = Check_Report_AWS(
                    metadata=self.metadata(), resource=cloudtrail_client.trails
                )
                report.status = "FAIL"
                report.status_extended = "No CloudTrail trails enabled and logging management events were found."
                report.region = region
                report.resource_id = cloudtrail_client.audited_account
                report.resource_arn = cloudtrail_client._get_trail_arn_template(region)
                trail_is_logging_management_events = False
                for trail in cloudtrail_client.trails.values():
                    if trail.region == region or trail.is_multiregion:
                        if trail.is_logging:
                            for event in trail.data_events:
                                # Classic event selectors
                                if not event.is_advanced:
                                    # Check if trail has IncludeManagementEvents and ReadWriteType is All
                                    if (
                                        event.event_selector["ReadWriteType"] == "All"
                                        and event.event_selector[
                                            "IncludeManagementEvents"
                                        ]
                                    ):
                                        trail_is_logging_management_events = True

                                # Advanced event selectors
                                elif event.is_advanced:
                                    if event.event_selector.get(
                                        "Name"
                                    ) == "Management events selector" and all(
                                        [
                                            field["Field"] != "readOnly"
                                            for field in event.event_selector[
                                                "FieldSelectors"
                                            ]
                                        ]
                                    ):
                                        trail_is_logging_management_events = True
                    if trail_is_logging_management_events:
                        report = Check_Report_AWS(
                            metadata=self.metadata(), resource=trail
                        )
                        report.region = region
                        report.status = "PASS"
                        if trail.is_multiregion:
                            report.status_extended = f"Trail {trail.name} from home region {trail.home_region} is multi-region, is logging and have management events enabled."
                        else:
                            report.status_extended = f"Trail {trail.name} in region {trail.home_region} is logging and have management events enabled."
                        # Since there exists a logging trail in that region there is no point in checking the remaining trails
                        # Store the finding and exit the loop
                        findings.append(report)
                        break
                if report.status == "FAIL":
                    findings.append(report)
        return findings