Date
November 30, 2025
Author
Karan Patel
,
CEO

If your organization runs workloads on AWS, CloudTrail is one of the most important sources of truth you have for detecting attacks, investigating incidents, and maintaining compliance. Yet many security teams treat it as a checkbox rather than an active detection layer. This post breaks down how CloudTrail actually works, what the logs contain, which events matter most from a threat detection standpoint, and how to query and alert on them effectively.

What Is AWS CloudTrail and Why Does It Matter for Security?

AWS CloudTrail is a managed service that records API calls made to your AWS account. Every time a user, role, or service interacts with AWS, whether through the console, CLI, SDK, or another service, that action generates an API call. CloudTrail captures those calls as log events and delivers them to an S3 bucket, CloudWatch Logs, or both.

From a security perspective, this gives you a near-complete audit trail of who did what, when, from where, and using which credentials. That scope makes CloudTrail the backbone of cloud-native detection engineering. Without it, you are effectively blind to identity-based attacks, privilege escalation, data exfiltration through AWS APIs, and configuration tampering.

CloudTrail captures three categories of events: Management Events (control plane actions like creating or deleting resources), Data Events (data plane actions like S3 object reads or Lambda invocations), and CloudTrail Insights Events (anomaly detection around unusual API call volumes). By default, only management events are logged. Enabling data events costs more, but for high-value buckets or functions, that visibility is non-negotiable.

If you are building detection capabilities around AWS and want structured, hands-on training, the AWS Pentesting Course at Redfox Cybersecurity Academy teaches you how attackers abuse these exact APIs so defenders know precisely what to look for.

Anatomy of a CloudTrail Log Event

Before writing detections, you need to understand what a raw CloudTrail event looks like. Every event is a JSON object. Here is a representative example of a suspicious AssumeRole event:

{
 "eventVersion": "1.08",
 "userIdentity": {
   "type": "IAMUser",
   "principalId": "AIDAEXAMPLEID",
   "arn": "arn:aws:iam::123456789012:user/attacker",
   "accountId": "123456789012",
   "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
   "userName": "attacker"
 },
 "eventTime": "2024-11-14T03:22:11Z",
 "eventSource": "sts.amazonaws.com",
 "eventName": "AssumeRole",
 "awsRegion": "us-east-1",
 "sourceIPAddress": "198.51.100.27",
 "userAgent": "aws-cli/2.13.0",
 "requestParameters": {
   "roleArn": "arn:aws:iam::123456789012:role/AdminRole",
   "roleSessionName": "session123"
 },
 "responseElements": {
   "credentials": {
     "accessKeyId": "ASIAIOSFODNN7EXAMPLE",
     "expiration": "2024-11-14T07:22:11Z"
   }
 },
 "eventID": "abc12345-def6-7890-ghij-klmnopqrstuv",
 "readOnly": false,
 "errorCode": null,
 "errorMessage": null
}

[cta]

The fields security teams should internalize are userIdentity, eventName, sourceIPAddress, errorCode, requestParameters, and responseElements. The errorCode field is particularly valuable because a flood of AccessDenied errors from a single principal is a reliable signal of reconnaissance or failed privilege escalation.

Key Fields and What They Reveal

userIdentity.type tells you whether the caller was an IAM user, assumed role, federated user, AWS service, or the root account. Root account activity outside of a known billing or account setup context should trigger an immediate alert.

sourceIPAddress can help you identify unexpected geographic origins or calls from infrastructure you do not own. When combined with threat intelligence feeds, this field becomes a fast path to detecting compromised credentials being used from attacker-controlled hosts.

userAgent reveals the tool used to make the call. Unusual agents like Boto3 appearing from a principal that normally uses the console, or custom strings associated with cloud attack tooling such as Pacu, are worth correlating.

Setting Up CloudTrail Properly for Security Visibility

A misconfigured CloudTrail is nearly as bad as no CloudTrail. Here is the baseline configuration every security team should enforce.

Enabling a Multi-Region Trail with Log File Validation

aws cloudtrail create-trail \
 --name security-audit-trail \
 --s3-bucket-name your-cloudtrail-bucket \
 --is-multi-region-trail \
 --enable-log-file-validation \
 --include-global-service-events \
 --cloud-watch-logs-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:CloudTrail/SecurityLogs:* \
 --cloud-watch-logs-role-arn arn:aws:iam::123456789012:role/CloudTrail-CWLogs-Role

[cta]

--is-multi-region-trail ensures that API calls in every region are captured, not just your primary deployment region. Attackers frequently pivot to unused regions precisely because teams forget to enable logging there. --enable-log-file-validation creates SHA-256 hash digests that let you verify the logs have not been tampered with after delivery, which matters for incident response and legal hold situations.

Enabling S3 Data Events for High-Value Buckets

