To audit Amazon S3 with AWS CloudTrail, create a trail that delivers events to an S3 log bucket, then choose which S3 object data events to record. CloudTrail records bucket configuration changes as management events, but object operations such as GetObject and PutObject are data events that you must select explicitly. Event history alone does not show S3 object activity.

This guide walks through a multi-Region trail, a narrowly scoped S3 data-event selector, the permissions CloudTrail needs to deliver logs, and ways to inspect and protect those records. For more on S3 identity and bucket-policy permissions, see our S3 access management guide.

Understand which S3 events CloudTrail records

CloudTrail groups events into categories. Management events describe control-plane operations, such as creating a bucket or changing its policy. Data events describe operations on resources, such as reading or writing an S3 object. Trails log management events by default; S3 data events are opt-in and incur additional charges. See the current AWS CloudTrail pricing before enabling high-volume selectors.

CloudTrail Event history is enabled by default and provides a searchable record of the past 90 days of management events in a Region. It does not show data events. Create a trail to deliver an ongoing record to S3, and select the S3 data events you need. See AWS's Event history limitations and S3 data-event logging guide.

For object-level auditing, common event names include GetObject, PutObject, and DeleteObject. Select read events, write events, or both based on the question you need to answer. CloudTrail records API context such as the event name, time, caller identity, and source IP; it is not a copy of the object's contents.

Create a trail and choose its S3 destination

A dedicated log bucket makes it easier to set separate access and retention controls. Create the bucket in the Region you choose for log storage, keep S3 Block Public Access enabled, and restrict who can read or change its contents. The CloudTrail console can create a bucket and attach the required delivery policy. If you use an existing bucket, add the CloudTrail statements shown in the next section.

  1. Open CloudTrail in the AWS Management Console and choose Create trail.
  2. Name the trail and choose a new or existing S3 bucket for log delivery. Keep log file validation enabled.
  3. Choose to log management events. A multi-Region trail covers enabled Regions in the account; the console creates multi-Region trails.
  4. Review the trail settings, create the trail, and confirm that logging is enabled.
  5. In the trail's event settings, configure S3 data events for the buckets, prefixes, and read/write operations you need.

A trail extends the record beyond Event history and can also send events to CloudWatch Logs. This setup stores the trail's log files in the S3 bucket you select. For current console and CLI options, see AWS's trail creation guide.

Limit data events to the objects you need

Logging every object operation across every bucket can create a large volume of events. Prefer selecting the sensitive buckets or prefixes and event names that support your audit or investigation needs. Advanced event selectors can filter by resource type, event name, read/write status, and resource ARN. If you update an existing trail with advanced selectors, include every event category it should continue to log: advanced selectors replace its basic selectors.

This AWS CLI example keeps management-event logging and adds S3 object events for one bucket. Replace the trail name, bucket, and Region with your values:

aws cloudtrail put-event-selectors \
  --trail-name s3-audit-trail \
  --region us-east-1 \
  --advanced-event-selectors '[
    {
      "Name": "All management events",
      "FieldSelectors": [
        { "Field": "eventCategory", "Equals": ["Management"] }
      ]
    },
    {
      "Name": "S3 object events for one bucket",
      "FieldSelectors": [
        { "Field": "eventCategory", "Equals": ["Data"] },
        { "Field": "resources.type", "Equals": ["AWS::S3::Object"] },
        { "Field": "resources.ARN", "StartsWith": ["arn:aws:s3:::example-sensitive-bucket/"] }
      ]
    }
  ]'

The example records both read and write data events for objects in the named bucket. Add an eventName selector or a narrower object-prefix ARN when you need a smaller scope. Advanced selectors do not support wildcard characters; use supported operators such as StartsWith. Keep the trail's destination bucket out of broad data-event selectors unless you intend to record CloudTrail's own delivery writes. AWS describes ways to avoid recursive logging in its data-event logging guidance. Check AWS's advanced selector reference before changing a production trail.

Scope the S3 delivery permissions

For an existing log bucket, allow the CloudTrail service principal to check the bucket ACL and write trail files only under the account's log prefix. Bind both statements to the trail ARN with aws:SourceArn. This example is for a single-account trail without a custom S3 prefix; organization trails and custom prefixes use different object paths.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudTrailAclCheck",
      "Effect": "Allow",
      "Principal": { "Service": "cloudtrail.amazonaws.com" },
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::my-cloudtrail-log-bucket",
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": "arn:aws:cloudtrail:us-east-1:123456789012:trail/s3-audit-trail"
        }
      }
    },
    {
      "Sid": "CloudTrailWrite",
      "Effect": "Allow",
      "Principal": { "Service": "cloudtrail.amazonaws.com" },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::my-cloudtrail-log-bucket/AWSLogs/123456789012/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control",
          "aws:SourceArn": "arn:aws:cloudtrail:us-east-1:123456789012:trail/s3-audit-trail"
        }
      }
    }
  ]
}

