Inline IAM policy does not allow 'cloudtrail:*' privileges
IAM inline policies are evaluated for statements that grant full CloudTrail permissions (cloudtrail:*) to all resources.
The finding flags identity policies that provide unrestricted control over CloudTrail operations.
Risk
Full CloudTrail access allows stopping trails, modifying configurations, or deleting audit data, compromising log integrity and availability. It also exposes event data, impacting confidentiality. Adversaries could hide activity, evade detection, and obstruct investigations.
Run this check with Prowler
Run in Prowler Cloudprowler aws --checks iam_inline_policy_no_full_access_to_cloudtrailRecommendation
Enforce least privilege and separation of duties: avoid cloudtrail:*; grant only specific actions needed (prefer read-only where possible). Add guardrails or boundaries to block destructive actions. Use managed, centrally governed policies and periodically right-size permissions based on usage.
Remediation
Terraform
resource "aws_iam_role_policy" "<example_resource_name>" {
name = "<example_resource_name>-policy"
role = "<example_resource_name>"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["cloudtrail:DescribeTrails"] # Critical: replace 'cloudtrail:*' with specific action(s) to remove full service access
Resource = "*"
}]
})
}NativeIaC
# CloudFormation: restrict CloudTrail permissions in inline policy
Resources:
<example_resource_name>InlinePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: <example_resource_name>-policy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- cloudtrail:DescribeTrails # Critical: use specific action(s) instead of 'cloudtrail:*' to avoid full service access
Resource: "*"
Roles:
- <example_resource_name>Other
Check Code
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.iam.iam_client import iam_client
from prowler.providers.aws.services.iam.lib.policy import check_full_service_access
critical_service = "cloudtrail"
class iam_inline_policy_no_full_access_to_cloudtrail(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for policy in iam_client.policies.values():
# Check only inline policies
if policy.type == "Inline":
report = Check_Report_AWS(metadata=self.metadata(), resource=policy)
report.region = iam_client.region
report.resource_id = f"{policy.entity}/{policy.name}"
report.status = "PASS"
resource_type_str = report.resource_arn.split(":")[-1].split("/")[0]
resource_attached = report.resource_arn.split("/")[-1]
report.status_extended = f"{policy.type} policy {policy.name}{' attached to ' + resource_type_str + ' ' + resource_attached if policy.attached else ''} does not allow '{critical_service}:*' privileges."
if policy.document and check_full_service_access(
critical_service, policy.document
):
report.status = "FAIL"
report.status_extended = f"{policy.type} policy {policy.name}{' attached to ' + resource_type_str + ' ' + resource_attached if policy.attached else ''} allows '{critical_service}:*' privileges to all resources."
findings.append(report)
return findings