Define the contract before the query
In a fictional funds service, the SOC receives authentication events through a queue. An analyst wants to correlate failures with a later success. Before counting rows, identify the producer, tenant, stable user identity, event identifier, result and both available times. A display name can change or exist in several tenants. A received row can also be another delivery of an earlier event. In the lab, the parser requires nonempty strings, a known result and timestamps with explicit offsets. Three invalid inputs are quarantined with reasons; they are not silently converted into successes or failures. This is a teaching policy chosen for synthetic data, not a universal contract for every provider.
Distinct event and repeated delivery
Delta has one failure delivered three times before success. Querying raw rows reaches the threshold of three; querying distinct events does not. Event identity must respect producer scope: two systems can emit the same local number without describing the same occurrence. The lab retains three different IDs in one second and the same local ID from three distinct sources. Deduplicating by timestamp alone would destroy legitimate activity. The example grouping removes copies with identical normalized payloads and retains the first observation. Conflicting payloads under one ID would need an additional policy; the convenient version must not be selected silently. Also retain delivery and rejection counts so ingestion problems remain diagnosable.
A timeline has more than one clock
Event time describes what the origin clock recorded; observed time describes when the collection point saw it. A collector observation timestamp is not necessarily the final SIEM indexing time. In the late case, failures occurred before success but arrived much later. At 100 seconds they cannot yet support the alert; retrospective analysis after arrival can find them. Correlating only by observed time places those failures after success and loses the sequence. Do not erase the original time to make the rule work. Retain both times, origin and the interpretation used. Also define reprocessing and repeated-alert policy; the lab’s simple full-history replay does not implement these production functions.
Time quality and identity scope
In the clock case, three failures have origin times later than their observation. Negative latency warrants investigation of clocks, parsing and transformation; it does not prove tampering. Normalizing an explicit offset to UTC resolves representation but does not repair a wrong clock. The teaching window includes exactly the 300 seconds before success; 301 seconds is outside. Testing the boundary prevents disputes caused by undefined inclusivity. In another case, failures for shared in funds-a are combined with success in funds-b when the join uses only the name. The correction retains tenant and identity in the predicate. More sources improve confidence only if the team understands identity relationships and timestamp quality.
Practice and operational handover
Run the script and first explain the difference between raw and events. Predict the result of removing tenant scope and replacing event_time with observed_time. Confirm which cases change and why. Then inspect what the pipeline emits: JSON must preserve a string containing a newline without fabricating another physical record, and a synthetic token is excluded through an explicit field allowlist. This does not validate every log consumer or every secret type. For APS handover, record parser version, correlation keys, selected clock, known delays, rejections, retention and replay procedure. No alert from a device lacking telemetry must appear as a coverage gap rather than evidence of security.
# Original local exercise, no network or production logs:
python3 content/labs/securityx-detection-evidence/run.py \
--output /tmp/securityx-detection.json
# Compare completeAlerts with earlyAlerts and inspect quarantined.
# Source time and observation time are retained separately.
Three deliveries of one failure look like three attempts. Correct deduplication removes delta’s alert; a join without tenant creates another false alert.
Common pitfalls
Counting rows as attempts; deduplicating by time alone; joining names across tenants; replacing clocks without records; hiding rejected events.
Related topics: Detection and quality · Incident response
Correlation depends on identifiable events, interpretable time and observable coverage.
Reference: OWASP Logging Cheat Sheet · CAS-005 / SecurityX V5; objectives 3.0; launched 2024-12-17