# how to read AWS CloudTrail for suspicious activity

## TL;DR
CloudTrail records every management API call in your AWS account, which makes it the timeline of record for cloud incidents. Query it with CloudTrail Lake SQL, look for the classic attacker patterns, and remember it logs API calls, not data access, so pair it with VPC flow logs and S3 access logs for the full picture.

```text
how to read AWS CloudTrail for suspicious activity
```

## Use this when
- you suspect suspicious activity in an AWS account
- you need a timeline of who did what in the cloud
- you are auditing privileged actions for a review
- an alert fired on an IAM key or role and you need context

## Not for this skill when
- you need network-level detail (that is VPC flow logs)
- you need to know which S3 objects were read (that needs S3 data events)
- the workload runs on another cloud (each has its own audit trail)
- you want real-time alerting rather than investigation (set up EventBridge rules)

## Steps
1. Open CloudTrail Lake and pick your event data store. If you dont have Lake enabled, enable it now; the 90-day event history console is painful for real investigations and Lake keeps a year or more queryable.

2. Find console logins without MFA or from unfamiliar places:
```sql
SELECT eventTime, userIdentity.userName, sourceIPAddress, additionalEventData
FROM [event data store id]
WHERE eventName = 'ConsoleLogin'
AND additionalEventData.MFAUsed = 'No'
ORDER BY eventTime DESC
LIMIT 50
```
Expected: mostly known users with MFA. Rows without MFA from unfamiliar IPs deserve a look.

3. Look for privilege moves: role assumptions from unusual IPs, new access keys, policy attachments:
```sql
SELECT eventTime, eventName, userIdentity.arn, sourceIPAddress
FROM [event data store id]
WHERE eventName IN ('AssumeRole', 'CreateAccessKey', 'AttachUserPolicy', 'PutUserPolicy')
ORDER BY eventTime DESC
LIMIT 100
```
Expected: mostly automation and known admins. A CreateAccessKey at 3am from a new IP is the classic "we have a problem" row.

4. Look for recon. Attackers map the environment before they act, which shows up as bursts of Describe, List, or Get calls from one principal in a short window. Group by principal and count; the outlier is your story.

5. Check for defense disabling: StopLogging, DeleteTrail, or changes to GuardDuty, Security Hub, or Config settings. Attackers turn off the cameras first. Any of these outside a change window is an incident by itself.

6. Check for new regions and new services. Activity in regions you never use, or first-time use of services like STS from odd places, is a strong signal. Baseline what "normal" looks like for your account first.

### Variant: reading CloudTrail for one compromised key
Filter everything by the key's access key ID or the user ARN, sort by time, and read it like a story: first the recon calls, then the privilege moves, then the resource creation. The sequence tells you what the attacker wanted.

### Variant: using Athena on the S3 archive instead of Lake
If you archive trail logs to S3, query them with Athena using the standard CloudTrail table schema. Slower than Lake but useful for deep history beyond your Lake retention, and for accounts that never enabled Lake.

### Variant: what CloudTrail will not show you
Data-plane reads need data events enabled (S3 object-level, Lambda invokes). Network traffic needs VPC flow logs. Instance memory and disk need EDR. CloudTrail is the management plane; plan the other sources alongside it.

## Why this happens
Attackers live in the management plane when they pivot through cloud: assuming roles, creating keys, opening security groups. Every one of those actions leaves a CloudTrail event, which is why the trail is usually the fastest path from "something is wrong" to "here is exactly what happened."

## Edge cases and pitfalls
- Assumed-role session names can be set by the caller, so dont trust the session name alone; correlate with the source IP and the calling principal.
- Cross-account events land in the other account's trail. If the attacker pivoted, you need both sides.
- A gap in the trail is itself a finding. If logging was stopped, treat the gap as attacker activity until proven otherwise.
- Timestamps are UTC. Convert before you compare against local-time sources or your timeline will be off by hours.
- Large accounts generate enormous event volumes. Narrow by time window and principal early, or your queries will time out.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_skmsWum0TSVAe07p8n73Rw