Replace the example bucket, account ID, Region, and trail name. Add any configured log prefix before AWSLogs/. Keep log-reader permissions separate: grant investigators only the S3 list/read access they need for the relevant account path, plus KMS decrypt access if the trail uses SSE-KMS. AWS documents the required statements and aws:SourceArn condition in its CloudTrail S3 bucket policy guide.

Choose CloudTrail, S3 server access logging, or both

CloudTrail and S3 server access logging answer related but different questions:

  • CloudTrail records selected S3 API activity with AWS event context. Management events cover bucket and configuration operations; S3 object data events must be enabled on a trail or event data store.
  • S3 server access logs provide detailed records of requests made to a bucket, including request and response details useful for traffic analysis and troubleshooting. Delivery is best effort, so completeness and timing are not guaranteed.

Use CloudTrail when you need an account-level audit trail and caller context. Consider S3 server access logging when request-level fields are useful. Some teams enable both. AWS's Amazon S3 logging options page compares their coverage and delivery behavior.

Inspect and query S3 events

CloudTrail log files are compressed JSON objects delivered to the selected bucket. An event record includes fields such as eventTime, eventSource, eventName, userIdentity, and sourceIPAddress; see AWS's CloudTrail event record reference. Use Event history to look up recent management events. To examine S3 data events, inspect the delivered files or create an Athena table over the CloudTrail log prefix.

After you create a table named cloudtrail_logs for the trail, this Athena query lists recent object operations. Athena's table name and column names must match your table definition:

SELECT eventtime,
       eventname,
       useridentity.arn AS principal,
       sourceipaddress
FROM cloudtrail_logs
WHERE eventsource = 's3.amazonaws.com'
  AND eventname IN ('GetObject', 'PutObject', 'DeleteObject')
ORDER BY eventtime DESC
LIMIT 100;

Athena queries the files in S3 and has separate query charges. See AWS's guide to querying CloudTrail logs with Athena. AWS Config can complement this event history by recording supported resource configuration state; see our AWS Config resource inventory and change tracking guide for that distinction.

Protect and retain the log files

  • Restrict access. Keep the log bucket private and limit write, read, and policy-change permissions. Consider storing security logs in a separate account if your organization uses a centralized log archive.
  • Set retention deliberately. Choose an S3 Lifecycle policy that matches your audit and investigation requirements. Validate retention obligations before expiring or transitioning log objects.
  • Choose encryption to meet your policy. CloudTrail log files use SSE-S3 unless you configure SSE-KMS. With SSE-KMS, use a key in the log bucket's Region and allow CloudTrail to encrypt and authorized readers to decrypt. See AWS's CloudTrail KMS encryption guidance.
  • Enable log file integrity validation. CloudTrail delivers digest files that can be checked against delivered logs; enabling validation does not run the check for you. To verify a period, use the AWS CLI while the log and digest files remain in their original S3 locations:
aws cloudtrail validate-logs \
  --trail-arn arn:aws:cloudtrail:us-east-1:123456789012:trail/s3-audit-trail \
  --start-time 2026-09-01T00:00:00Z \
  --end-time 2026-10-01T00:00:00Z \
  --region us-east-1

Replace the trail ARN and dates with your own. Validation checks whether delivered log files and digest files have changed or are missing; it does not prove that your selectors captured every event you intended. See AWS's integrity validation overview and validate-logs requirements.

Verify the setup

  1. Confirm that the trail shows logging enabled and successful recent S3 delivery.
  2. Perform an approved test object read or write in a selected bucket, then check the delivered event after CloudTrail processes it.
  3. Check that an event in an unselected bucket or prefix is absent if your selector excludes it.
  4. Run log file validation for the delivered period if integrity validation is enabled.

CloudTrail log delivery is not an immediate alerting channel. If you need prompt detection, build a separate alerting path from supported CloudTrail events and validate its coverage against your selectors.

FAQs

Does CloudTrail log S3 object access by default?

No. Trails log management events by default, but S3 object operations are data events. Add S3 data-event selectors for the buckets, prefixes, and read/write activity you need.

Is CloudTrail Event history enough for S3 auditing?

Event history is useful for recent management-event lookups, but it covers only the past 90 days in a Region and does not show data events. Use a trail for ongoing S3 log delivery and explicitly configure data events for object-level activity.

Should I also enable S3 server access logging?

It depends on the evidence you need. CloudTrail provides selected API events and identity context; server access logging provides detailed request records with best-effort delivery. Compare their fields and coverage before relying on either for a particular audit question.