Skip to content

Elastic and OpenSearch

Works with: Elasticsearch 8 and 9 (self-managed or Elastic Cloud, including Elastic Security), OpenSearch 2 and 3 (including Amazon OpenSearch Service with a master user), and the Wazuh indexer.

SafeHanded writes with the _bulk API. Each event has a fixed document id (<org_id>-<seq>), so an event sent twice is stored once.

  1. Create an API key that can only write SafeHanded events. In Kibana → Dev Tools:

    POST /_security/api_key
    {
    "name": "safehanded",
    "role_descriptors": {
    "safehanded_writer": {
    "cluster": ["monitor"],
    "indices": [{ "names": ["logs-safehanded.audit-*"], "privileges": ["create_doc", "auto_configure"] }]
    }
    }
    }

    Copy the encoded value from the response. Kibana’s Stack Management → API keys works too, with the same role descriptor.

  2. Copy your Elasticsearch endpoint (Elastic Cloud: the deployment’s overview page).

  3. In SafeHanded: Settings → Integrations → Connect → Elastic / OpenSearch. Enter the URL, choose API key, paste the encoded key, and leave Index or data stream blank. Save, then Send test event.

Events go to the data stream logs-safehanded.audit-default, which Elasticsearch’s built-in logs template accepts. In Kibana, create a data view for logs-safehanded.audit-*. Each document has @timestamp set to when the event happened.

  1. Create an internal user, e.g. safehanded, with a role that has create_index, write and create_doc on the index pattern safehanded-audit*.
  2. In SafeHanded choose Username and password, and enter the cluster URL, the user, and safehanded-audit as the index.
  • Rejected the credentials (HTTP 401/403): wrong key or password, or the role lacks create_doc / auto_configure on the target.
  • The destination refused an event (mapper_parsing_exception …): an existing mapping on the index conflicts with SafeHanded’s fields. Use a new index or data stream name.
  • Re-sent events are stored once only while they land in the same index. After a data stream rolls over, a rare re-send can be stored twice. De-duplicate on org_id + seq if that matters.