AWS CloudTrail records every API call made within an AWS account — from console clicks to SDK invocations to internal service-to-service calls. It is the primary forensic, audit, and compliance log for AWS, and the source-of-truth for answering "who did what, when, from where" across your cloud footprint.
S3:GetObject, Lambda:Invoke, and DynamoDB item-level reads/writes. Off by default — extra cost, very high volume.RunInstances).CreateAccessKey for the compromised user, from which IP, when?UpdateStack, PutBucketPolicy, or ModifySecurityGroup.GetObject calls turn into a five-figure monthly bill. Scope data event selectors to only the buckets and prefixes you actually need to audit.
aws cloudtrail create-trail \
--name org-audit-trail \
--s3-bucket-name central-audit-logs-111122223333 \
--is-multi-region-trail \
--is-organization-trail \
--enable-log-file-validation \
--kms-key-id arn:aws:kms:us-west-2:111122223333:key/abcd-ef01
aws cloudtrail start-logging --name org-audit-trail
# Add S3 data events for one sensitive bucket only
aws cloudtrail put-event-selectors \
--trail-name org-audit-trail \
--advanced-event-selectors '[{
"Name": "Sensitive S3 reads",
"FieldSelectors": [
{"Field": "eventCategory", "Equals": ["Data"]},
{"Field": "resources.type", "Equals": ["AWS::S3::Object"]},
{"Field": "resources.ARN", "StartsWith": ["arn:aws:s3:::pii-vault/"]}
]
}]'
SELECT eventTime, userIdentity.arn, sourceIPAddress, eventName
FROM ABCD-1234-EVENT-DATA-STORE-ID
WHERE eventName = 'ConsoleLogin'
AND responseElements.ConsoleLogin = 'Failure'
AND eventTime > '2026-04-18T00:00:00Z'
ORDER BY eventTime DESC
LIMIT 100;
Management events are control-plane (create, modify, delete) and free for the first copy. Data events are data-plane reads/writes on resources like S3 objects and Lambda invokes — disabled by default because the volume and cost are large. Most production accounts log all management events globally and only data events on sensitive resources.
Enable log file integrity validation, send logs to a write-once S3 bucket in a dedicated audit account with object lock and MFA delete, and restrict bucket policy to only the CloudTrail service principal. SCPs prevent member-account admins from disabling the org trail.
Lake is faster to set up (no Glue catalog, partitions, or schema), supports up to 10 years retention with built-in queries, and bills per GB ingested + scanned. S3 + Athena is cheaper at very high event volumes if you already have a lake architecture. Pick Lake unless you have an existing data lake pipeline.
Typically within 5 minutes of the API call, with a documented SLA of up to 15 minutes for delivery to S3. Real-time alerting requires routing through EventBridge instead of waiting for log files.
A trail created in the AWS Organizations management account that automatically applies to every member account, present and future. Member accounts cannot disable it. This is the standard control for ensuring no account in the org operates without audit logging.
CloudTrail records AWS API calls (who did what to AWS resources). CloudWatch Logs collects application and OS logs (what the workloads themselves printed). They overlap when CloudTrail is configured to also stream events into a CloudWatch Logs group for alarming.
CloudTrail is the non-negotiable audit foundation. Configure an organization-wide multi-region trail with log file validation on day one, restrict who can disable it via SCP, and add data events surgically where the data sensitivity justifies the cost.