Skip to content
Integrations
Skip navigation

Enterprise Security Integration

Splunk ES compatibility: threat-intel collections and what blocks them populating, adaptive response, CIM aliases, and corrected detections.

Published Last updated

On this page (10)

Enterprise Security Integration Documentation

The Whisper Security Add-on is Splunk-ES-compatible but does not ship a prebuilt correlation-search pack. What it gives ES is two Threat Intelligence KV Store collections, an Enrich with Whisper adaptive response action, CIM-compliant field aliases on whisper:enrichment events, and graph-query macros you can call from your own detections. This page covers what you switch on, and how to build a detection on top of it.

What ships

Read coverage before band. Only known-clean — coverage: known-clean. In coverage, no malicious evidence. licenses the word "clean"; no-data — coverage: no-data. Not in coverage. This is not a verdict — nothing was looked at. means unknown, which is a different thing again; malicious-evidenced — coverage: malicious-evidenced. In coverage, with positive evidence of malice. and ambiguous — coverage: ambiguous. In coverage, and the evidence points both ways. mean there is evidence, whatever the band says. Full contract: Coverage — what we looked at.

Threat Intelligence framework integration

The ES Threat Intelligence framework consumes KV Store collections that match the ES ip_intel and domain_intel schemas. The add-on ships two, whisper_ip_intel and whisper_domain_intel. Each is written either by a populator search in savedsearches.conf or by the whisper_threat_intel modular input, and the two writers key their records differently, so a detection that filters on one will not see records written by the other. Neither collection fills on its own in this release: both populator searches are refused before they return rows, so the feeds do not appear in ES.

To enable the populators, in Splunk:

  1. Go to Settings > Searches, Reports, and Alerts.
  2. Filter on app = TA-whisper-graph.
  3. Edit Whisper - Populate IP Threat Intel KV Store and Whisper - Populate Domain Threat Intel KV Store -- set Enabled = true and pick a schedule (the default 0 */6 * * * runs every 6 hours).
  4. In ES, confirm the feeds appear under Configure > Data Enrichment > Threat Intelligence Management.

Enrich with Whisper adaptive response action

alert_actions.conf ships the [whisper_enrich] custom alert action, backed by whisper_adaptive_response.py. It lets an ES analyst, or a correlation search, enrich an indicator on demand and write the result back onto the notable event.

From a notable event:

  1. Open the notable in Incident Review.
  2. Actions > Run Adaptive Response > Enrich with Whisper.
  3. The action pulls candidate indicators from src, dest, src_dns, and dest_dns on the notable, calls the WhisperGraph, and adds the enrichment result as a comment on the notable.

From a correlation search, attach action.whisper_enrich = 1 to the saved search to fire the enrichment automatically on each triggered result.

CIM field aliases on enrichment events

props.conf aliases Whisper-prefixed fields on whisper:enrichment events to CIM field names, so notable events, RBA rules and ES dashboards correlate without custom extractions. The events are tagged network resolution dns, so they participate in the Network Resolution and DNS CIM data models; whisper:threat_intel and whisper:watchlist events are tagged threat report for Threat Intelligence. The alias table is on CIM Mapping.

Templates and macros

savedsearches.conf ships four disabled enrichment pipeline templates under the Example - Whisper - ... prefix. Clone one, replace its <source_index>, <source_sourcetype>, <destination_index> and <indicator_field> placeholders, and enable it. The templates are listed on Saved Searches.

macros.conf ships nine whisper_* macros you can reuse inside detections, dashboards or RBA rules to keep SPL short. They are query helpers, not correlation-search thresholds, and every one is parameterised -- the substitution flows into the params argument of whisperquery, so nothing is interpolated into the Cypher query. Each macro, with its arguments, is on Macros.

Building your own detections

The recipe for a Whisper-powered ES detection: pick the index whose events carry the indicator, clone one of the example templates, add Whisper context with whisperlookup or a whisper_* macro, then put your condition in a where clause on whisper_risk_score, whisper_threat_level, one of the whisper_is_* flags, or a graph-traversal result. Write the match to index=risk for RBA or to index=notable. Schedule it disabled and tune it against historical data before you enable it.

Worked example -- multi-feed threat IP communication

Goal: flag internal hosts talking to IPs appearing on multiple distinct threat feeds.

spl
index=<firewall_index> sourcetype=<firewall_sourcetype> earliest=-15m action=allowed
| rename dest_ip AS indicator
| dedup src_ip indicator
| `whisper_explain(indicator)`
| spath sources{}.feedId output=feeds
| eval feed_count=mvcount(feeds)
| where feed_count >= 2
| eval risk_score=case(feed_count >= 4, 80, feed_count >= 2, 50, 1=1, 0)
| eval risk_message="Whisper: destination IP listed on " . feed_count . " threat feeds"
| eval risk_object=src_ip, risk_object_type="system"
| collect index=risk sourcetype=whisper:risk

CALL explain() returns its feed evidence in a column called sources, an array of objects each carrying feedId, weight, firstSeen and lastSeen. Extract sources{}.feedId rather than sources{} so mvcount counts feeds and not objects. Verified against production on 2026-08-09.

The >= 2 minimum feed count is the detection threshold -- change it inline.

Alerting on the risk score alone

Every whisperlookup result already carries whisper_risk_score and whisper_risk_level, so an RBA rule can trigger on the score without a detection of your own:

spl
index=<source_index> sourcetype=<source_sourcetype> earliest=-15m
| rename <indicator_field> AS indicator
| dedup indicator
| whisperlookup field=indicator
| where whisper_risk_score >= 60
| eval risk_score=whisper_risk_score
| eval risk_message="Whisper risk " . whisper_risk_level . " (" . whisper_risk_factors_list . ")"
| eval risk_object=indicator, risk_object_type=if(whisper_indicator_type=="ip", "system", "other")
| collect index=risk sourcetype=whisper:risk

The factor weights in lookups/whisper_risk_factors.csv, and the full factor list, are on the Enrichment page.

What the add-on sends

Whisper commands send the indicator you look up — a hostname, IP address, ASN or CIDR — to graph.whisper.security over HTTPS, with this add-on's version and a random installation identifier. Your event data, field values, user names and search text are never sent. Scheduled use: a search you schedule keeps sending on that schedule, unattended, under this acknowledgement. See the Privacy Policy and the Terms & Conditions.

Where this runs

Install the add-on on the ES search head, or the ES search head cluster: the adaptive response action and the populator searches run there. Confirm whisper_user is imported into the ES roles your analysts use, so they can run whisperlookup and whisperquery from the ES search bar. Shipping the add-on to a distributed environment is on Deployment Architecture.