Skip to main content

Lambda Function Invoke API CloudTrail Logging

Overview

This check verifies that AWS Lambda function invocations (the Invoke API) are being recorded by CloudTrail as data events. By default, CloudTrail only logs management events (like creating or deleting functions). To capture who invoked a function, when, and from where, you must explicitly enable Lambda data event logging on a trail.

Risk

Without Lambda Invoke data events logged:

  • Attackers can run code undetected - adversaries can invoke Lambda functions without leaving audit trails
  • No accountability - you cannot determine who called a function, when, or from what source
  • Incident response is blind - investigating unauthorized function execution becomes impossible
  • Compliance gaps - many security frameworks require logging of compute execution events

This impacts both confidentiality (covert data access) and integrity (covert code execution).

Remediation Steps

Prerequisites

  • AWS account access with permission to modify CloudTrail settings
  • An existing CloudTrail trail (or permission to create one)
Creating a trail if you do not have one

If you do not have an existing CloudTrail trail, create one first:

  1. Go to CloudTrail in the AWS Console
  2. Click Create trail
  3. Enter a trail name (e.g., management-events-trail)
  4. Choose or create an S3 bucket for log storage
  5. Optionally enable CloudWatch Logs integration
  6. Click Next, review settings, and Create trail

CLI method:

aws cloudtrail create-trail \
--name management-events-trail \
--s3-bucket-name <YOUR_LOG_BUCKET_NAME> \
--is-multi-region-trail \
--region us-east-1

aws cloudtrail start-logging \
--name management-events-trail \
--region us-east-1

AWS Console Method

  1. Sign in to the AWS Management Console
  2. Navigate to CloudTrail
  3. In the left navigation, click Trails
  4. Click on the trail name you want to configure
  5. Scroll down to the Data events section and click Edit
  6. Under Data event type, select Lambda
  7. For Log selector template, choose one of:
    • Log all events - captures invocations for all Lambda functions (recommended)
    • Custom - to select specific functions only
  8. Click Save changes

Your trail will now capture Lambda Invoke events. It may take a few minutes for logging to begin.

AWS CLI (optional)

Enable Lambda data event logging using advanced event selectors:

Log all Lambda function invocations:

aws cloudtrail put-event-selectors \
--trail-name <YOUR_TRAIL_NAME> \
--advanced-event-selectors '[
{
"Name": "Log all Lambda data events",
"FieldSelectors": [
{"Field": "eventCategory", "Equals": ["Data"]},
{"Field": "resources.type", "Equals": ["AWS::Lambda::Function"]}
]
}
]' \
--region us-east-1

Log invocations for a specific function only:

aws cloudtrail put-event-selectors \
--trail-name <YOUR_TRAIL_NAME> \
--advanced-event-selectors '[
{
"Name": "Log specific Lambda function",
"FieldSelectors": [
{"Field": "eventCategory", "Equals": ["Data"]},
{"Field": "resources.type", "Equals": ["AWS::Lambda::Function"]},
{"Field": "resources.ARN", "Equals": ["arn:aws:lambda:us-east-1:<ACCOUNT_ID>:function:<FUNCTION_NAME>"]}
]
}
]' \
--region us-east-1

Using basic event selectors (alternative):

aws cloudtrail put-event-selectors \
--trail-name <YOUR_TRAIL_NAME> \
--event-selectors '[
{
"ReadWriteType": "All",
"IncludeManagementEvents": true,
"DataResources": [
{
"Type": "AWS::Lambda::Function",
"Values": ["arn:aws:lambda"]
}
]
}
]' \
--region us-east-1

To list your existing trails:

aws cloudtrail describe-trails --region us-east-1

To view current event selectors on a trail:

aws cloudtrail get-event-selectors --trail-name <YOUR_TRAIL_NAME> --region us-east-1
CloudFormation (optional)

This template creates a CloudTrail trail with Lambda data event logging enabled:

AWSTemplateFormatVersion: '2010-09-09'
Description: CloudTrail trail with Lambda Invoke data event logging

Parameters:
TrailName:
Type: String
Default: lambda-data-events-trail
Description: Name for the CloudTrail trail
LogBucketName:
Type: String
Description: S3 bucket name for CloudTrail logs

Resources:
CloudTrailTrail:
Type: AWS::CloudTrail::Trail
Properties:
TrailName: !Ref TrailName
S3BucketName: !Ref LogBucketName
IsMultiRegionTrail: true
IsLogging: true
IncludeGlobalServiceEvents: true
EnableLogFileValidation: true
AdvancedEventSelectors:
- Name: Log all Lambda data events
FieldSelectors:
- Field: eventCategory
Equals:
- Data
- Field: resources.type
Equals:
- AWS::Lambda::Function

