Skip to main content

AWS CloudTrail

Records every API call made in your AWS account — console clicks, CLI commands, and SDK calls. Answers who did what, when, and from where. 90 days of history free, longer with an S3 Trail.

CloudTrail records every API call made in your AWS account — every console click, every CLI command, every SDK call, and every service-to-service call. It answers: who took this action, when, from where, and on which resource.

What Gets Logged

TEXT
Management Events (logged by default, free):
Operations performed on AWS resources
Examples: launching EC2, modifying a Security Group, creating an IAM user,
changing an S3 bucket policy, updating a Lambda function
Can separate Read events (describe, list, get) from Write events (create, delete, modify)
Data Events (NOT logged by default — must explicitly enable):
Object-level operations on resources
Examples: S3 GetObject, PutObject, DeleteObject (which files were read/written)
Lambda Invoke (which function was called and by whom)
DynamoDB GetItem, PutItem (which records were accessed)
These generate high volume and have additional cost
CloudTrail Insights Events:
ML-based anomaly detection on management events
Detects unusual API call spikes, unexpected resource provisioning bursts
Creates an Insights finding and an EventBridge event

90 Days vs Trail

TEXT
Default: 90 days of management event history stored and searchable for free
Trail: creates permanent storage by streaming events to an S3 bucket
Benefits: indefinite retention, query with Athena, cross-region, log validation
For compliance: always create a Trail. Always enable log file validation.
Log file validation: CloudTrail signs each log file. If someone deletes or modifies a file,
validation detects the tampering.

CloudTrail + EventBridge = Real-Time Response

Bash
Root user logs into the console
↓ CloudTrail records the event within seconds
↓ EventBridge rule matches: source=aws.signin, userIdentity.type=Root
↓ SNS sends email to security team immediately
EC2 instance terminated at 2 AM
↓ CloudTrail records ec2:TerminateInstances
↓ EventBridge detects it
↓ Lambda creates incident, records who terminated it and from what IP

Protecting Your Audit Logs

◈ DIAGRAM
Store CloudTrail logs in a dedicated S3 bucket in a separate security account
Enable S3 Object Lock (WORM) on the bucket — logs cannot be deleted or modified
Even if the main account is fully compromised → audit logs remain intact and trustworthy
Alert on CloudTrail being stopped:
EventBridge rule matching StopLogging or DeleteTrail → immediate SNS alert
(Attackers often disable CloudTrail as one of their first actions)

Querying CloudTrail with Athena

TEXT
Create an Athena table over your CloudTrail S3 bucket
Query months of API history with SQL:
SELECT eventTime, userIdentity.arn, sourceIPAddress, eventName
FROM cloudtrail_logs
WHERE eventName = 'DeleteSecurityGroup'
AND eventTime > '2024-01-15'
ORDER BY eventTime DESC LIMIT 100;
Remember

S3 object-level operations (GetObject, PutObject, DeleteObject) are Data Events and are NOT logged by default. If you need to know who accessed which files in a compliance-critical S3 bucket, you must explicitly enable Data Events for that bucket when creating the Trail. Many teams assume everything is logged — this gap is where breaches go undetected.

Frequently Asked Questions

What's the difference between CloudTrail and CloudWatch?

CloudTrail logs API activity — who called what AWS API, when, from which IP, and whether it succeeded. CloudWatch logs application and infrastructure behavior — metrics, logs your app writes, alarms. They're complementary: CloudTrail answers 'who deleted this S3 bucket,' CloudWatch answers 'why did this Lambda time out.' Security investigations and compliance audits rely on CloudTrail; performance debugging relies on CloudWatch.

What's a common mistake teams make with CloudTrail?

Relying on the default 90-day event history and assuming it's enough, then discovering during an incident investigation that the relevant activity happened four months ago and is gone. The fix is creating an S3 Trail early — before you need it — so events are durably stored indefinitely. Also enable log file validation and a separate, locked-down logging account so an attacker who compromises your account can't just delete the trail.