Skip to content

This tool is not affiliated with, endorsed by or sponsored by Amazon Web Services, Inc. or Amazon.com, Inc. AWS, Amazon Web Services, CloudTrail and GuardDuty are trademarks of Amazon.com, Inc. or its affiliates. Other names are trademarks of their respective owners.

How to export CloudTrail, VPC Flow and S3 logs for forensics

Export CloudTrail logs from the trail bucket, event history or CloudTrail Lake, plus VPC Flow Logs, S3 access logs, GuardDuty findings and IAM reports.

Published on 5 min read

TL;DR. Collect first, analyse second. The best CloudTrail source is the trail's S3 bucket (AWSLogs/<account-id>/CloudTrail/<region>/YYYY/MM/DD/*.json.gz): copy it with aws s3 sync, keep the files compressed and untouched. No trail? Download event history per region — 90 days, management events only. Then grab VPC Flow Logs, S3 server access logs, GuardDuty findings and the IAM credential report. Take a few quiet days before the incident too: baselines need them.

Attackers with admin rights delete trails and detectors. Retention settings quietly expire objects. Event history rolls over after 90 days. The single most useful thing you can do in the first hour of an AWS incident is to put a copy of the evidence somewhere the attacker cannot reach, before anyone starts "cleaning up".

Before you start: scope and a safe destination

  • Time window. From a few days before the first suspicious event to now. Detections that compare against normal behaviour (a key's usual IP addresses, the regions you normally use) need that quiet period.
  • Accounts and regions. Organization trails put every account under one bucket; single-account trails may be per region. List them with aws cloudtrail describe-trails --include-shadow-trails.
  • Credentials for collection. Use a principal the attacker has not touched, ideally a dedicated read-only role. Do not collect with the compromised key.
  • Destination. A local encrypted disk or a separate account. Record SHA-256 hashes of what you downloaded for the case file.

1. CloudTrail from the trail's S3 bucket (best source)

A CloudTrail trail delivers gzip-compressed JSON files to S3, about every five minutes according to AWS's description of how CloudTrail works. The key layout is predictable:

s3://<bucket>/[<prefix>/]AWSLogs/[<org-id>/]<account-id>/CloudTrail/<region>/YYYY/MM/DD/<account>_CloudTrail_<region>_<timestamp>_<id>.json.gz

Copy the window you need:

aws s3 sync s3://<bucket>/AWSLogs/<account-id>/CloudTrail/ ./cloudtrail \
  --exclude "*" --include "*/2026/09/1*"

Notes from the field:

  • Keep the .json.gz files as they are. Recompressing or merging them loses the per-file names that carry the region and delivery time.
  • Digest files under CloudTrail-Digest/ are signed hash chains, not events. Keep them for the case file — they let you run log file integrity validation — but analysis tools skip them.
  • Data events (S3 GetObject, Lambda Invoke…) land in the same files if the trail was configured for them. They are not logged by default (AWS documentation), so check the trail's event selectors to know what you can expect to see.
  • CloudTrail Insights events, when enabled, sit under a separate CloudTrail-Insight/ prefix.

2. CloudTrail event history (no trail configured)

Every account has event history: the last 90 days of management events, per region, without data events. It is better than nothing and it is independent of trails, so an attacker deleting a trail does not remove it.

  • Console: CloudTrail → Event history, in each region, remove the default read-only filter, choose the time range, then Download events → JSON (preferred) or CSV. A single download holds up to 200,000 events.
  • CLI, per region:
for r in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
  aws cloudtrail lookup-events --region "$r" \
    --start-time 2026-09-01T00:00:00Z --output json > "events-$r.json"
done

lookup-events returns each event as a JSON string in the CloudTrailEvent field; keep the output as-is, analysis tools parse it.

3. CloudTrail Lake

If you have an event data store, query it and save the results to S3:

SELECT eventJson FROM <event-data-store-id>
WHERE eventTime > '2026-09-01 00:00:00'

Selecting the full eventJson column keeps every field. Flat column selections work for quick reviews but drop nested fields such as requestParameters.

4. VPC Flow Logs

VPC Flow Logs go to S3, CloudWatch Logs or Firehose.

  • S3: AWSLogs/<account-id>/vpcflowlogs/<region>/YYYY/MM/DD/*.log.gz. Sync it like CloudTrail. Plain-text delivery includes a header line naming the fields; keep it, because custom formats change the column order. Parquet is a delivery option too, but not every tool reads it.
  • CloudWatch Logs: create an export task to S3 (aws logs create-export-task) or page through aws logs filter-log-events for a narrow window.

Flow logs record metadata (addresses, ports, bytes, accept/reject), not payloads. The VPC Flow Logs analysis post explains what that can prove.

5. S3 server access logs

If server access logging was enabled on the bucket that matters, the logs sit in the target bucket and prefix you configured:

aws s3 sync s3://<log-bucket>/<prefix>/ ./s3-access

The objects have no extension and one space-delimited line per request. Delivery is best effort: AWS states that completeness and timeliness are not guaranteed (documentation). Use them alongside CloudTrail data events when both exist.

6. GuardDuty findings

GuardDuty retains findings for 90 days; an S3 publishing destination keeps them longer (export documentation). Export them early — deleting a detector is a common attacker move.

DET=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
aws guardduty list-findings --detector-id "$DET" --query 'FindingIds' --output text \
  | xargs -n 50 aws guardduty get-findings --detector-id "$DET" --finding-ids > findings.json

Repeat per region where GuardDuty is enabled.

7. IAM credential report

The credential report lists every user with password, MFA and access-key status, including last-used dates. IAM generates at most one report every four hours (documentation).

aws iam generate-credential-report
aws iam get-credential-report --query Content --output text | base64 -d > credential-report.csv

Checklist

SourceWhereRetention to worry aboutPriority
CloudTrail trailS3 bucket AWSLogs/…/CloudTrail/Bucket lifecycle rules1
Event historyConsole / lookup-events, per region90 days1 if no trail
GuardDuty findingsget-findings or S3 export90 days in GuardDuty2
Credential reportIAMSnapshot of now2
S3 data eventsSame trail filesOnly if configured2
S3 server access logsTarget bucketBucket lifecycle3
VPC Flow LogsS3 / CloudWatch LogsLog group retention3

Next step

Once collected, drop everything at once into the in-browser analyzer: trail folders, event-history JSON or CSV, Lake CSV, flow logs, access logs, findings and the credential report are recognised automatically, and nothing leaves your machine. The CloudTrail log analysis guide walks through reading the results, and the incident response overview puts collection in the wider containment plan.

Related articles

What CloudTrail, VPC Flow Logs and S3 access logs do not record, where baselines fail, and how to write honest conclusions when evidence is missing.
GPU instances, a bill spike, a region nobody uses: confirm crypto-mining on AWS from CloudTrail and flow logs, contain it, and find how they got in.
Defense evasion on AWS: StopLogging, DeleteTrail, event selectors, GuardDuty detectors deleted, Config and Flow Logs removed, and what CloudTrail keeps.

This tool is not affiliated with, endorsed by or sponsored by Amazon Web Services, Inc. or Amazon.com, Inc. AWS, Amazon Web Services, CloudTrail and GuardDuty are trademarks of Amazon.com, Inc. or its affiliates. Other names are trademarks of their respective owners.