1. Start with the investigation question
A support team receives a report of potentially improper reads of reconciliation files. The first question is which objects were read, by whom, and during which period. Default CloudTrail history covers management events by Region for 90 days; it does not replace collection of the data events needed for GetObject. An empty search in an unsuitable source does not close the investigation. Build a matrix containing event category, account, Region, resource, period, and retention destination. For a known regional call, first confirm the queried Region. For object access, establish whether collection existed during the relevant period and which filters were active. Record gaps explicitly without turning current configuration into historical coverage.
2. Change selectors without reducing coverage
Moving to advanced selectors can solve sensitive-read collection while losing management events if prior coverage is forgotten. Both selector modes do not accumulate on the same trail. Save approved configuration before the change and express the full intent in the new set. At selector level, matching one is enough for an event to be selected; within each selector, interpret the actual fields and operators. A readOnly=false filter excludes reads even when resources are correct. During rehearsal, perform an authorized read and an authorized management change, confirm records at the destination, and measure delay. Acceptance needs behavioral checks alongside configuration API success.
3. Correlate without duplicating or erasing perspectives
A timeline must distinguish eventTime from SIEM arrival. Late delivery does not change the recorded action time. Retain UTC times, identifiers, and references to original records. For the same copy ingested twice, eventID identifies the individual event. However, a cross-account action can produce distinct events sharing sharedEventID with different recipientAccountIds. Relate these perspectives without deleting them as though they were duplicate bytes. The Python model below uses fictional data to show a repeated copy and two perspectives on one action. Predict three unique events and two related perspectives. The exercise does not validate a trail, signatures, optional fields, or the entire CloudTrail schema; it teaches only the keys used for correlation.
4. Findings, sensors, and rehearsals
GuardDuty can update an existing finding when it observes related activity. Counting only new IDs can hide an ongoing issue; track count, last observation, and resources. A synthetic finding received in a ticket demonstrates the tested integration path but does not exercise every fleet sensor. For Runtime Monitoring, check coverage per resource and investigate Unhealthy status, including agent and VPC endpoint. Global enablement does not establish event delivery from every instance. Also confirm resource support: ECS Fargate and EKS Fargate do not have identical coverage under this plan. When presenting results, distinguish tested integration, operational sensor, and investigated threat. These are complementary evidence with different owners and acceptance criteria.
5. Suppression and configuration state
Reducing noise requires understanding what becomes invisible. Suppressed findings are archived and do not reach documented integrations such as EventBridge; they also stop participating as attack-sequence signals. Limit exceptions to known behaviors with rationale and review. For configuration changes, AWS Config Daily represents the period’s latest state and may not show intermediate transitions. A central aggregator provides a read view of source data without granting rule deployment into those accounts. Define collection, aggregation, detection, and correction separately. An operational meeting should distinguish an actually corrected change, an event merely filtered out, and a recording gap, because each requires different action and ownership.
6. Read query results with their limitations
Config advanced query examines current state rather than providing universal historical search. Deleted resources and ResourceNotRecorded CIs are not returned by this mechanism. If the objective is to investigate a deleted instance, select history and sources supporting that question. Arrays also present an interpretation risk: a rule-name condition and a compliance condition can match different elements. Before claiming rule A failed, inspect the name/status pair in the same element. At handover, deliver example queries with assumptions, coverage, and limitations alongside commands. The recipient needs to know when an empty query means an incorrect filter, unrecorded data, or absence actually observed within a valid scope.
# Original local correlation exercise, not a CloudTrail parser or verifier.
# No credentials, network calls, or AWS changes.
rows = [
{"eventID": "a", "eventTime": "2026-10-05T09:00:00Z", "recipientAccountId": "caller", "sharedEventID": "action-1"},
{"eventID": "b", "eventTime": "2026-10-05T09:00:00Z", "recipientAccountId": "owner", "sharedEventID": "action-1"},
{"eventID": "c", "eventTime": "2026-10-05T08:59:00Z", "recipientAccountId": "caller"},
]
rows.append(dict(rows[0]))
unique = {row["eventID"]: row for row in rows}
ordered = sorted(unique.values, key=lambda row: (row["eventTime"], row["eventID"]))
perspectives = [row for row in unique.values if row.get("sharedEventID") == "action-1"]
assert len(unique) == 3
assert [row["eventID"] for row in ordered] == ["c", "a", "b"]
assert {row["recipientAccountId"] for row in perspectives} == {"caller", "owner"}
print("unique=3 related_perspectives=2 order=c,a,b")
A sensitive read is missing from the SIEM because the selector includes only writes. The telemetry incident requires correcting the filter and declaring the uncovered window.
Common pitfalls
Empty query as absence; accepted API as coverage; sample as sensor; suppression as remediation; current state as history.
Related topics: Detection and security evidence · Federation and session context
A security conclusion should state source, scope, period, and observation limits.
Reference: CloudTrail event history · SCS-C03