skip to content

When a hunt query becomes a scheduled SIEM detection, what must change in the search?

level: seniorimportance: must knowfreq 62%

answer

  1. run once versus run forever
  2. pin the index, bound the window
  3. window tied to the interval, plus lookback
  4. the eyeball becomes a number
  5. state the accepted misses

basics

~20 s

It becomes scoped and repeatable: pinned index and sourcetype, a window matched to the run interval with a lookback for late data, no wildcards or subsearch joins, and a fixed threshold. The narrowing is deliberate and written down.

solid answer

~40 s

A hunt runs once, a human reads it, and breadth is the point. A scheduled detection runs every few minutes forever beside every other rule, and its output goes to a queue rather than to its author, so it must be cheap, deterministic and bounded. Replace `index=*` and wildcarded sourcetypes with the exact index and sourcetype; replace `earliest=-90d` with a window equal to the run interval, offset by a lookback so records arriving late are still in range; use parsed fields instead of free text; rewrite subsearch-backed joins as `stats`; turn the analyst's eyeball into a fixed threshold; emit one row per entity with the fields triage needs. Then state the narrowing: one object, one index, one window, one threshold. That sentence is the rule's coverage claim.

code

text · 12 lines
text
# hunt: interactive, run once, breadth is the point
index=* sourcetype=*audit* customers earliest=-90d
| join type=left user [ search index=* sourcetype=*hr* ]
| table _time user client_ip database object statement

# scheduled: runs every 15 minutes, window offset for late-arriving records
index=db_audit sourcetype=cloudsql:audit statement_type=SELECT object=customers
  earliest=-20m latest=-5m
| stats count as stmts, dc(client_ip) as src_ips,
        min(_time) as first_seen, max(_time) as last_seen
        by user, database
| where stmts > 200

go deeper

for a junior

Be ready to name the obvious differences: a hunt is run once by a person over a wide range, while a scheduled search runs on a timer over a small window against a pinned index, and it needs a fixed threshold.

for a middle

Explain each rewrite and why it is needed: pinned source, window tied to the run interval with a lookback for late records, fields instead of free text, stats instead of a subsearch-backed join, output shaped as one row per entity.

for a senior

Show that you treat the narrowing as a coverage decision, can state the rule's accepted misses in a sentence, and know that an over-expensive rule can be skipped so its window is never searched at all.

for a principal

Own the arrangement where the wide hunt is retained alongside the narrow rule and re-run deliberately, and where the cost of a scheduled search is reviewed as a detection-coverage question rather than an infrastructure one.

## Two searches, two jobs The exploratory query and the scheduled detection can express the same intent and still have almost nothing in common as artefacts. A **hunt query** is run once, by the person who wrote it, who is looking at the output. It may span ninety days, wildcard the sourcetype because nobody is sure what the audit stream is called this quarter, carry three joins and a subsearch, and return raw events for eyeballing. Its breadth is its value: it exists to find something nobody has written a rule for yet. Its cost is paid once, and its author will notice if it behaves strangely. A **scheduled detection** runs on a timer, hundreds of times a day, competing for the same search capacity as every other rule, and its output lands in a queue read by somebody who was not there when it was written. Everything about it has to be bounded and boring. ## What changes, concretely **Pin the source.** `index=*` and `sourcetype=*audit*` become `index=db_audit sourcetype=cloudsql:audit`. Wildcards over sourcetypes were tolerable while a human was checking; on a schedule they multiply cost by whatever else lands in those indexes and change meaning silently when a new source is onboarded. **Bound the window and tie it to the schedule.** `earliest=-90d` becomes a window equal to the run interval, shifted back far enough that records arriving late are still inside it — a search running every fifteen minutes might cover from twenty minutes ago to five minutes ago. Get this wrong in one direction and consecutive runs overlap and re-alert on the same activity; in the other, there is a gap between runs that nothing ever examines. **Use fields, not free text.** A bare term such as `customers` matches wherever that string appears; `object=customers` states which field you mean. Free text also makes the rule fragile against unrelated changes in message formatting. **Remove subsearch-backed joins.** A join is materialised on the search head and capped, so a scheduled correlation can silently truncate. Reading both sources in one pass and aggregating with `stats` by the shared key expresses the same intent without an intermediate result set. **Fix the threshold.** During the hunt, the analyst looked at the distribution and said *that one is odd*. The rule needs a number. Deriving a defensible number from real data is its own exercise; what matters here is that the number is explicit in the search rather than living in the author's judgment. **Shape the output for triage.** One row per entity, carrying the evidence: user, client address, database, object, statement count, first and last seen. A rule that emits raw events forces every analyst to reconstruct the picture from scratch at three in the morning, and to re-run the search to do it. ## What the narrowing costs, and why you write it down The exploratory query found a contractor account bulk-reading a customer table through a shared application service account across ninety days and every index. The scheduled version watches one object, on one index, over a fifteen-minute window, above a threshold. It would not have found the same behaviour against a different table, or below the threshold, or spread thinly over weeks. That is not a defect — a rule that keeps the breadth of a hunt cannot run on a schedule — but it is a claim that must be stated rather than assumed. The useful form is one sentence of scope and one of accepted misses: *fires on more than N SELECT statements against the customers object on the db_audit index within fifteen minutes by a single principal; does not see other objects, other data stores, or activity spread below the threshold.* Anyone reviewing coverage later reads that sentence instead of reverse-engineering the SPL. ## The failure mode people forget: the run that never happened A scheduled search that is too expensive does not merely cost money. When the scheduler is saturated, runs are skipped, and a skipped run means that window is never searched — a gap with no alert and no record in the alert queue, because the absence of an alert and the absence of a run look identical from the outside. This is why the narrowing above is a detection concern rather than a budget concern, and why rule cost belongs in the review of the rule. ## Keep the hunt query The hunt does not get deleted when the rule ships. It stays as the wide version you re-run when the rule has been quiet, when the estate changes, or when an incident elsewhere suggests the narrow version's assumptions no longer hold. The pair — one wide and occasional, one narrow and continuous — is the working arrangement, not a stage you pass through.

  • Why not simply schedule the ninety-day hunt to run nightly?
    Cost scales with every run, and the output is dominated by the same historic activity night after night, so the same finding re-alerts indefinitely. Worse, an expensive run is the one most likely to be skipped or finalized, and a skipped run means that window is never searched at all, with nothing in the queue to show for it.
  • How do you choose the window relative to the run interval?
    Make the window at least as long as the interval, then shift it back by enough to cover ingestion lag, measured by comparing event timestamps against index time on that source. Overlap produces duplicate alerts you deduplicate on the entity key; too small a shift produces gaps that nothing examines, which is the worse of the two errors.
  • What do you keep from the hunt once the rule ships?
    The hunt itself, saved and re-runnable, along with its intent and field-level logic. It is the wide version you go back to when the rule has been quiet, when the estate changes shape, or when an incident suggests the narrow rule's assumptions no longer hold. The narrow rule and the wide query are a pair, not two stages.

The hunt is a floodlight you switch on once and look under; the detection is a tripwire you leave in place. A tripwire strung across the whole estate never stays taut.

saying these in an interview costs you the question

  • Schedules the exploratory query unchanged and calls it a detection
  • Leaves index and sourcetype wildcarded on a scheduled search
  • Treats the narrowing as free rather than as accepted misses
  • Emits raw events and leaves triage to reconstruct the picture
  • Ignores skipped runs because no alert means nothing happened

context