aws cloudtrail put-event-selectors \
 --trail-name security-audit-trail \
 --event-selectors '[
   {
     "ReadWriteType": "All",
     "IncludeManagementEvents": true,
     "DataResources": [
       {
         "Type": "AWS::S3::Object",
         "Values": ["arn:aws:s3:::sensitive-data-bucket/"]
       }
     ]
   }
 ]'

[cta]

Without this, an attacker who gains access to valid credentials and exfiltrates objects from S3 will leave no trace in your CloudTrail logs at all.

High-Signal CloudTrail Events Every Security Team Should Monitor

Not all CloudTrail events are equally interesting. The following categories represent the highest-signal events from an attacker behavior perspective, mapped to real attack techniques.

Identity and Credential-Based Detections

  • Root account usage: Any ConsoleLogin or API call where userIdentity.type is Root outside of documented maintenance windows.
  • New access key creation: CreateAccessKey events, especially when the key is created for a user other than the caller, are a common persistence technique after initial access.
  • IAM policy modifications: PutUserPolicy, AttachRolePolicy, CreatePolicyVersion, and SetDefaultPolicyVersion events can indicate privilege escalation attempts.
  • Console login without MFA: CloudTrail logs whether MFA was used during a ConsoleLogin event. A login without MFA from an account that should have it enabled is worth flagging.

Reconnaissance-Oriented Events

When an attacker gains initial access to credentials, they typically run enumeration commands before escalating. These generate characteristic patterns in CloudTrail.

Common reconnaissance API calls include ListBuckets, DescribeInstances, ListRoles, ListUsers, GetAccountAuthorizationDetails, ListAttachedRolePolicies, and GetCallerIdentity. A burst of these calls across multiple services within a short window, especially when originating from an unfamiliar IP, is a strong signal of active reconnaissance.

The tool Pacu, an open-source AWS exploitation framework, generates exactly this kind of multi-service enumeration pattern. Understanding attacker tooling helps you tune detections to catch real campaigns rather than noise.

Understanding how attackers chain these enumeration techniques into privilege escalation and lateral movement is covered in depth in the Redfox Cybersecurity Academy AWS Pentesting Course, which is worth reviewing even from a purely defensive perspective.

Persistence and Privilege Escalation Events

  • Creating new IAM users: CreateUser followed by CreateAccessKey on the same new user, especially outside business hours.
  • Adding users to groups: AddUserToGroup targeting groups with administrative policies attached.
  • Backdoor Lambda functions: UpdateFunctionCode or AddPermission on Lambda functions can indicate an attacker inserting a reverse shell or data exfiltration payload into an existing trusted function.
  • CloudTrail disruption: StopLogging, DeleteTrail, and UpdateTrail are critical events that should trigger a P1 alert in any environment. An attacker who knows what they are doing will attempt to blind your logging before executing destructive or exfiltration actions.

Querying CloudTrail Logs with Athena

CloudTrail logs delivered to S3 are stored in compressed JSON format partitioned by account, region, and date. Amazon Athena lets you query them directly using standard SQL. This is the fastest path to investigative queries during an incident.

Creating the Athena Table

CREATE EXTERNAL TABLE cloudtrail_logs (
   eventVersion STRING,
   userIdentity STRUCT
       type: STRING,
       principalId: STRING,
       arn: STRING,
       accountId: STRING,
       userName: STRING,
       accessKeyId: STRING
   >,
   eventTime STRING,
   eventSource STRING,
   eventName STRING,
   awsRegion STRING,
   sourceIPAddress STRING,
   userAgent STRING,
   errorCode STRING,
   errorMessage STRING,
   requestParameters STRING,
   responseElements STRING,
   eventID STRING
)
ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://your-cloudtrail-bucket/AWSLogs/123456789012/CloudTrail/';

[cta]

Detecting Root Account Usage

SELECT
   eventTime,
   eventName,
   sourceIPAddress,
   userAgent,
   awsRegion
FROM cloudtrail_logs
WHERE userIdentity.type = 'Root'
 AND eventTime >= '2024-11-01T00:00:00Z'
ORDER BY eventTime DESC;

[cta]

Finding AccessDenied Storms Indicating Privilege Escalation Attempts

SELECT
   userIdentity.userName,
   userIdentity.arn,
   sourceIPAddress,
   COUNT(*) AS denied_count,
   MIN(eventTime) AS first_seen,
   MAX(eventTime) AS last_seen
FROM cloudtrail_logs
WHERE errorCode = 'AccessDenied'
 AND eventTime >= '2024-11-14T00:00:00Z'
GROUP BY
   userIdentity.userName,
   userIdentity.arn,
   sourceIPAddress
HAVING COUNT(*) > 20
ORDER BY denied_count DESC;

[cta]

