Back to Checks
alibabacloud

ActionTrail is configured to export copies of all log entries across all regions

actiontrail_multi_region_enabled
Service: actiontrailSeverity: critical
OfficialBuilt-inVerified
Categories:logging
Resource Type:ALIYUN::ACTIONTRAIL::Trail

Alibaba Cloud ActionTrail records API calls made to your account, including caller identity, time, source IP, request parameters, and response elements. Ensuring a multi-region trail exists guarantees that operations across all regions and global services are captured, enabling detection of unexpected activities in unused regions.

Prowler logoProwlerprowler-provider-alibabacloud

Risk

Without a multi-region trail enabled, API calls made in regions outside the primary trail's scope will not be recorded. This creates blind spots in security analysis, resource change tracking, and compliance auditing, potentially allowing unauthorized or malicious activity to go undetected across your Alibaba Cloud account.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler alibabacloud --checks actiontrail_multi_region_enabled

Recommendation

Enable a multi-region trail in ActionTrail to ensure all API calls across all regions are recorded and delivered to a centralized OSS bucket and SLS project for security analysis and compliance auditing.

Remediation

CLI

aliyun actiontrail CreateTrail --Name <trail_name> --OssBucketName <oss_bucket_for_actiontrail> --RoleName aliyunactiontraildefaultrole --SlsProjectArn <sls_project_arn_for_actiontrail> --SlsWriteRoleArn <sls_role_arn_for_actiontrail> --EventRW <api_type_for_actiontrail>

Terraform

resource "alicloud_actiontrail_trail" "example" {
  trail_name         = "multi-region-trail"
  trail_region       = "All"
  sls_project_arn    = "acs:log:cn-hangzhou:123456789:project/actiontrail-project"
  sls_write_role_arn = data.alicloud_ram_roles.actiontrail.roles.0.arn
}

Other

1Log on to the **ActionTrail Console**
2Click on **Trails** in the left navigation pane
3Click **Add new trail**
4Enter a trail name in the `Trail name` box
5Set **Yes** for `Apply Trail to All Regions`
6Specify an OSS bucket name in the `OSS bucket` box
7Specify an SLS project name in the `SLS project` box
8Click **Create**

Check Code

from prowler.lib.check.models import Check, CheckReportAlibabaCloud
from prowler.providers.alibabacloud.services.actiontrail.actiontrail_client import (
    actiontrail_client,
)


class actiontrail_multi_region_enabled(Check):
    """Check if ActionTrail is configured to export copies of all log entries."""

    def execute(self) -> list[CheckReportAlibabaCloud]:
        findings = []

        # Check if there's at least one multi-region trail that is enabled
        multi_region_trails = []
        for trail in actiontrail_client.trails.values():
            if trail.trail_region == "All" and trail.status == "Enable":
                multi_region_trails.append(trail)

        # Create a single report for the overall check
        report = CheckReportAlibabaCloud(metadata=self.metadata(), resource={})
        report.region = actiontrail_client.region
        report.resource_id = actiontrail_client.audited_account
        report.resource_arn = (
            f"acs:actiontrail::{actiontrail_client.audited_account}:trail"
        )

        if multi_region_trails:
            # At least one multi-region trail is enabled
            trail_names = [trail.name for trail in multi_region_trails]
            report.status = "PASS"
            report.status_extended = (
                f"ActionTrail is configured with {len(multi_region_trails)} multi-region trail(s) "
                f"that are enabled: {', '.join(trail_names)}. "
                "These trails export copies of all log entries across all regions."
            )
        else:
            # Check if there are any trails at all
            if actiontrail_client.trails:
                # There are trails but none are multi-region or enabled
                enabled_trails = [
                    t
                    for t in actiontrail_client.trails.values()
                    if t.status == "Enable"
                ]
                multi_region_trails_disabled = [
                    t
                    for t in actiontrail_client.trails.values()
                    if t.trail_region == "All" and t.status != "Enable"
                ]

                if enabled_trails and not multi_region_trails_disabled:
                    report.status = "FAIL"
                    report.status_extended = (
                        f"ActionTrail has {len(enabled_trails)} enabled trail(s), but none are configured "
                        "for multi-region logging (TrailRegion is not set to 'All'). "
                        "Multi-region trails are required to capture events from all regions."
                    )
                elif multi_region_trails_disabled:
                    trail_names = [t.name for t in multi_region_trails_disabled]
                    report.status = "FAIL"
                    report.status_extended = (
                        f"ActionTrail has multi-region trail(s) but they are disabled: {', '.join(trail_names)}. "
                        "Enable the multi-region trail(s) to export copies of all log entries."
                    )
                else:
                    report.status = "FAIL"
                    report.status_extended = (
                        "ActionTrail has trails configured, but none are enabled or configured for multi-region logging. "
                        "At least one trail with TrailRegion set to 'All' and Status set to 'Enable' is required."
                    )
            else:
                # No trails configured at all
                report.status = "FAIL"
                report.status_extended = (
                    "ActionTrail is not configured. No trails exist. "
                    "Create at least one multi-region trail (TrailRegion='All') and enable it "
                    "to export copies of all log entries across all regions."
                )

        findings.append(report)
        return findings