Investigate S3 Access and Drift
Trace S3 access and prove bucket drift with CloudTrail and AWS Config.
Introduction
30 Second Summary
Files stored online can be accessed in seconds, while the clue that proves who did it may live somewhere else. A security setting can also change before anyone records what it looked like.
In this project, you will build a compact Amazon S3 investigation lab using AWS CloudTrail, Amazon CloudWatch Logs Insights, and AWS Config. Your final case timeline will connect the actor's activity to the bucket's restored security state.
What You'll Build
Your finished lab turns a harmless bucket incident into a case timeline showing the responsible actor beside the restored security state.
By the end of this project, you'll have:
- A private evidence target where a harmless file produces object-level activity you can investigate.
- A CloudWatch Logs Insights result that groups PutObject, GetObject, and DeleteObject by event type across the selected Region.
- A configuration drift timeline that places CloudTrail actor evidence beside AWS Config before-and-after states.
- Secret Mission: Narrow the trail to record only GetObject plus DeleteObject while excluding PutObject.
Are there any prerequisites?
You need an AWS account with permission to manage Amazon S3, AWS CloudTrail, Amazon CloudWatch Logs, AWS Config, and AWS Identity and Access Management.
You also need a Linux device with one small non-sensitive file ready to upload.
Before We Start
An investigation falls apart when its starting conditions are vague. Fixing the lab parameters before any activity gives each later event a reliable baseline.
This preflight locks the lab to one AWS Region. It also confirms the identity you will use in the AWS Management Console.
You will choose one harmless file for controlled object activity. The case asks who accessed that object.
A second question tracks the S3 security setting that changed. A final question proves whether the bucket returned to a safe state.
In this step, get ready to:
- Confirm the AWS identity you will use for the investigation.
- Record one account ID plus one lab Region.
- Prepare the known file baseline for the case.
Confirm your AWS access
Your console identity determines which resources you can create or inspect. The role for this lab needs broad access across the evidence services.
- Sign in to the AWS Management Console on your Linux device.
- Check the upper-right account menu to confirm the expected role or user is active.
- Confirm with your AWS administrator that this identity can manage the required services described below.
What access does this lab need?
- Amazon S3 access covers the evidence bucket plus its harmless test object.
- AWS CloudTrail access covers trail creation plus event settings.
- CloudWatch Logs access covers the log group plus evidence queries.
- AWS Identity and Access Management access covers the delivery role used by the trail.
- AWS Config access covers the customer managed recorder plus configuration history.
Unsure About Your Access?
Use a sandbox account where your role is expected to manage each required service. Ask your AWS administrator to confirm the permission scope before creating lab resources.
Describe your current AWS identity to get help checking its expected permissions.
Fix the account and Region context
The account ID makes later resource names collision-resistant. One Region keeps the trail, log group, bucket activity, and configuration history aligned.
- Choose your account name or number in the upper-right navigation bar.
- Read the 12-digit value shown beside Account.
- Record the 12-digit value here: <account-id>.
- Choose the currently displayed Region name in the navigation bar.
- Choose one Region for the lab.
- Record the selected Region here: <region>.
Cannot Find the Account ID?
- Use the number beside Account when that entry appears in the account menu.
- Choose Security credentials when the account number is absent from the menu.
- Find the number beside AWS account ID under Account details.
- Help me locate my account ID without sharing credentials.
- Confirm the navigation bar still shows <region>.
That establishes your first evidence anchor. Every regional resource in this lab now has one consistent location.
Prepare the case baseline
An object key identifies an object inside a bucket. For this lab, the uploaded file name becomes the intended object key.
- Use your Linux desktop's application launcher to open its file manager.
- Locate one small non-sensitive file for the lab.
- Review the file contents to confirm they contain no credentials or personal data.
You should see harmless content that is safe to upload temporarily for controlled evidence generation.
- Record the local file name here: <harmless-file>.
- Record the same file name as the intended object key here: <object-key>.
- Define the investigation question as follows: who accessed the object, what S3 security setting changed, and whether the bucket was restored safely.
Before you check the baseline, do you expect every case detail to point to one concrete value? Hold that prediction while you review each field.
- Check that <account-id> contains exactly 12 digits.
- Check that the console navigation bar shows <region>.
- Check that <harmless-file> opens successfully on your Linux device.
- Check that <object-key> matches the local file name.
Your investigation now has a known account, location, source object, target key, and case objective. That baseline makes every later event easier to trust.
Your case parameters are fixed. Next, you will create the private S3 evidence target that generates the activity you investigate.
Set Up a Private Evidence Target
A forensic timeline is only trustworthy when you know exactly which resource generated each event. This lab therefore needs a controlled storage target with an expected access history.
In this step, you'll create a private Amazon S3 bucket for known evidence. You'll upload the harmless file before generating one controlled download.
In this step, get ready to:
- Confirm the selected account context.
- Create the private evidence bucket with the required protection settings.
- Generate a controlled object download from the harmless file.
Confirm the lab account and Region
The AWS Management Console context determines which account owns the bucket. It also controls which Region receives the lab resources.
- Check that the Region shown in the console header matches <region>.
- Open the account menu in the upper-right corner.
- Confirm the displayed 12-digit account ID matches <account-id>.
- Use the console search bar to open Amazon S3.
You should see the list of general purpose buckets for the selected account.
Create the private evidence bucket
The bucket is the controlled evidence target for every later investigation action. Its account-based name lowers the chance of colliding with another globally unique S3 bucket name.
Creating this bucket can incur usage-based S3 charges. This lab stores one small file to keep usage low.
- Choose General purpose buckets.
- Choose Create bucket.
- Enter nw-s3-dfir-data-<account-id> in the bucket name field.
- Set the bucket Region to <region>.
- Keep Bucket owner enforced selected.
- Keep all four Block Public Access protections enabled.
What do these settings do?
The four Block Public Access values remain enabled. This preserves the complete default public-access protection set.
Bucket owner enforced retains the default Object Ownership setting.
SSE-S3 supplies default encryption for new objects.
Versioning stays disabled so cleanup remains simple.
- Keep the default SSE-S3 encryption option.
- Keep versioning disabled.
- Choose Create bucket.
You should see nw-s3-dfir-data-<account-id> listed with Region <region>.
- Choose nw-s3-dfir-data-<account-id> from the bucket list.
- Choose the Permissions tab.
- Confirm the page shows all four bucket-level Block Public Access protections enabled.
Good. Your private evidence target now exists with the required public-access protections.
Bucket not created?
- Compare the bucket name with nw-s3-dfir-data-<account-id> if S3 reports that the name is unavailable.
- Recheck the 12-digit account ID if the generated name does not match the lab account.
- Confirm your signed-in role can create S3 buckets if the creation action is blocked.
- Help me diagnose why this S3 evidence bucket was not created.
Upload and download the evidence object
This object is your known test evidence. Uploading it gives every later event a specific key to reference.
S3 object data-event logging is not configured yet. This first download establishes the baseline access that the investigation must reconstruct.
- Choose the Objects tab.
- Choose Upload.
- Choose Add file.
- Select <harmless-file> from your Linux device.
- Confirm the queued file shows <object-key> as its intended object key.
- Choose Upload.
You should see a success message for the uploaded file.
- Use your browser's Back button to return to the bucket's Objects tab.
- Confirm <object-key> appears in the object list.
That gives the investigation a known object with a confirmed key.
Before you test the download, do you expect S3 to keep the original object after the browser saves a local copy?
- Refresh the Objects tab.
- Select the checkbox beside <object-key>.
- Choose Download above the object list.
- Check your browser's completed downloads list for the selected object.
Your Objects tab still lists <object-key>. Your browser's downloads list shows a completed local copy on the Linux device.
Object or download missing?
- Refresh the Objects tab if the upload succeeded but the key is not listed.
- Check your browser's completed downloads list if the local copy is difficult to find.
- Confirm <object-key> is selected before choosing Download again.
- Help me find my uploaded S3 object or downloaded copy.
Your private target now contains a known object with a controlled download behind it. Next, you'll test whether CloudTrail Event history can find that access.
Expose the Event History Blind Spot
Your private Amazon S3 bucket still contains <object-key>. You downloaded this object once to create a known access event.
AWS CloudTrail Event history looks like the obvious place to investigate that download. This step tests whether the view contains the object-level evidence you need.
In this step, get ready to:
- Search Event history for the known object download.
- Compare the object search with a visible bucket management event.
- Record the investigation limitation exposed by the comparison.
Search for the object read
The earlier download gives you a known event to search for. Finding it would let Event history prove who accessed the object.
- Use the search bar at the top of the console to switch from Amazon S3 to AWS CloudTrail.
- Choose Event history from the left navigation.
- Check that the Region shown in the console header is <region>.
- Set the recent time range to include the earlier object download.
Before you apply the filter, do you think Event history will show the download you performed?
- Set the lookup filter to Event name.
- Enter GetObject as the filter value.
You'll see no matching event for the known download. This is the intended blind spot.
Still seeing unrelated events?
- Confirm that GetObject uses the exact capitalization shown above.
- Remove any extra filters that could change the search.
- Help me check my Event history filter.
What did the empty result prove?
Management events describe changes to resources in the control plane. Event history contains these events from the selected Region.
Object operations such as GetObject occur in the data plane. Event history omits S3 object data events.
Prove Event history is working
A visible management event confirms that Event history is working in the chosen Region. The comparison isolates the limitation to object-level evidence.
Before you change the filter, do you expect the bucket creation event to appear?
- Replace GetObject with CreateBucket in the Event name filter.
You'll see the recent bucket creation management event in the results.
Cannot find CreateBucket?
- Widen the recent time range until it includes the bucket creation.
- Confirm that the console still shows <region>.
- Help me find the bucket creation event.
- Open the matching CreateBucket event.
- Read the event's UTC time.
- Identify the recorded identity.
- Confirm the recorded Region.
- Record that CloudTrail Event history shows management events but omits S3 object data events.
You now have a visible management event from the same Region. Its details expose the event time plus the recorded identity.
Your evidence now supports a precise limitation. Event history does not provide S3 object data-event evidence.
You have proved the blind spot with evidence from the same Region. The next step adds scoped data-event logging for the missing object activity.
Capture and Query S3 Data Events
Your CloudTrail Event history check proved that bucket-level management activity is visible while the object download remains missing. That evidence gap blocks you from proving who accessed the file.
This step adds explicit Amazon S3 data-event logging for the target bucket. A scoped trail sends that evidence to Amazon CloudWatch Logs Insights so you can query object writes, reads, and deletions.
In this step, get ready to:
- Create a multi-Region trail with management-event logging plus a new CloudWatch Logs destination.
- Scope an advanced event selector to objects in the target bucket.
- Generate controlled object activity and query the resulting evidence.
Create the investigation trail
A trail provides ongoing event delivery beyond Event history. Its S3 destination retains log files while its CloudWatch Logs destination gives you a faster investigation loop.
- Return to the CloudTrail console from the previous step.
- Choose Create trail.
The trail configuration form now gives you one place to define storage and query delivery.
- Enter nw-s3-dfir-trail in Trail name.
- Choose Create new S3 bucket under Storage location.
The generated bucket becomes the durable storage destination for the trail's log files.
- Turn off Log file SSE-KMS encryption so the new log bucket uses SSE-S3.
- Enable CloudWatch Logs.
CloudTrail now shows the settings for a log group and its delivery role.
- Choose New for the log group.
- Enter nw-s3-dfir-events as the log group name.
The new log group uses the default STANDARD class. Standard log groups automatically discover fields in CloudTrail JSON events.
- Choose New for the IAM delivery role.
- Accept the default CloudTrail role configuration.
Why CloudWatch Logs delivery?
CloudWatch Logs delivery provides a short path from event generation to an interactive query. CloudTrail Lake or S3 analysis with Amazon Athena requires more setup for this compact investigation.
- Choose Next.
- Leave Management events selected.
The event-type page now shows the controls that determine which bucket-level actions remain logged.
- Leave Read selected.
- Leave Write selected.
Both management-event categories remain enabled for later investigation steps.
- Choose Next.
- Review the summary for nw-s3-dfir-trail.
The summary should show the new S3 log bucket plus CloudWatch Logs delivery to nw-s3-dfir-events.
- Choose Create trail.
The trail details page should show nw-s3-dfir-trail as logging. CloudTrail trails created in the console are multi-Region trails.
That is the delivery backbone in place. Management events now flow to durable storage plus a query-ready log group.
Trail not appearing?
- Confirm that your console is still set to <region>.
- Check that your role can create CloudTrail trails, S3 buckets, CloudWatch log groups, and IAM roles.
- Return to the configuration form if CloudTrail reports that the delivery role or log group could not be created.
- Help me diagnose why my CloudTrail trail or CloudWatch Logs delivery was not created.
Scope the S3 data-event selector
An advanced event selector controls which data-plane operations the trail records. The selector will target objects in one bucket while preserving the trail's existing management-event coverage.
- Open the selector editor from the details page for nw-s3-dfir-trail.
- Confirm that Read management events remain enabled.
The selector editor still includes management reads for bucket-level investigation.
- Confirm that Write management events remain enabled.
- Add Data events.
A data-event selector now appears below the management-event settings.
- Select S3 as the resource type.
- Select Custom as the log selector template.
The custom template exposes the resource conditions that keep logging focused on the evidence bucket.
- Keep eventCategory set to Data.
- Keep resources.type set to AWS::S3::Object.
These conditions identify object-level S3 activity as the evidence category.
- Add the resources.ARN field.
- Set its operator to StartsWith.
The ARN prefix condition will include every object key below the target bucket.
- Enter arn:aws:s3:::nw-s3-dfir-data-<account-id>/ as the ARN prefix.
- Confirm that the selector has no readOnly condition.
The trailing slash places the selector at the bucket's object boundary. The missing read-only filter keeps both access directions in scope.
- Save the selector changes using the page's save control.
Why omit readOnly?
The resources.ARN condition with StartsWith limits data events to objects under nw-s3-dfir-data-<account-id>.
Omitting readOnly lets the selector record reads plus writes. That coverage includes object uploads, downloads, and deletions.
The scoped selector is ready. Your trail now captures the object activity that Event history could not show.
Selector not saving?
- Check that eventCategory contains Data.
- Check that resources.type contains AWS::S3::Object.
- Confirm that the ARN starts with arn:aws:s3::: and ends with /.
- Help me fix my scoped S3 advanced event selector.
Generate and query object evidence
The selector only records activity that happens after it is saved. You will now create one controlled write, one read, and one deletion for <object-key>.
- Switch back to the Objects tab for nw-s3-dfir-data-<account-id>.
- Choose Upload.
The upload page is ready to receive the same harmless local file.
- Choose Add file.
- Select <harmless-file> from your Linux device.
The upload queue should list the file that creates <object-key>.
- Approve the replacement if the console requests confirmation for the existing key.
- Choose Upload.
You should see a success message for the upload. This generates the controlled object write.
- Return to the bucket's Objects tab.
- Select <object-key>.
The selected object is ready for the controlled read.
- Download the selected object through the S3 console.
The downloaded copy should appear on your Linux device. This generates the object read that was previously invisible.
Deleting this harmless test object is deliberate and limited to the evidence bucket. The console presents a confirmation screen before removal.
- Select <object-key> again.
- Start the console's delete action for the selected object.
The confirmation screen should identify <object-key> as the object being removed.
- Confirm the deletion using the console's confirmation control.
Refresh the bucket's object list. You should no longer see <object-key>.
CloudTrail usually delivers events to CloudWatch Logs in about five minutes. A longer delay can still occur because delivery timing is not guaranteed.
- Switch to CloudWatch Logs Insights in Region <region>.
- Select only nw-s3-dfir-events as the query source.
The query now scans only the trail's Standard log group.
- Set the narrowest recent time range that covers the upload, download, and deletion.
Before you run the check, which object actions do you expect the trail to have recorded?
- Replace the query editor contents with this query:
stats count(*) by eventSource, eventName, awsRegion
What does this query do?
- The stats count(*) expression counts matching log events.
- The eventSource field groups activity by the AWS service that received each request.
- The eventName field separates the individual operations.
- The awsRegion field confirms where each request occurred.
- Choose Run query.
You should see s3.amazonaws.com rows for PutObject, GetObject, and DeleteObject in <region>.
You have closed the investigation blind spot. The trail now proves that the controlled object write, read, and deletion occurred.
Missing an object event?
- Refresh the results after a few more minutes because CloudTrail delivery can take longer than its usual average.
- Confirm that the query time range begins before the upload.
- Check that nw-s3-dfir-events is the only selected log group.
- Help me find a missing S3 data event in CloudWatch Logs Insights.
The grouped result proves that the operations exist. Raw messages add the actor, source, target, and precise event time needed for a case timeline.
- Replace the grouped query with this raw-event query:
fields @timestamp, @message | sort @timestamp desc | limit 25
What does this query show?
- The @timestamp field shows when CloudWatch Logs received each event.
- The @message field exposes the raw CloudTrail JSON record.
- The descending sort places the newest records first.
- The limit 25 clause keeps the inspection set small.
- Choose Run query.
- Open a recent raw message that names PutObject.
The opened message should expose the event time, identity ARN, source IP address, bucket name, and object key.
- Repeat the raw-message inspection for GetObject.
- Repeat the raw-message inspection for DeleteObject.
All three records should identify nw-s3-dfir-data-<account-id> plus <object-key> as the controlled target.
Cannot find the raw messages?
- Narrow the time range to the period immediately after the selector was saved.
- Refresh after a few minutes if the grouped results appeared before every raw event finished delivery.
- Confirm that the query source remains nw-s3-dfir-events.
- Help me locate my raw S3 object events in CloudWatch Logs Insights.
Your investigation now has queryable object-level evidence with actor and target details. Next, you will generate a controlled security configuration change and examine what CloudTrail can prove about it.
Investigate the Security Change
Your AWS CloudTrail trail already captures object reads, writes, and deletions for the target bucket. You can now move from data access to security-control evidence.
In this step, you'll create controlled drift in Amazon S3 by clearing one Block Public Access protection. CloudTrail will identify the actor behind the change.
The management event also records the UTC time and source IP address. It does not provide an explicit before-and-after resource-state timeline.
In this step, get ready to:
- Create controlled drift by clearing only BlockPublicAcls on the target bucket.
- Find the PutBucketPublicAccessBlock management event in CloudTrail Event history.
- Compare the event evidence with the bucket's current Permissions state.
Simulate controlled configuration drift
Changing a public-access control can feel risky. This lab limits the drift to one bucket-level protection.
The other three Block Public Access protections stay enabled. No public ACL or public bucket policy is added.
- Switch back to the Amazon S3 console from earlier.
- Select General purpose buckets.
- Select nw-s3-dfir-data-<account-id>.
- Select the Permissions tab.
- Choose Edit next to Block public access (bucket settings).
- Clear only the setting represented by BlockPublicAcls.
- Leave the setting represented by IgnorePublicAcls selected.
- Leave the setting represented by BlockPublicPolicy selected.
- Leave the setting represented by RestrictPublicBuckets selected.
- Choose Save changes.
- Enter confirm when the console requests confirmation.
- Choose Confirm.
You'll return to the Permissions page with exactly one bucket-level protection disabled. You've created a controlled drift condition on the target bucket.
What changed in the bucket?
With BlockPublicAcls set to false, that setting no longer rejects new public ACL operations. IgnorePublicAcls remains set to true.
The public-policy protections also remain enabled. The lab has changed one control without making the bucket public.
Can't change the bucket setting?
- Keep any account-level or organization-level protections unchanged if they prevent this edit.
- Use a standalone sandbox account where bucket-level changes are permitted.
- Ask an administrator for access to an approved sandbox before continuing.
- Help me understand why this AWS account prevents the bucket-level change.
Inspect the management event
CloudTrail Event history is Region-scoped. A bucket-level Block Public Access update appears as a management event named PutBucketPublicAccessBlock.
- Switch back to the CloudTrail console from earlier.
- Confirm the selected Region is <region>.
- Select Event history from the navigation pane.
- Set the Event name filter to PutBucketPublicAccessBlock.
- Set the recent time range to cover the bucket change you just saved.
Before you open the result, which parts of the change do you expect CloudTrail to tie to one actor?
- Open the matching PutBucketPublicAccessBlock event.
- Record the actor identity: the actor identity ARN.
- Record the UTC event time: the UTC event time.
- Record the source IP address: the source IP address.
- Confirm the target bucket is nw-s3-dfir-data-<account-id>.
- Review the requested public-access-block configuration in the event.
What does the event prove?
- The actor identity is the actor identity ARN.
- The UTC change time is the UTC event time.
- The source IP is the source IP address.
- The target is nw-s3-dfir-data-<account-id>.
- The requested configuration sets BlockPublicAcls to false.
- The requested configuration keeps IgnorePublicAcls set to true.
- The requested configuration keeps BlockPublicPolicy set to true.
- The requested configuration keeps RestrictPublicBuckets set to true.
Before you inspect the record further, do you think this single event can show the bucket's resource state before the request?
- Inspect the event details for an explicit resource state from before the change.
The event gives you the actor and requested change. It does not provide an explicit before-and-after resource-state timeline.
Can't find the management event?
- Confirm CloudTrail Event history is still showing Region <region>.
- Keep the Event name filter set to PutBucketPublicAccessBlock.
- Refresh the existing Event history search instead of changing the bucket again.
- Help me find the missing CloudTrail management event.
Before the final check, which single protection should the Permissions page show as disabled?
- Switch back to the target bucket's Permissions page from earlier.
- Confirm the setting represented by BlockPublicAcls is disabled.
- Confirm the setting represented by IgnorePublicAcls remains enabled.
- Confirm the setting represented by BlockPublicPolicy remains enabled.
- Confirm the setting represented by RestrictPublicBuckets remains enabled.
- Confirm no public ACL has been added.
- Confirm no public bucket policy has been added.
You'll see exactly one bucket-level Block Public Access protection disabled. CloudTrail Event history shows the matching PutBucketPublicAccessBlock event with actor evidence.
That is a useful forensic result. CloudTrail attributes the action while the Permissions page confirms the current weak state.
You now have actor evidence plus a visible gap in state history. Next, you'll add the configuration record that proves the bucket's state before and after containment.
Add Configuration History and Close the Case
Your CloudTrail management event identifies the actor who weakened the S3 control. It still leaves the bucket's before-and-after state implicit.
AWS Config closes that evidence gap by recording configuration items over time. That history shows when the bucket moves between security states.
You will capture the weak state before restoring the protection. A UTC timeline will connect that state history to the CloudTrail actors.
In this step, get ready to:
- Configure AWS Config to record only AWS::S3::Bucket changes.
- Restore BlockPublicAcls to true after capturing the weak state.
- Build a UTC incident timeline from CloudTrail evidence and AWS Config states.
Start narrowly scoped configuration recording
Continuous recording creates a configuration item whenever AWS Config detects a change to a recorded resource. Selecting one resource type keeps the evidence focused on S3 buckets.
AWS Config charges for recorded configuration items. Limiting this recorder to one resource type avoids collecting unrelated account activity.
- Enter AWS Config in the AWS Management Console search bar.
- Select AWS Config from the search results.
- Confirm that the Region selector shows <region>.
- Choose Get started.
- Choose Specific resource types on the Settings stage.
- Select only AWS::S3::Bucket.
- Choose Continuous recording.
- Choose the AWS Config service-linked role.
- Confirm that the selected role is AWSServiceRoleForConfig.
Why keep the recorder narrow?
Specific resource types limits the recorder to evidence relevant to this investigation. Continuous recording preserves each detected S3 bucket change as a separate configuration item.
This scope avoids an account-wide AWS Config bootstrap. The resulting timeline stays focused on the target bucket.
- Choose the new-bucket option in the delivery section.
- Enter a globally unique delivery bucket name that ends with <account-id>.
- Leave Amazon SNS disabled.
- Continue to the Rules stage.
- Select no managed rules.
- Continue to the Review stage.
- Confirm that the recorder includes only AWS::S3::Bucket.
- Confirm the setup.
The recorder is active with continuous recording scoped to S3 buckets. Your dedicated delivery bucket stores the configuration history.
Recorder setup blocked?
- Confirm that your signed-in role can manage AWS Config resources.
- Confirm that your signed-in role can create the dedicated delivery bucket.
- Use Settings to inspect an existing customer managed recorder if Get started is unavailable.
- Use a standalone sandbox account if the existing recorder belongs to another workload.
- Ask for help with the recorder configuration by selecting Help me diagnose my AWS Config recorder setup..
Capture the weak state and restore protection
The first configuration item must capture the controlled weak state. That snapshot gives the restoration a clear baseline.
AWS Config records changes on a best-effort basis. A quiet inventory during the first refresh is expected.
- Choose Resources in AWS Config.
- Filter Resource inventory to AWS::S3::Bucket.
- Refresh Resource inventory until nw-s3-dfir-data-<account-id> appears.
- Choose nw-s3-dfir-data-<account-id>.
- Inspect its current Block Public Access configuration.
The recorded weak state shows BlockPublicAcls=false. The other three protections remain true.
You have captured the missing before-state. The restoration now has evidence to compare against.
Restoring the cleared protection contains the controlled drift. The bucket still has no public ACL or public bucket policy.
- Switch back to the S3 Permissions page from earlier.
- Choose Edit next to Block public access (bucket settings).
- Enable the setting represented by BlockPublicAcls.
- Choose Save changes.
- Enter confirm in the confirmation field.
- Choose Confirm.
All four bucket-level Block Public Access protections are now enabled. The bucket remains free of public ACLs and public bucket policies.
The controlled drift is contained. AWS Config can now preserve the restored state beside the weak baseline.
- Return to AWS Config from earlier.
- Choose Resources.
- Choose nw-s3-dfir-data-<account-id>.
- Choose Resource Timeline.
- Filter the timeline by Configuration events.
- Refresh the timeline until the contained configuration appears.
You should see the weak state with BlockPublicAcls=false followed by the contained state with BlockPublicAcls=true.
The timeline should show IgnorePublicAcls, BlockPublicPolicy, and RestrictPublicBuckets set to true in both states.
Contained state missing?
- Refresh the same Resource Timeline while AWS Config processes the change.
- Confirm that AWS Config still shows <region>.
- Confirm that the recorder still includes AWS::S3::Bucket.
- Confirm that the current S3 Permissions page shows BlockPublicAcls enabled.
- Ask for help finding the contained state by selecting Help me find the missing contained state in AWS Config..
Correlate the evidence and close the case
Evidence correlation connects actor activity to recorded resource states. UTC gives every evidence source one shared clock.
What does each source prove?
CloudTrail data events identify the actor behind the recorded object activity. The management event identifies the actor behind the security-setting change.
AWS Config supplies the false-to-true state history. The live S3 Permissions page confirms final containment.
- Create a case timeline with columns for UTC time, actor, action, target, and evidence source.
- Switch back to CloudWatch Logs Insights from earlier.
- Select only nw-s3-dfir-events.
- Open the matching raw events for <object-key>.
- Add a PutObject row with its UTC time, actor, target key, and CloudTrail data-event source.
- Add a GetObject row with its UTC time, actor, target key, and CloudTrail data-event source.
- Add a DeleteObject row with its UTC time, actor, target key, and CloudTrail data-event source.
Your timeline now contains the recorded lifecycle of <object-key>. Each row links an object operation to an identity.
- Switch back to CloudTrail Event history from earlier.
- Open the PutBucketPublicAccessBlock management event.
- Add a management-event row with its UTC time, actor, source IP address, target bucket, and requested configuration.
- Return to the bucket's AWS Config Resource Timeline.
- Add the weak-state row showing BlockPublicAcls=false.
- Add the contained-state row showing BlockPublicAcls=true.
- Arrange every timeline row in UTC chronological order.
The correlated timeline now connects object access to the configuration change. It also shows the bucket's recovery from the weak state.
Before the final check, do you think one evidence source can prove both actor identity and resource state?
- Switch back to the S3 Permissions page.
- Confirm that BlockPublicAcls is enabled.
- Confirm that IgnorePublicAcls is enabled.
- Confirm that BlockPublicPolicy is enabled.
- Confirm that RestrictPublicBuckets is enabled.
- Confirm that no public ACL exists.
- Confirm that no public bucket policy exists.
- Add a final containment row showing all four protections enabled.
CloudTrail proves the actor activity. AWS Config proves the bucket's false-to-true state history.
The current S3 Permissions page confirms the contained state. All four Block Public Access protections are enabled.
Case closed. Your UTC timeline now proves the object activity, the configuration drift, and the restored bucket state.
Secret mission
Reduce S3 Data-Event Noise
Your trail captures every object operation for the target bucket. High-volume buckets can bury the activity that matters most. Filter the selector so the next query keeps GetObject and DeleteObject while excluding PutObject.
Clean Up Your Resources
Clean Up Your Resources
Your lab uses usage-based services from AWS. Choose whether to keep the lab active, pause evidence collection, or delete its resources.
Cost warning
Data events from AWS CloudTrail, delivery to Amazon CloudWatch Logs, configuration items from AWS Config, and storage in Amazon S3 are usage-based. Clean up now if you do not plan to continue the lab.
Stopping collection prevents new evidence from accumulating. Stored logs remain until you delete their log groups or S3 buckets.
Resources you used:
- The private S3 target bucket nw-s3-dfir-data-<account-id>. The test object is already absent.
- The multi-Region CloudTrail trail nw-s3-dfir-trail with its scoped advanced event selector.
- The S3 log bucket created for nw-s3-dfir-trail.
- The CloudWatch Logs log group nw-s3-dfir-events.
- The default CloudTrail delivery role CloudTrail_CloudWatchLogs_Role in AWS Identity and Access Management.
- The AWS Config customer managed recorder with its delivery channel, dedicated delivery bucket, and recorded configuration items.
Keep everything running
Keep the lab active if you plan to continue investigating S3 activity. No immediate teardown is required.
- Keep nw-s3-dfir-trail limited to GetObject and DeleteObject for the target bucket.
- Set a retention period for nw-s3-dfir-events to limit stored log volume.
- Leave the AWS Config recorder scoped only to AWS::S3::Bucket.
- Review ongoing AWS charges regularly.
Pause - I'll come back to this later
Pause new evidence collection while preserving the trail settings, stored logs, and configuration history for later use.
- Return to the details for nw-s3-dfir-trail in CloudTrail.
- Choose Stop logging.
- Confirm with Stop logging.
- Return to Settings in AWS Config.
- Choose Customer managed recorder.
- Choose Stop recording.
- Choose Confirm.
That gives you a clean stopping point. New CloudTrail logging and AWS Config recording are now paused.
Existing S3 objects and CloudWatch log data remain stored. That stored data can still incur charges.
Delete - I don't want to use this again
Deleting this lab is permanent. That is safe here because your incident timeline already captures the evidence you need.
- Return to the details for nw-s3-dfir-trail in CloudTrail.
- Find the S3 bucket under Storage location.
- Record its name here: your CloudTrail log bucket name.
- Return to Settings in AWS Config.
- Find the dedicated delivery bucket for the customer managed recorder.
- Record its name here: your Config delivery bucket name.
These two bucket names identify the stored evidence that remains after collection stops.
- Return to the CloudTrail trail list.
- Select nw-s3-dfir-trail.
- Choose Delete.
- Confirm with Delete.
The trail stops collecting events immediately. Its delivery destinations remain until you remove them.
- Return to the CloudWatch log groups area from earlier.
- Select nw-s3-dfir-events.
- Choose Actions.
- Choose Delete log group(s).
- Confirm the deletion.
The live query destination is now removed. Historical CloudTrail objects still sit in the S3 log bucket.
- Return to Settings in AWS Config.
- Choose Customer managed recorder.
- Choose Stop recording.
- Choose Confirm.
The recorder no longer creates new configuration items. Its existing delivery data remains in the dedicated S3 bucket.
S3 requires each bucket to be empty before deletion. Remove the stored objects first.
- Return to General purpose buckets in S3.
- Select nw-s3-dfir-data-<account-id>.
- Choose Empty.
- Complete the confirmation shown on Empty bucket.
- Monitor Empty bucket: Status until the process completes.
The target bucket is now empty. You can remove the bucket itself.
- Select the empty nw-s3-dfir-data-<account-id> bucket.
- Choose Delete.
- Enter nw-s3-dfir-data-<account-id> as the bucket name.
- Choose Delete bucket.
- Empty your CloudTrail log bucket name by repeating the same S3 empty flow.
- Delete your CloudTrail log bucket name by repeating the same S3 delete flow.
- Empty your Config delivery bucket name by repeating the same S3 empty flow.
- Delete your Config delivery bucket name by repeating the same S3 delete flow.
Your charge-generating collection and storage resources are now removed. One shared delivery role still needs a careful check.
The CloudTrail delivery role may be shared by another trail. Deleting a shared role could interrupt that trail's log delivery.
- Return to the CloudTrail trail list.
- Check the CloudWatch Logs delivery role used by each remaining trail.
- Find CloudTrail_CloudWatchLogs_Role in IAM.
- Use the role's delete action only if no remaining trail uses it.
The stopped AWS Config recorder no longer records configuration items. Its delivery-channel metadata can remain for this lab.
Nice Work!
Nice Work!
You pulled it off! Your evidence lab now traces object activity through configuration drift to verified containment.
You've learned how to:
- Build a private Amazon S3 evidence target that generates controlled object-access evidence.
- Trace object activity by pairing scoped AWS CloudTrail data events with CloudWatch Logs Insights queries.
- Correlate the PutBucketPublicAccessBlock actor record with AWS Config configuration items to prove the bucket's before-and-after security state.
- Complete the optional Secret Mission by retaining GetObject plus DeleteObject while excluding PutObject from the post-change results.
Ready to quiz yourself?