Outputs:
TrailArn:
Description: ARN of the CloudTrail trail
Value: !GetAtt CloudTrailTrail.Arn

To add Lambda data events to an existing trail, add the AdvancedEventSelectors or EventSelectors property to your existing AWS::CloudTrail::Trail resource:

  ExistingTrail:
Type: AWS::CloudTrail::Trail
Properties:
TrailName: my-existing-trail
S3BucketName: my-log-bucket
IsLogging: true
# Add this section to enable Lambda data events
EventSelectors:
- ReadWriteType: All
IncludeManagementEvents: true
DataResources:
- Type: AWS::Lambda::Function
Values:
- arn:aws:lambda

Deploy the template:

aws cloudformation deploy \
--template-file lambda-cloudtrail-logging.yaml \
--stack-name lambda-cloudtrail-logging \
--parameter-overrides \
TrailName=lambda-data-events-trail \
LogBucketName=<YOUR_LOG_BUCKET_NAME> \
--region us-east-1
Terraform (optional)

Create a CloudTrail trail with Lambda data event logging:

resource "aws_cloudtrail" "lambda_data_events" {
name = "lambda-data-events-trail"
s3_bucket_name = var.log_bucket_name
include_global_service_events = true
is_multi_region_trail = true
enable_log_file_validation = true

advanced_event_selector {
name = "Log all Lambda data events"

field_selector {
field = "eventCategory"
equals = ["Data"]
}

field_selector {
field = "resources.type"
equals = ["AWS::Lambda::Function"]
}
}
}

variable "log_bucket_name" {
description = "S3 bucket name for CloudTrail logs"
type = string
}

To add Lambda data events to an existing trail, add the advanced_event_selector or event_selector block:

resource "aws_cloudtrail" "main" {
name = "main-trail"
s3_bucket_name = var.log_bucket_name
# ... other existing configuration ...

# Add this block for Lambda data events
event_selector {
read_write_type = "All"
include_management_events = true

data_resource {
type = "AWS::Lambda::Function"
values = ["arn:aws:lambda"]
}
}
}

For specific functions only:

resource "aws_cloudtrail" "specific_lambda" {
name = "specific-lambda-trail"
s3_bucket_name = var.log_bucket_name

advanced_event_selector {
name = "Log specific Lambda functions"

field_selector {
field = "eventCategory"
equals = ["Data"]
}

field_selector {
field = "resources.type"
equals = ["AWS::Lambda::Function"]
}

field_selector {
field = "resources.ARN"
equals = [
"arn:aws:lambda:us-east-1:123456789012:function:my-function-1",
"arn:aws:lambda:us-east-1:123456789012:function:my-function-2"
]
}
}
}

Verification

After enabling Lambda data event logging, verify the configuration:

  1. Go to CloudTrail > Trails and select your trail
  2. Scroll to Data events and confirm Lambda is listed as a data event source
  3. Invoke a Lambda function (manually or through your application)
  4. After a few minutes, check CloudTrail > Event history
  5. Filter by Event name = Invoke to see Lambda invocation events
CLI verification commands

Check the current event selectors on your trail:

aws cloudtrail get-event-selectors \
--trail-name <YOUR_TRAIL_NAME> \
--region us-east-1

Look for Lambda data resources in the output:

{
"AdvancedEventSelectors": [
{
"Name": "Log all Lambda data events",
"FieldSelectors": [
{
"Field": "eventCategory",
"Equals": ["Data"]
},
{
"Field": "resources.type",
"Equals": ["AWS::Lambda::Function"]
}
]
}
]
}

Or with basic event selectors:

{
"EventSelectors": [
{
"ReadWriteType": "All",
"IncludeManagementEvents": true,
"DataResources": [
{
"Type": "AWS::Lambda::Function",
"Values": ["arn:aws:lambda"]
}
]
}
]
}

After invoking a function, search for Invoke events:

aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=Invoke \
--region us-east-1 \
--max-results 10

Additional Resources

Notes

  • Cost considerations: Data events are charged separately from management events. At high volumes, Lambda invocation logging can generate significant costs. Consider logging only critical functions if cost is a concern.
  • First copy free: The first copy of management events is free per region. Data events are always charged.
  • Log volume: High-throughput Lambda functions can generate substantial log data. Use S3 lifecycle policies and CloudWatch Logs retention settings to manage storage costs.
  • Multi-region trails: For comprehensive coverage, use a multi-region trail to capture Lambda invocations across all regions.
  • Event delay: CloudTrail events typically appear within 15 minutes of the API call, though it can take longer during high-volume periods.
  • Sensitive data: Lambda Invoke events include the function name, request ID, and caller identity. Request/response payloads are not logged by CloudTrail.
  • Selective logging: If you have many functions but only need to audit a few, use advanced event selectors with specific function ARNs to reduce costs and noise.