CloudTrail Logging Gaps: What You're Missing and Why Attackers Know It
CloudTrail's default configuration leaves critical blind spots — S3 object access, Lambda invocations, and RDS API calls go unlogged. Here's what to enable first and what it costs.
“We have CloudTrail enabled” is one of the most common responses in cloud security assessments — and one of the most misleading. Having CloudTrail enabled and having useful CloudTrail coverage are two very different things. The default configuration captures only management events, leaving a significant portion of attacker activity completely invisible. Sophisticated attackers know this, and they exploit it routinely.
What CloudTrail Logs by Default
CloudTrail’s default logging category is management events — also called the control plane. These are API calls that create, modify, or delete AWS resources: launching an EC2 instance, creating an IAM role, modifying a security group, deleting an S3 bucket. Management events tell you what your infrastructure looks like at any point in time.
Management event logging is valuable and should absolutely be enabled in all regions. But it captures the skeleton of your infrastructure, not what happens inside it. The gap is data events — API calls that operate on the data within resources rather than on the resources themselves. This distinction is the difference between knowing a safe exists and knowing who opened it and what they took.
The Four Critical Data Event Categories
S3 object-level logging captures GetObject, PutObject, DeleteObject, and related calls on individual S3 objects. Without this, you can see that an S3 bucket was created or its policy was changed, but you cannot see any of the reads or writes that occurred inside it. This is the single most important data event category to enable.
Lambda invocation logging captures every execution of a Lambda function. Without it, you can see that a Lambda function was created or its code was updated, but you cannot see when it ran, what triggered it, or what it did at runtime. A backdoor Lambda function installed by an attacker would be completely invisible in default CloudTrail.
DynamoDB item-level logging captures GetItem, PutItem, DeleteItem, and Query operations on DynamoDB tables. At high read/write volumes this can generate an enormous number of log entries, which is why it’s off by default — but for tables containing sensitive data (user records, financial data, healthcare information), the visibility is essential.
RDS Data API logging captures calls to the RDS Data API (rds-data:ExecuteStatement), used primarily with Aurora Serverless. RDS also has its own database-level audit logging separate from CloudTrail, which captures SQL queries — this is worth enabling independently of CloudTrail data events.
The Attacker’s Knowledge
This is not a secret. Security researchers have documented the CloudTrail data event gap extensively, and it appears in red team assessments so frequently that experienced attackers treat it as a baseline assumption. When planning a data exfiltration operation, an attacker who identifies that an AWS account has no S3 data events enabled knows they can drain any S3 bucket they have access to without generating a single CloudTrail entry.
Exfiltrating a 200GB S3 bucket of customer records in an account with only management event logging enabled will produce exactly zero CloudTrail log entries for the GetObject calls. The only evidence might be a spike in S3 data transfer metrics in CloudWatch — which most organizations don’t have alerts on — or an anomaly in GuardDuty’s S3 protection findings, which uses heuristics rather than complete event coverage.
S3 Server Access Logging as a Partial Alternative
S3 has its own logging mechanism separate from CloudTrail: server access logging. When enabled on a bucket, it writes access log records to a target bucket for every request made to the source bucket, including requests that CloudTrail data events would also capture. The format is different (Apache Combined Log Format rather than JSON), but the coverage of GetObject, PutObject, and DeleteObject is comparable.
Server access logs have two important limitations relative to CloudTrail data events. First, they don’t include the IAM principal identity in a structured, parseable way — the requester field contains an ARN but not the rich context (user type, session context, assumed-role chain) that CloudTrail provides. Second, there’s no SLA on delivery; logs can be delayed by several hours, making real-time alerting impractical. Use server access logging as a forensic backup, not a primary detection mechanism.
CloudTrail Lake vs S3 Destination
CloudTrail can deliver events to two destinations: an S3 bucket or CloudTrail Lake. The choice has real implications for cost and query capability.
S3 delivery is the traditional approach. Events arrive as gzipped JSON files in an S3 bucket, partitioned by account, region, and date. To query them, you need to set up Athena with an appropriate table definition and partition management. The storage cost is low (S3 standard), and you control retention through S3 lifecycle policies.
CloudTrail Lake is a managed event data store that lets you query CloudTrail events using SQL directly in the console or API, without setting up Athena. Query performance is faster and setup is simpler, but the cost model is different — you pay per GB of data scanned in queries, similar to Athena, plus storage costs that are higher than raw S3. CloudTrail Lake also has built-in retention options from 90 days to 7 years.
For most organizations, S3 + Athena is the more cost-effective path at scale, while CloudTrail Lake is valuable for teams that want immediate query capability without the Athena setup overhead.
The Cost of Comprehensive Data Event Logging
S3 data events at scale are expensive. If your applications make millions of S3 API calls per day — which is common for any production workload — enabling data events on all buckets can multiply your CloudTrail costs significantly. CloudTrail charges per 100,000 data events after the first copy of management events (which is free).
The solution is a targeted approach rather than all-or-nothing. Use S3 bucket tags to identify sensitive buckets — DataClassification: Confidential, DataClassification: PII, or similar — and enable CloudTrail data events only on those buckets initially. This gives you coverage where breaches matter most while controlling cost. Expand coverage incrementally as you understand the volume and cost implications.
Priority Order for What to Enable
Not everything can be enabled at once. Here’s a prioritized sequence based on breach impact:
- S3 data events on sensitive-tagged buckets. The highest-impact gap for most organizations. Define a sensitive bucket tag and configure a CloudTrail data event selector to match it.
- Lambda invocation events. Low volume relative to S3 in most environments, high signal value for detecting backdoor functions or unusual invocation patterns.
- Management events in all regions. Ensure your trail is truly multi-region, not just enabled in your primary region. Attackers create resources in less-monitored regions.
- CloudTrail Lake for query capability. Once you have the events flowing, invest in making them queryable. Incident response without fast querying is painful.
Detecting If CloudTrail Itself Has Been Disabled
A common attacker technique is to disable CloudTrail early in a breach to prevent further activity from being logged. The critical insight is that disabling a trail generates a cloudtrail:StopLogging management event before the trail stops recording. This means CloudTrail logs its own disabling in the management event stream.
Configure an EventBridge rule to fire on cloudtrail:StopLogging, cloudtrail:DeleteTrail, and cloudtrail:PutEventSelectors (which could be used to narrow logging scope). Route that rule to an SNS topic that sends an immediate alert via email and SMS. Because this is a management event, it works even in default CloudTrail configurations — the one logging gap that genuinely doesn’t apply here. If you receive that alert, you know an attacker has achieved enough privilege to attempt to cover their tracks, and the clock is running.
CloudDefender
Defend your cloud. Continuously.
CloudDefender Suite gives security teams continuous posture management, threat detection, and compliance automation across AWS, Azure, and GCP — with zero false-positive fatigue.
Try CloudDefender →