Replay fixtures (fill in)¶
Before you fill this in
Start in: Module 11 (DET-001 walkthrough and assignment). Save as: docs/capstone/work/fixtures/<rule-id>.fire.jsonl and <rule-id>.quiet.jsonl, one pair per rule, eight pairs in total.
Example: Helix HELIX-003 fixture. Helix event names don’t exist in notes-api.
A rule you’ve never replayed is a belief. A fixture turns it into a claim someone else can test: this input fires the rule, and that input, which looks almost the same, does not.
The two files¶
| File | Contains | Must produce |
|---|---|---|
<rule-id>.fire.jsonl |
The smallest set of events that should trip the rule | Exactly the alert ID <rule-id>:<group key> |
<rule-id>.quiet.jsonl |
The nearest legitimate case: below threshold, outside the window, a different group key, or a benign value | No alert |
An empty quiet file proves nothing. Make it the case a tired analyst would confuse with the attack.
Each line is one notes-api event, in the same shape the API writes:
{"ts":"2026-09-15T10:00:01.000000Z","event":"<event name>","service":"notes-api","lab_mode":true,"trace_id":"fx-1","actor":"alice"}
tsis UTC with microseconds. Windows are measured in event time, not ingest time.- Include every field your rule’s
group_byandmatch_fieldread. A missing field groups underusername, or under an empty key. - Use dummy values only. Never paste a real token or a real IMDS key.
Shape example — DET-001 (provided rule)¶
DET-001.fire.jsonl: six login_failure events from one src_ip within
120 seconds.
{"ts":"2026-09-15T10:00:01.000000Z","event":"login_failure","service":"notes-api","lab_mode":true,"trace_id":"fx-1","src_ip":"127.0.0.1","username":"alice"}
{"ts":"2026-09-15T10:00:02.000000Z","event":"login_failure","service":"notes-api","lab_mode":true,"trace_id":"fx-2","src_ip":"127.0.0.1","username":"alice"}
10:00:06.)
DET-001.quiet.jsonl: three failures from the same src_ip, which is below
the threshold of five. A user who mistypes a password three times isn’t an
attack.
Replay command¶
This runs soc-lite’s own ingest and evaluate against one file with a
throwaway database, so it never touches your live cases.
The fire file should print ['DET-001:127.0.0.1'] and the quiet file [].
The Docker path reads the rules mounted from labs/detections/rules.yaml,
so your authored rules are included.
Record¶
Copy this table into work/attack-coverage.md under Replay fixtures.
| Rule | Fire file → alert | Quiet file → nothing | What the quiet case represents |
|---|---|---|---|
| DET-001 | |||
| DET-002 | |||
| DET-003 | |||
| DET-004 | |||
| DET-005 | |||
| (yours) | |||
| (yours) | |||
| (yours) |