Elastic Security integration
The elastic.notify rule action writes a matched rule alert and its cited
fully qualified domain names (FQDNs) to an Elasticsearch data stream as an
Elastic Common Schema (ECS) document. It works with Elastic Cloud Hosted,
Elastic Cloud Serverless, and self-managed clusters that are reachable from
the public internet. Each rule controls which alerts are sent. Connecting
Elastic alone does not export alerts.
- Choose a data stream. The default,
logs-haveibeensquatted.finding-default, matches the built-inlogs-*-*index template, so Elasticsearch creates it on first write. - Create an API key limited to that data stream (see Least-privilege API key). Copy the Encoded value.
- In the app, open Connectors > Elastic Security.
- Enter the deployment or project Cloud ID, or select Elasticsearch endpoint URL and enter the HTTPS endpoint. Enter the data stream and the API key.
- Select Save to store the configuration.
- Select Test connection to verify the saved configuration and enable export.
- Open each intended rule in the rule editor. In the Response tab, select Add action > Notify Elastic Security and choose the configured destination. Save the rule and ensure it is enabled.
Test connection checks, through the
has privileges API,
that the key holds create_doc on the data stream. It does not write a
document, and it does not check that the data stream exists or can be created.
Saving does not test the connection. The saved connection remains inactive until Test connection succeeds. Save any configuration changes before testing. If a test fails, the configuration stays saved and export remains inactive.
The setup page does not display the saved API key. Leave the key blank to keep
it when updating the same endpoint. Changing the endpoint or Cloud ID requires
entering the key again. You can paste either the encoded key or its
id:api_key pair.
Least-privilege API key
Section titled “Least-privilege API key”Create the key in Kibana (Stack Management > API keys) or with the
create API key API.
Grant create_doc on the one data stream. Add auto_configure only when
Elasticsearch must create the data stream on first write. Without it, create
the data stream in advance.
POST /_security/api_key{ "name": "have-i-been-squatted", "role_descriptors": { "haveibeensquatted_writer": { "indices": [ { "names": ["logs-haveibeensquatted.finding-default"], "privileges": ["create_doc", "auto_configure"] } ] } }}The key needs no cluster privileges. create_doc only adds documents; it
cannot update, delete, or read them.
Network access
Section titled “Network access”Delivery originates from Cloudflare Workers that only reach public internet addresses. Elastic Cloud Hosted and Serverless endpoints work without further configuration. A self-managed cluster must expose its HTTPS REST endpoint on a public address, on port 443, 9200, or 9243, with a certificate valid for its host name. Private addresses, IP address endpoints, redirects, and paths such as reverse-proxy prefixes are rejected. A traffic filter or IP allowlist that admits only specific source addresses blocks delivery unless it permits Cloudflare’s IP ranges.
Delivery semantics
Section titled “Delivery semantics”An enabled elastic.notify action sends a matched rule alert only when the
Elastic connection is enabled and connected and its destination is enabled.
Each alert is written with the
bulk API
as one create operation whose _id is the rule alert ID (event.id).
- If the document already exists, Elasticsearch returns a version conflict, which is recorded as delivered. This deduplication holds only within one backing index: after a data stream rolls over, a replay of an older alert can write a second copy.
- When Elasticsearch throttles the request (HTTP 429, including a throttled bulk item), the document is resent once, after at most ten seconds.
- A mapping conflict or other rejected document, an authentication or authorization failure, and a missing data stream are recorded as failures and are not retried.
- If the request fails in transit or Elasticsearch returns a server error, the outcome is unknown and is not resent automatically.
Failures before delivery starts may be retried, but the connector makes no further attempts after delivery starts. A service interruption can therefore lose an export. Historical backfill and automatic replay are not available.
The setup page shows the last connection-test result, never provider response text or the API key.
Document format
Section titled “Document format”Each finding becomes one ECS document. url.domain and related.hosts hold
the alert’s cited FQDNs, and are omitted when the alert cites none.
event.severity and event.risk_score use Elastic Security’s severity bands:
informational 0, low 21, medium 47, high 73, critical 99. The unchanged
version 1 finding is kept under haveibeensquatted.
{ "@timestamp": "2026-09-24T12:00:00Z", "ecs": { "version": "8.17.0" }, "message": "Possible impersonation", "event": { "kind": "alert", "category": ["threat"], "type": ["indicator"], "id": "d16b752d-3d3b-4e72-bc6f-cfd12112f0b4", "action": "finding.created", "created": "2026-09-24T12:00:00Z", "module": "haveibeensquatted", "dataset": "haveibeensquatted.finding", "severity": 73, "risk_score": 73 }, "rule": { "id": "1af143cb-34dd-4cac-9c58-2aa0bbd181f0", "name": "Brand lookalike" }, "url": { "domain": ["login-example.test", "mail.login-example.test"] }, "related": { "hosts": ["login-example.test", "mail.login-example.test"] }, "observer": { "vendor": "Have I Been Squatted", "product": "Have I Been Squatted" }, "haveibeensquatted": { "schema_version": 1, "event_type": "finding.created", "finding": { "id": "d16b752d-3d3b-4e72-bc6f-cfd12112f0b4", "domain_id": "c2b351e1-7bd5-401d-9b42-5c3f3a17542b", "lookup_id": "1c5804dd-86ec-42c9-bce3-8b456c937936", "rule_id": "1af143cb-34dd-4cac-9c58-2aa0bbd181f0", "title": "Possible impersonation", "name": "Brand lookalike", "description": null, "level": "high", "alert_status": "active", "created_on_unix": 1790251200, "fqdns": ["login-example.test", "mail.login-example.test"] } }}The document sets no data_stream.* fields; Elasticsearch derives them from
the data stream name. finding.fqdns is resolved from the alert’s cited source
records as described in the Splunk guide.
A retrieval failure skips the Elastic action instead of reporting an empty
result.