AWS CloudTrail Events Integration
Kloudfuse ingests AWS CloudTrail events by routing them through CloudWatch Logs and then to a Kinesis Firehose delivery stream. This gives you a searchable record of every API call made in your AWS account alongside your metrics and application logs.
Overview
AWS CloudTrail records every API call made in your AWS account — including the AWS Console, CLI, SDKs, and other AWS services. Examples of events captured include: EC2 instance launches, IAM policy changes, S3 object deletions, Lambda invocations, and login activity.
Common use cases for CloudTrail in Kloudfuse:
-
Security monitoring — detect unusual API patterns, unauthorized access attempts, or privilege escalation.
-
Compliance reporting — produce an audit trail showing who changed what, and when.
-
Incident investigation — correlate infrastructure changes with service disruptions using Kloudfuse’s unified log and metrics view.
-
Change tracking — track configuration changes to AWS resources over time.
Data flows as follows:
-
CloudTrail records API events and sends them to an S3 bucket (default) and optionally to a CloudWatch Logs log group.
-
A Kinesis Firehose subscription filter on the CloudWatch log group forwards records to Kloudfuse.
| CloudTrail management events (API calls to AWS services) are captured automatically once a trail is enabled. Data events (for example, S3 object-level operations or Lambda invocations) require separate configuration and incur additional cost. |
Prerequisites
Before you begin, ensure the following requirements are in place:
| Requirement | Details |
|---|---|
Kinesis Firehose delivery stream |
A Kinesis Firehose delivery stream named |
S3 bucket |
An S3 bucket to receive CloudTrail event archives. |
AWS CLI |
AWS CLI configured with permissions to manage CloudTrail trails, CloudWatch Logs, and IAM. |
Step 1: Create a CloudTrail Trail
If you do not already have a trail configured, create one. A trail must be configured to deliver events to a CloudWatch Logs log group to forward them to Kloudfuse.
First, create an S3 bucket for CloudTrail (if needed):
aws s3api create-bucket \
--bucket my-cloudtrail-bucket \
--region us-west-2 \
--create-bucket-configuration LocationConstraint=us-west-2
Apply a bucket policy that allows CloudTrail to write to it:
cat > cloudtrail-bucket-policy.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSCloudTrailAclCheck",
"Effect": "Allow",
"Principal": {"Service": "cloudtrail.amazonaws.com"},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::my-cloudtrail-bucket"
},
{
"Sid": "AWSCloudTrailWrite",
"Effect": "Allow",
"Principal": {"Service": "cloudtrail.amazonaws.com"},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-cloudtrail-bucket/AWSLogs/*",
"Condition": {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}}
}
]
}
EOF
aws s3api put-bucket-policy \
--bucket my-cloudtrail-bucket \
--policy file://cloudtrail-bucket-policy.json
Create the trail:
aws cloudtrail create-trail \
--name kloudfuse-trail \
--s3-bucket-name my-cloudtrail-bucket \
--include-global-service-events \
--is-multi-region-trail
aws cloudtrail start-logging \
--name kloudfuse-trail
Step 1a: Enable Data Events (Optional)
By default, CloudTrail captures only management events. Data events (S3 object-level operations, Lambda invocations, DynamoDB item operations, and others) must be explicitly enabled per trail and are billed separately.
See CloudTrail Data Event Enablement for enablement instructions for each supported service.
Step 2: Send CloudTrail Events to CloudWatch Logs
Create the IAM role that allows CloudTrail to write to CloudWatch Logs:
cat > cloudtrail-cw-trust.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "cloudtrail.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}
EOF
aws iam create-role \
--role-name CloudTrailToCloudWatchRole \
--assume-role-policy-document file://cloudtrail-cw-trust.json
aws iam put-role-policy \
--role-name CloudTrailToCloudWatchRole \
--policy-name CloudTrailLogsPolicy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:*:*:log-group:*"
}]
}'
Create the CloudWatch log group and configure the trail to use it:
aws logs create-log-group --log-group-name /aws/cloudtrail/kloudfuse
ROLE_ARN=$(aws iam get-role \
--role-name CloudTrailToCloudWatchRole \
--query 'Role.Arn' \
--output text)
LOG_GROUP_ARN=$(aws logs describe-log-groups \
--log-group-name-prefix /aws/cloudtrail/kloudfuse \
--query 'logGroups[0].arn' \
--output text)
aws cloudtrail update-trail \
--name kloudfuse-trail \
--cloud-watch-logs-log-group-arn "$LOG_GROUP_ARN" \
--cloud-watch-logs-role-arn "$ROLE_ARN"
Step 3: Subscribe to Kinesis Firehose
Subscribe the CloudTrail log group to the kloudfuse-logs Firehose delivery stream:
aws logs put-subscription-filter \
--log-group-name /aws/cloudtrail/kloudfuse \
--filter-name kloudfuse \
--filter-pattern "" \
--destination-arn "arn:aws:firehose:<region>:<account-id>:deliverystream/kloudfuse-logs" \
--role-arn "arn:aws:iam::<account-id>:role/KloudfuseFirehoseRole"
Step 4: Verify the Integration
Confirm Events are being Sent
-
Confirm the trail is actively logging:
aws cloudtrail get-trail-status \ --name kloudfuse-trail \ --query '{IsLogging: IsLogging, LatestDeliveryTime: LatestDeliveryTime}'bashIsLoggingmust betrue.LatestDeliveryTimeshould be recent (within the last few minutes). -
Confirm the CloudWatch log group subscription filter points to the correct Firehose stream:
aws logs describe-subscription-filters \ --log-group-name /aws/cloudtrail/kloudfuse \ --query 'subscriptionFilters[*].{Filter:filterName,Destination:destinationArn}'bashThe
destinationArnmust reference thekloudfuse-logsdelivery stream. -
In the AWS Console, open Amazon Kinesis and select the
kloudfuse-logsdelivery stream. -
Click the Monitoring tab and check the
IncomingRecordsand DeliveryToHTTPEndpoint.Success graphs. Both should show non-zero values within a few minutes of making an API call in your account. -
If DeliveryToHTTPEndpoint.Success is zero, check the DeliveryToHTTPEndpoint.DataFreshness metric for errors and verify the Kloudfuse ingester endpoint URL and API key in the Firehose HTTP endpoint configuration.
Confirm Events are Arriving in Kloudfuse
-
Make an API call in your AWS account (for example, run any
awsCLI command) to generate a fresh event. -
In the Kloudfuse UI, click the Logs tab and select Search from the drop-down.
-
Set the time picker to the last 15 minutes.
-
In the search bar, click Advanced Search and enter the following FuseQL query to confirm events are flowing:
eventSource="cloudtrail.amazonaws.com" or eventVersion="1.08"fuseqlAny result confirms that CloudTrail JSON records are reaching Kloudfuse.
-
To narrow the results to a specific AWS service, filter by
eventSource. For example, to view IAM activity:eventSource="iam.amazonaws.com" | count by eventNamefuseql -
To find console sign-in events:
eventName="ConsoleLogin"fuseql -
To find events from a specific IAM user or role:
eventSource="iam.amazonaws.com" and userIdentity.type="IAMUser"fuseql
References
-
CloudTrail Data Event Enablement — Enablement instructions for CloudTrail data events (S3, Lambda, DynamoDB, AppSync, Cognito, Bedrock, SNS, and others).
-
Enrichment IAM Permissions — IAM policy documents required for the Kloudfuse enrichment scraper and associated AWS integrations.
-
AWS Kinesis Firehose Integration — Kinesis Firehose delivery stream setup, which this integration depends on for log forwarding.
-
AWS CloudWatch Logs Integration — CloudWatch Logs integration, which shares the same Kinesis Firehose pipeline used here.
Fields and Label Enrichment
CloudTrail events do not require a separate enrichment step.
Unlike CloudWatch metrics (which carry only sparse dimensions such as InstanceId) or application logs (which carry no AWS context at all), every CloudTrail event is self-describing JSON that already includes the metadata you would otherwise need to attach externally:
| Field | What it contains |
|---|---|
|
Who made the call — IAM user, assumed role, federated identity, AWS service, or root account, including the ARN and account ID |
|
IP address or AWS service name that originated the request |
|
Region where the action was performed |
|
AWS service that processed the request (for example, |
|
Specific API operation (for example, |
|
ARNs and resource types of every AWS resource affected by the call |
|
Full parameters submitted with the API call |
|
Response returned by the service, where applicable |
You can filter and aggregate directly on these fields in Kloudfuse without any scraper configuration. For example, to count API calls by actor across all services:
eventSource="cloudtrail.amazonaws.com" | count by userIdentity.arn, eventSource
To find all actions taken on a specific resource by ARN:
resources.ARN="arn:aws:s3:::my-bucket" | count by eventName