CloudTrail log analysis: a step-by-step guide
CloudTrail log analysis in your browser: load the exports, read the verdict and findings, pivot on keys and IPs, build the timeline, then remediate.
TL;DR. Collect the exports, drop them all into the analyzer, then work in this order: verdict and coverage (what the tool could and could not see) → findings (confirm each one against its evidence rows) → entity pivots (every key, IP and principal the attacker touched) → timeline (the story, in order) → remediation (containment first). Plan 30 to 60 minutes for a typical key-leak incident. Everything runs locally in WebAssembly; no log leaves your browser.
This guide uses AWS Forensics because it is what this site provides, but the method is the same whatever you use — Athena, CloudTrail Lake, a SIEM or jq. The questions do not change; only the speed of answering them does.
Step 1 — Collect the exports
Get the CloudTrail files for the incident window plus two to three quiet days before it. Two detections — "access key used from a new IP" and "activity in a region not used before" — compare against the first day of activity found in the logs, so without a baseline they have nothing to compare to. The tool warns you when less than two days of CloudTrail are loaded.
Add whatever else you have:
- VPC Flow Logs (network exfiltration, mining traffic)
- S3 server access logs or CloudTrail S3 data events (object reads)
- GuardDuty findings JSON
- The IAM credential report (MFA, root keys, users created during the incident)
The export guide has the commands for each source.
Step 2 — Load everything at once
On the home page, choose files or a folder, or drop them. Accepted as-is:
| Source | Formats understood |
|---|---|
| CloudTrail | S3 .json.gz trees (including organization trails), event history JSON or CSV, lookup-events output, CloudTrail Lake CSV, EventBridge envelopes, CloudWatch Logs exports |
| VPC Flow Logs | Default version 2 text or custom formats with their header line |
| S3 | Server access log objects |
| GuardDuty | get-findings output or S3-exported findings |
| IAM | Credential report CSV |
ZIPs (including nested ones) and gzip are decompressed as streams, so multi-gigabyte exports do not need to fit in memory. Digest files are recognised and skipped. The Files tab lists every file with the format detected, and a "files not analysed" section explains anything that was skipped — an ALB log, a Parquet flow log, a truncated gzip.
To practise first, click Try a sample: it loads a synthetic export of a fictional incident, clearly labelled as such.
Step 3 — Read the verdict and the coverage notes
The verdict has three levels:
- Compromised — at least one critical finding, or two high-severity findings with at least one attacker-side signal (access anomaly, reconnaissance, defense evasion, exfiltration, impact or a GuardDuty finding).
- Suspicious — any high or medium finding, or several low ones.
- Clean — no detection fired.
Configuration findings from the credential report (root keys, users without MFA) are shown but excluded from the verdict: they describe posture, not activity.
Then read the coverage block. "No S3 data events or S3 access logs" means data theft from buckets cannot be assessed — it does not mean it did not happen. A "Clean" verdict with three coverage warnings is a weak statement; say so in your notes. The limitations post goes further.
Step 4 — Confirm each finding against its evidence
Each finding shows its severity, the MITRE ATT&CK techniques, the parameters extracted (key, principal, IP, bucket, region…), the time span and the evidence events. Open the raw record of at least the first and last evidence event.
Questions to ask for every finding:
- Who?
userIdentity.arnanduserIdentity.accessKeyId. Is this a human, a CI role, an AWS service? - From where?
sourceIPAddressanduserAgent. Corporate egress, a CI runner, a VPS? - Did it succeed? A missing
errorCodemeans success;AccessDeniedmeans the attempt failed. - Is there a change ticket? Admin work looks like attacker work. Ask the person named in the event.
Detections point; they do not prove. A "GPU instances launched" finding in an ML team's account is Tuesday. The same finding from a key that was on a laptop in Lyon yesterday and on a VPS today is an incident.
Step 5 — Pivot on entities to scope
The Entities tab lists every principal, access key, IP address, region, resource and user agent in the logs, with counts, errors, first/last seen and what each was seen with. Entities that appear in findings are flagged.
The scoping loop:
- Pivot on the leaked key → note every IP it was used from.
- Pivot on each attacker IP → note every other key or principal used from it.
- Pivot on each new principal (a user the attacker created, a role it assumed) → note what it did.
- Repeat until no new entity appears.
This is how you find the second access key the attacker minted for their backdoor user, which the first key's activity alone would not show you. The leaked access key investigation applies the loop in detail.
Step 6 — Build the timeline
The Timeline tab orders the evidence events of every finding (up to six per finding). The Events tab has the complete record set with filters — source, "in findings only", "errors only", "writes only" — and a UTC/local toggle. Click any row for the original record.
For the case file:
- CSV export of the filtered events (cells that could be interpreted as spreadsheet formulas are neutralised);
- JSON report with the verdict, findings, evidence and statistics.
Write the narrative in UTC and keep the original exports next to it.
Step 7 — Work the remediation checklist
The Remediation tab merges the remediation steps of every finding, containment first, with the actual values filled in: the key to deactivate, the user to delete, the region where GuardDuty must be re-enabled. Tick items as you go (the state stays in the page only).
Before deleting anything, make sure you saved what you need as evidence: inline policies of backdoor users, the user data of modified instances, a snapshot of the attacker's instances. Then follow AWS's Security Incident Response Guide for the rest of the process.
Common pitfalls
- Only one region of event history. Event history is per region; attackers like the regions you do not open.
- No baseline. Loading only the incident day makes "new IP" and "new region" detections blind.
- Trusting the sourceIPAddress of AWS services. When a service acts for you, the field contains a service name such as
ec2.amazonaws.com, not an IP. - Stopping at the first key. The first key is how they came in, not everything they hold.