Loading

Event correlation (EQL) rules

Event correlation rules use Event Query Language (EQL) to detect ordered sequences of events, single events with complex conditions, or the absence of expected events. EQL is purpose-built for event-based data and excels at expressing time-ordered relationships that other query languages cannot.

EQL rules are the right fit when:

  • You need to detect a sequence of events that must occur in a specific order, such as a process creation followed by a network connection from the same process.
  • You want to detect missing events in a sequence, for example, a login that is never followed by a logout within a time window.
  • The detection logic involves correlating events by a shared field (such as process.entity_id or host.id) across time.
  • You need richer event-level logic than KQL allows, such as filtering by event category within a sequence step.

EQL rules are not the best fit when:

  • A single-event match is sufficient. Use a custom query rule instead.
  • You need to count how often something happens. Use a threshold rule instead.
  • You need aggregation, transformations, or pipe-based processing. Use an ES|QL rule instead.

EQL rules require at least one Elasticsearch index pattern or data view. The indexed data must include a timestamp field (defaults to @timestamp) and an event category field (defaults to event.category). Sequence queries also benefit from a tiebreaker field to resolve events that share the same timestamp.

The following examples use the detections API request format to show how EQL rules are defined. Each example is followed by a field-by-field breakdown.

This rule detects when msxsl.exe starts and then makes an outbound network connection from the same process instance, a known living-off-the-land binary (LOLBin) technique.

{
  "type": "eql",
  "language": "eql",
  "name": "MSXSL network connection after process start",
  "description": "Detects msxsl.exe starting and making an outbound network connection.",
  "query": "sequence by process.entity_id [process where event.type == \"start\" and process.name == \"msxsl.exe\"] [network where event.type == \"connection\" and network.direction == \"egress\"]",
  "index": ["winlogbeat-*", "logs-endpoint.events.*"],
  "severity": "high",
  "risk_score": 73,
  "interval": "5m",
  "from": "now-6m"
}
		
Field Value Purpose
type / language "eql" / "eql" Both must be "eql". Unlike custom query rules, the language field is fixed and not interchangeable.
query sequence by process.entity_id [process where ...] [network where ...] A two-step sequence. The by process.entity_id clause ensures both events came from the same process instance. The first bracket matches a process-start event for msxsl.exe, and the second matches an outbound network connection from that same process.
index ["winlogbeat-*", "logs-endpoint.events.*"] Covers Winlogbeat and Elastic Defend indices. Both must contain process and network events for the sequence to match.

This rule detects certutil.exe being used to download files and demonstrates the EQL-specific settings fields.

{
  "type": "eql",
  "language": "eql",
  "name": "File download via certutil",
  "description": "Detects certutil.exe being used to download files, a common LOLBin technique.",
  "query": "process where event.type == \"start\" and process.name == \"certutil.exe\" and process.args : \"-urlcache\"",
  "index": ["winlogbeat-*", "logs-endpoint.events.*"],
  "event_category_override": "event.category",
  "tiebreaker_field": "event.sequence",
  "timestamp_field": "@timestamp",
  "severity": "medium",
  "risk_score": 47,
  "interval": "5m",
  "from": "now-6m"
}
		
Field Value Purpose
query process where event.type == "start" and ... and process.args : "-urlcache" A single-event EQL query. The : operator performs a wildcard match on process.args, unlike the strict == equality used for other fields.
event_category_override "event.category" Specifies which field contains the event classification (such as process, file, network). Defaults to event.category. Override this when your data uses a different field name.
tiebreaker_field "event.sequence" A secondary sort field for events that share the same timestamp. Ensures deterministic event ordering in sequence queries.
timestamp_field "@timestamp" The field used for ordering events in sequences. Defaults to @timestamp. Different from the timestamp_override advanced setting, which controls the query time range.

The following settings are specific to EQL rules. For settings shared across all rule types, refer to Rule settings reference.

Index patterns or data view
The Elasticsearch indices or data view the rule searches when querying for events.
EQL query
The EQL query that defines the detection logic. Can be a single-event query, a sequence, or a sequence with missing events. Documents or sequences matching this query generate alerts.
EQL settings (optional)

Additional fields used by EQL search:

  • Event category field: The field containing event classification (such as process, file, or network). Typically a keyword family field. Defaults to event.category.
  • Tiebreaker field: A secondary field for sorting events in ascending, lexicographic order when they share the same timestamp.
  • Timestamp field: The field containing the event timestamp, used for ordering sequence events. Defaults to @timestamp. This is different from the Timestamp override advanced setting, which controls the query time range.
Suppress alerts by (optional)
Reduce repeated or duplicate alerts by grouping them on one or more fields. For details, refer to Alert suppression.
Required fields (optional)
An informational list of fields the rule needs to function. This does not affect rule execution.
Related integrations (optional)
Associate the rule with one or more Elastic integrations to indicate data dependencies and allow users to verify each integration's installation status.