﻿---
title: Indicator match rules
description: Detect security events that match known threat indicators from threat intelligence feeds.
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5498/solutions/security/detect-and-alert/indicator-match
products:
  - Elastic Cloud Serverless
  - Elastic Security
applies_to:
  - Serverless Security projects: Generally available
  - Elastic Stack: Generally available
---

# Indicator match rules
## Overview

Indicator match rules continuously compare field values in your security event indices against field values in threat indicator indices. When a match is found, an alert is generated, enriched with metadata from the matched indicator. This makes indicator match rules the primary mechanism for operationalizing threat intelligence feeds within Elastic Security.

### Limitations

Indicator match rules provide a powerful capability to search your security data; however, their queries can consume significant deployment resources. When creating an indicator match rule, limit the time range of the indicator index query to the minimum period necessary for the desired rule coverage. For example, the default indicator index query `@timestamp > "now-30d/d"` searches specified indicator indices for indicators ingested during the past 30 days and rounds the query start time down to the nearest day (resolves to UTC `00:00:00`). Without this limitation, the rule includes all of the indicators in your indicator indices, which may extend the time it takes for the indicator index query to complete.
<admonition title="Support restrictions">
  Indicator match rules have two additional constraints:
  - **Cold and frozen tier data is not supported** - Data in these tiers must be older than the rule's query time range. If your data has unreliable timestamps, exclude cold and frozen tier data using a Query DSL filter.
  - **Look-back time is limited to 24 hours** - Rules with an additional look-back time greater than 24 hours are not supported.
</admonition>


### When to use an indicator match rule

Indicator match rules are the right fit when:
- You maintain an index of **known threat indicators** (IP addresses, domains, file hashes, URLs) and want to detect when any of them appear in your event data.
- You need to compare fields across **two separate indices** (source events and threat intelligence).
- You want alerts automatically **enriched** with indicator metadata, such as threat type, confidence, and source feed.

