Back to Checks
aws

Lambda function Invoke API calls are recorded by CloudTrail

awslambda_function_invoke_api_operations_cloudtrail_logging_enabled
Service: awslambdaSeverity: low
OfficialBuilt-inVerified
Categories:logging
Resource Type:AwsLambdaFunction

AWS Lambda function invocations are recorded as CloudTrail data events when trails include AWS::Lambda::Function resources.

The finding reflects whether a function's Invoke activity is being logged by an eligible trail.

Risk

Without Lambda Invoke data events, per-invocation accountability is lost. Adversaries or misused automation can run code without an audit trail, obscuring actor, time, and source. This hinders forensics and enables covert exfiltration or unauthorized changes, impacting confidentiality and integrity.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks awslambda_function_invoke_api_operations_cloudtrail_logging_enabled

Recommendation

Enable CloudTrail data event logging for AWS::Lambda::Function to capture Invoke calls across required Regions and accounts. Apply least privilege selectors to scope events, centralize logs with strong retention, and integrate alerts for anomalous invokes as part of defense in depth.

Remediation

CLI

aws cloudtrail put-event-selectors --trail-name <example_resource_name> --advanced-event-selectors '[{"FieldSelectors":[{"Field":"eventCategory","Equals":["Data"]},{"Field":"resources.type","Equals":["AWS::Lambda::Function"]}]}]'

Terraform

resource "aws_cloudtrail" "<example_resource_name>" {
  name           = "<example_resource_name>"
  s3_bucket_name = "<example_resource_name>"

  event_selector {
    data_resource {
      type   = "AWS::Lambda::Function"  # Critical: enable Lambda data events
      values = ["arn:aws:lambda:<REGION>:<ACCOUNT_ID>:function"]  # Critical: capture Invoke for all functions in this account/region
    }
  }
}

NativeIaC

Resources:
  <example_resource_name>:
    Type: AWS::CloudTrail::Trail
    Properties:
      S3BucketName: <example_resource_name>
      IsLogging: true
      EventSelectors:
        - DataResources:
            - Type: AWS::Lambda::Function  # Critical: enables Lambda data event logging
              Values:
                - arn:aws:lambda:<REGION>:<ACCOUNT_ID>:function  # Critical: logs Invoke events for all functions in the specified account/region

Other

1In the AWS Console, go to CloudTrail > Trails
2Select your trail and click Edit or Event logging
3Under Data events, choose Add data event selector (or Edit)
4Select Lambda function and choose to log data events for all functions (or specify functions)
5Save changes

Check Code

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


class awslambda_function_invoke_api_operations_cloudtrail_logging_enabled(Check):
    def execute(self):
        findings = []
        for function in awslambda_client.functions.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=function)

            report.status = "FAIL"
            report.status_extended = (
                f"Lambda function {function.name} is not recorded by CloudTrail."
            )
            lambda_recorded_cloudtrail = False
            if cloudtrail_client.trails:
                for trail in cloudtrail_client.trails.values():
                    for data_event in trail.data_events:
                        # classic event selectors
                        if not data_event.is_advanced:
                            if "DataResources" in data_event.event_selector:
                                for resource in data_event.event_selector[
                                    "DataResources"
                                ]:
                                    if resource["Type"] == "AWS::Lambda::Function" and (
                                        function.arn in resource["Values"]
                                        or f"arn:{awslambda_client.audited_partition}:lambda"
                                        in resource["Values"]
                                    ):
                                        lambda_recorded_cloudtrail = True
                                        break
                        elif data_event.is_advanced:
                            for field_selector in data_event.event_selector[
                                "FieldSelectors"
                            ]:
                                if (
                                    field_selector["Field"] == "resources.type"
                                    and "AWS::Lambda::Function"
                                    in field_selector["Equals"]
                                ):
                                    lambda_recorded_cloudtrail = True
                                    break
                        if lambda_recorded_cloudtrail:
                            break
                    if lambda_recorded_cloudtrail:
                        report.status = "PASS"
                        report.status_extended = f"Lambda function {function.name} is recorded by CloudTrail trail {trail.name}."
                        break
            findings.append(report)

        return findings