AWS Builder Center

Who Changed This? Investigating AWS Resource Changes with CloudTrail

When something breaks or gets exposed in AWS, the first question is always the same: who changed it, and when? CloudTrail has the answer, but only if you know where to look. This article walks through a practical, repeatable approach.

Who Changed This? Investigating AWS Resource Changes with CloudTrail

When something breaks or gets exposed in AWS, the first question is always the same: who changed it, and when? CloudTrail has the answer, but only if you know where to look. This article walks through a practical, repeatable approach.

What CloudTrail records

CloudTrail logs API activity in your account. Each event tells you:
  • Who: the IAM user, role, or service (userIdentity)
  • What: the API call (eventName)
  • When: eventTime
  • Where from: sourceIPAddress and userAgent
  • Result: success, or an errorCode

Step 1: Start with Event History

Open CloudTrail → Event history. It keeps the last 90 days of management events and needs no setup.
  • Filter by Resource name (for example, your bucket or role name)
  • Or filter by Event name (for example, PutBucketPolicy)
  • Note that the console lets you filter by one attribute at a time
This is enough for quick checks, but it gets slow when you need to correlate several events.

Step 2: Go deeper with CloudTrail Lake or Athena

For longer retention and flexible searching, use CloudTrail Lake (or a trail delivering to S3, queried with Athena). Example query to see recent activity on one bucket:
sql
1
2
3
4
5
6
SELECT eventTime, userIdentity.arn, eventName,
sourceIPAddress, errorCode
FROM <event-data-store-id>
WHERE eventSource = 's3.amazonaws.com'
AND element_at(requestParameters, 'bucketName') = 'my-bucket'
ORDER BY eventTime DESC
Replace the event data store ID and bucket name with your own.

Step 3: Watch for high-risk events

These changes commonly increase exposure or reduce visibility:
  • PutBucketPolicy, PutBucketAcl, DeletePublicAccessBlock: S3 exposure
  • AuthorizeSecurityGroupIngress: new inbound rules (check for 0.0.0.0/0)
  • AttachRolePolicy, PutUserPolicy: permission changes
  • CreateAccessKey: new long-term credentials
  • StopLogging, DeleteTrail: someone disabling your audit trail

Step 4: Build the timeline

For the resource in question, line up events in order and answer:
  • Who made the first change, and was it expected?
  • Did the source IP or user agent look unusual?
  • Did a change come right after a login or role assumption from a new location?
  • Was there any failed attempt (AccessDenied) before the success?

Making it proactive

  • Send CloudTrail events to EventBridge and alert on the high-risk events above
  • Enable CloudTrail log file validation so logs can’t be silently altered
  • Use multi-region trails and an organization trail so no account or region is missed
  • Keep logs in a separate, locked-down account

What’s still hard

Today, finding every event for one resource means searching by name or writing queries yourself. A built-in resource-centric timeline, where you select a resource and see every change in order, would speed up incident response, especially for smaller teams. Until then, the Lake query approach above is the most flexible option.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article