Indicator match rules are **not** the best fit when:
- You need to join data from multiple sources with transformations, aggregations, or complex filtering. Use an [ES|QL rule](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5498/solutions/security/detect-and-alert/esql) with [`LOOKUP JOIN`](https://docs-v3-preview.elastic.dev/elastic/elasticsearch/tree/main/reference/query-languages/esql/commands/lookup-join) for more flexible cross-index queries.
- You need to detect event sequences or ordering. Use an [EQL rule](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5498/solutions/security/detect-and-alert/eql) instead.


### Data requirements

Indicator match rules require:
- **Source event indices** containing the security events you want to scan.
- **Indicator indices** containing threat intelligence data. Data in these indices must be [ECS compatible](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5498/reference/security/fields-and-object-schemas/siem-field-reference) and must contain a `@timestamp` field.


## Using value lists as indicator indices

You can use [value lists](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5498/solutions/security/detect-and-alert/create-manage-value-lists) as the indicator index. This is useful when you have a flat list of indicators (IPs, domains, hashes) that you want to match against without creating a full indicator index:
1. Upload a value list of indicators.
2. In the **Indicator index patterns** field, enter `.items-<{{kib}} space>` (the hidden index where value lists are stored).
3. In the **Indicator index query** field, enter `list_id : <your-list-name>`.
4. In **Indicator mapping**, set the **Indicator index field** to the list type (`keyword`, `text`, or `IP`).


## Annotated examples

The following examples use the [detections API](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5498/solutions/security/detect-and-alert/using-the-api) request format to show how indicator match rules are defined. Each example is followed by a breakdown of the indicator match-specific fields. For common fields like `name`, `severity`, and `interval`, refer to the [detections API documentation](https://www.elastic.co/docs/api/doc/kibana/group/endpoint-detection-engine-rules-api).

### IP-based indicator match

This rule matches outbound network connections against a threat intelligence feed of known malicious IP addresses.
```json
{
  "type": "threat_match",
  "language": "kuery",
  "name": "Network connection to known malicious IP",
  "description": "Matches outbound network events against a threat intelligence feed of malicious IPs.",
  "query": "event.category: \"network\" and network.direction: \"egress\"",
  "index": ["packetbeat-*", "filebeat-*", "logs-endpoint.events.*"],
  "threat_index": ["filebeat-threatintel-*"],
  "threat_query": "@timestamp >= \"now-30d\"",
  "threat_mapping": [
    {
      "entries": [
        {
          "field": "destination.ip",
          "type": "mapping",
          "value": "threat.indicator.ip"
        }
      ]
    }
  ],
  "threat_indicator_path": "threat.indicator",
  "severity": "critical",
  "risk_score": 99,
  "interval": "5m",
  "from": "now-6m"
}
```


| Field                   | Value                                                                  | Purpose                                                                                                                                                                                                       |
|-------------------------|------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type`                  | `"threat_match"`                                                       | Identifies this as an indicator match rule.                                                                                                                                                                   |
| `query`                 | `event.category: "network" and network.direction: "egress"`            | Filters source events to outbound network connections. Only these events are compared against indicators. Uses `"kuery"` or `"lucene"`, the same query languages available in custom query rules.             |
| `threat_index`          | `["filebeat-threatintel-*"]`                                           | The index patterns containing threat intelligence indicators.                                                                                                                                                 |
| `threat_query`          | `@timestamp >= "now-30d"`                                              | Limits indicator matches to indicators ingested in the past 30 days. Shorter windows reduce stale matches but may miss long-lived indicators. Longer windows increase coverage at the cost of execution time. |
| `threat_mapping`        | `[{ "entries": [{ "field": ..., "type": "mapping", "value": ... }] }]` | Maps `destination.ip` from source events to `threat.indicator.ip` in the indicator index. When values match, an alert is generated and enriched with indicator metadata.                                      |
| `threat_indicator_path` | `"threat.indicator"`                                                   | The field path prefix for indicator data in the indicator index. Defaults to `threat.indicator`. Override when your indicator data uses a different field structure.                                          |


### File hash match with AND logic and performance tuning

This rule matches file creation events against threat intelligence by both SHA-256 hash and file name, requiring both fields to match. Performance tuning fields control parallelism and batch size.
```json
{
  "type": "threat_match",
  "language": "kuery",
  "name": "Known malware file hash detected",
  "description": "Matches file creation events against threat intelligence by SHA-256 hash and file name.",
  "query": "event.category: \"file\" and event.type: \"creation\"",
  "index": ["logs-endpoint.events.*", "winlogbeat-*"],
  "threat_index": ["filebeat-threatintel-*"],
  "threat_query": "@timestamp >= \"now-30d\"",
  "threat_mapping": [
    {
      "entries": [
        {
          "field": "file.hash.sha256",
          "type": "mapping",
          "value": "threat.indicator.file.hash.sha256"
        },
        {
          "field": "file.name",
          "type": "mapping",
          "value": "threat.indicator.file.name"
        }
      ]
    }
  ],
  "concurrent_searches": 5,
  "items_per_search": 500,
  "severity": "critical",
  "risk_score": 99,
  "interval": "5m",
  "from": "now-6m"
}
```


| Field                       | Value                     | Purpose                                                                                                                                                                                          |
|-----------------------------|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `threat_mapping[0].entries` | Two entries in one object | Multiple entries within a single `entries` object are combined with AND logic, so both the SHA-256 hash and file name must match. Separate `entries` objects (sibling array items) use OR logic. |
| `concurrent_searches`       | `5`                       | The number of indicator searches to run in parallel. Increasing this value can speed up rule execution for large indicator indices at the cost of higher resource usage.                         |
| `items_per_search`          | `500`                     | The number of indicators to include in each search request. Larger batches reduce the total number of searches but increase per-search memory usage.                                             |


## Indicator match rule field reference

The following settings appear in the **Define rule** section when creating an indicator match rule. For settings shared across all rule types, refer to [Rule settings reference](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5498/solutions/security/detect-and-alert/common-rule-settings).
<definitions>
  <definition term="Source">
    The index patterns or data view that store your source event documents. Prepopulated with indices from the [default Elastic Security indices](/elastic/docs-content/pull/5498/solutions/security/get-started/configure-advanced-settings#update-sec-indices) advanced setting.
  </definition>
  <definition term="Custom query">
    The query and filters used to retrieve source event documents. Field values in matching documents are compared against indicator values according to the threat mapping. Defaults to `*:*` (all documents).
  </definition>
  <definition term="Indicator index patterns">
    The index patterns that store threat indicator documents. Prepopulated with indices from the [`securitySolution:defaultThreatIndex`](/elastic/docs-content/pull/5498/solutions/security/get-started/configure-advanced-settings#update-threat-intel-indices) advanced setting.
  </definition>
  <definition term="Indicator index query">
    The query used to retrieve indicator documents. Defaults to `@timestamp > "now-30d/d"`, which searches for indicators ingested in the past 30 days.
  </definition>
  <definition term="Indicator mapping">
    Threat mapping conditions that compare values in source event fields with values in indicator fields. Configure:
    - **Field**: A field from your source event indices.
    - <applies-to>Elastic Stack: Generally available since 9.2</applies-to> **MATCHES / DOES NOT MATCH**: Whether the values should match or not match. At least one `MATCHES` entry is required.
    <note>
      Define matching (`MATCHES`) conditions first, then narrow down your results by adding `DOES NOT MATCH` conditions to exclude field values you want to ignore. Mapping entries that only use `DOES NOT MATCH` are not supported. At least one entry must have a `MATCHES` condition.
    </note>
    - **Indicator index field**: A field from your threat indicator index.
    Multiple mapping entries can be combined with `AND` and `OR` clauses. Only single-value fields are supported.
  </definition>
  <definition term="Indicator prefix override (optional)">
    Define the location of indicator data within the structure of indicator documents. When the indicator match rule executes, it queries specified indicator indices and references this setting to locate fields with indicator data. This data is used to enrich indicator match alerts with metadata about matched threat indicators. The default value for this setting is `threat.indicator`.
    <important>
      If your threat indicator data is at a different location, update this setting accordingly to ensure alert enrichment can still be performed.
    </important>
  </definition>
  <definition term="Suppress alerts (optional)">
    Reduce repeated or duplicate alerts. For details, refer to [Alert suppression](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/5498/solutions/security/detect-and-alert/alert-suppression).
  </definition>
</definitions>