Identifying CloudTrail Disruption Attempts

SELECT
   eventTime,
   eventName,
   userIdentity.arn,
   sourceIPAddress,
   awsRegion
FROM cloudtrail_logs
WHERE eventName IN ('StopLogging', 'DeleteTrail', 'UpdateTrail', 'PutEventSelectors')
ORDER BY eventTime DESC;

[cta]

These Athena queries are directly usable in incident response playbooks. For ongoing monitoring, you can schedule them using EventBridge or push matching events into your SIEM through CloudWatch Logs subscriptions.

Forwarding CloudTrail to a SIEM with CloudWatch and Kinesis

For real-time detection, you want CloudTrail events flowing into your SIEM or detection platform rather than waiting to run Athena queries. The standard pipeline is CloudTrail to CloudWatch Logs, then CloudWatch Logs to Kinesis Data Firehose, and from there to your destination, whether that is Splunk, Elastic, or another platform.

Creating a Metric Filter for Root Login Events

aws logs put-metric-filter \
 --log-group-name CloudTrail/SecurityLogs \
 --filter-name RootAccountUsage \
 --filter-pattern '{ $.userIdentity.type = "Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != "AwsServiceEvent" }' \
 --metric-transformations \
   metricName=RootAccountUsage,metricNamespace=CloudTrailMetrics,metricValue=1

[cta]

Setting an Alarm on That Metric

aws cloudwatch put-metric-alarm \
 --alarm-name "RootAccountLogin" \
 --alarm-description "Triggers on any root account API activity" \
 --metric-name RootAccountUsage \
 --namespace CloudTrailMetrics \
 --statistic Sum \
 --period 300 \
 --threshold 1 \
 --comparison-operator GreaterThanOrEqualToThreshold \
 --evaluation-periods 1 \
 --alarm-actions arn:aws:sns:us-east-1:123456789012:SecurityAlerts

[cta]

The SNS topic at the end of that chain can trigger Lambda for automated response, send notifications to your on-call system, or feed into a ticketing workflow. This is the foundation of a real-time detection pipeline built entirely on native AWS services.

Using CloudTrail Insights for Anomaly Detection

CloudTrail Insights analyzes your management event activity and establishes a baseline of normal API call volume per event type. When it detects a statistically significant deviation, it generates an Insights event with the baseline rate, the observed rate, and the duration of the anomaly.

To enable it on an existing trail:

aws cloudtrail put-insight-selectors \
 --trail-name security-audit-trail \
 --insight-selectors '[{"InsightType": "ApiCallRateInsight"}, {"InsightType": "ApiErrorRateInsight"}]'

[cta]

ApiErrorRateInsight is particularly useful for detecting credential stuffing or automated privilege escalation attempts that generate abnormal volumes of AccessDenied errors. While Insights is not a replacement for signature-based detections, it provides a useful catch-all for novel attack patterns that do not match known event sequences.

Protecting CloudTrail Logs from Tampering

An attacker who compromises a sufficiently privileged principal can delete your CloudTrail, modify its configuration, or delete the S3 objects containing the logs. Protecting against this is as important as the logging itself.

Apply an S3 bucket policy that denies deletion of objects even to the bucket owner, using S3 Object Lock in Compliance mode:

aws s3api put-object-lock-configuration \
 --bucket your-cloudtrail-bucket \
 --object-lock-configuration '{
   "ObjectLockEnabled": "Enabled",
   "Rule": {
     "DefaultRetention": {
       "Mode": "COMPLIANCE",
       "Days": 365
     }
   }
 }'

[cta]

In Compliance mode, no user, including the root account, can delete locked objects before the retention period expires. This protects your audit trail even in scenarios where an attacker achieves full account compromise.

Additionally, use AWS Config rules such as cloud-trail-enabled and cloud-trail-log-file-validation-enabled to continuously monitor for configuration drift and receive alerts if CloudTrail is ever disabled.

Key Takeaways

CloudTrail is the foundation of AWS threat detection, but its value is proportional to how well you configure, query, and alert on it. The highest-leverage actions are enabling multi-region trails with log file validation, turning on data events for sensitive resources, building Athena queries for investigative workflows, creating CloudWatch metric filters for critical event categories, and applying S3 Object Lock to prevent log tampering.

The events that matter most from an attacker perspective map closely to real attack techniques: credential abuse, reconnaissance API bursts, IAM policy manipulation, CloudTrail disruption, and anomalous data access. Knowing exactly which events attackers generate, and at what volume, is something you develop by studying the offensive side as carefully as the defensive one.

If you want to sharpen that attacker perspective to become a more effective defender, the AWS Pentesting Course from Redfox Cybersecurity Academy walks through how real attacks unfold across AWS services, giving you the context to build detections that actually catch threats rather than generating noise.

Copy Code