Search OCSF data from Splunk
Learn how to search OCSF security data stored in Axiom from Splunk, using the Axiom Portal for Splunk or the Axiom for Splunk app.
An OCSF dataset in Axiom is an ordinary Axiom dataset, so both Splunk integrations search it like any other dataset. Analysts search OCSF events with SPL from the Splunk interface they already know, and pushed-down filters and aggregations run inside Axiom. This page covers the last step of the OCSF flow: searching OCSF data from Splunk.
The examples on this page use a dataset named ocsf that contains events conformed to the Axiom OCSF schema. Replace ocsf with the name of your dataset.
Search OCSF data with the Portal
Through the Axiom Portal for Splunk, the OCSF dataset is an index like any other: index=federated:ocsf in standard mode, or index=ocsf in transparent mode. The following examples use transparent mode.
Events carry the native OCSF fields under their dotted names, such as class_uid, user.name, and src_endpoint.ip. Dotted field names take double quotes in SPL, as on any Splunk index. In where and eval expressions, use single quotes instead, for example 'user.name'.
Count events by OCSF class:
Failed logons by user and source address. In the Authentication class (3002), activity_id 1 is a logon and status_id 2 is a failure:
Bytes by destination for network traffic over time:
Filters and aggregations like these are computed inside Axiom. For the full list of what runs in Axiom and what runs on the search head, see SPL command support.
As with any OCSF query, filter on the numeric *_id fields rather than their display strings. The IDs are fixed by OCSF, while producers spell the strings differently.
Arrays of objects
Promoted arrays of objects, such as observables, attacks, and vulnerabilities, arrive as one field that contains the array as compact JSON. Arrays of scalar values, such as email.to, arrive as ordinary Splunk multivalue fields.
To work with the elements of an array of objects, extract them with spath. spath returns a multivalue field, which you can expand with mvexpand. For example, list the IP address observables in Detection Findings (2004):
spath and mvexpand run on the search head over the events Axiom returns, so filter the search first, for example by class_uid, to keep the number of events small. A search-time filter on an element, such as observables{}.value=192.0.2.145, matches nothing, because the field only exists after spath runs. Filter after spath instead:
Fields in unmapped
Fields stored under the unmapped map field appear in events as dotted fields that start with unmapped., for example unmapped.device.os.name. You can use them in the base search like any other field. Filters, stats ... by, top, and timechart on them run inside Axiom:
Base-search filters and aggregations work for paths up to 8 segments below unmapped. For example, unmapped.device.os.name is 3 segments below unmapped. For a deeper path, the search returns an error instead of results. Extract deeper fields with spath instead:
Replace PATH with the path of the field below unmapped. spath runs on the search head over the events Axiom returns, so narrow the base search first, for example by class_uid and time range.
An array inside unmapped, such as unmapped.evidences, behaves like a promoted array of objects: you can’t filter or aggregate on its elements in the base search. To read its elements, extract them with spath:
Search OCSF data with the Axiom app
The Axiom for Splunk app queries the dataset by name with its ax commands, and returns OCSF fields as Splunk fields.
In version 1.2.0 and later, the app names array fields the same way Splunk’s spath command does, so you don’t need spath for arrays:
- Nested objects become dotted field names, for example
src_endpoint.ip. - An array of scalar values becomes a multivalue field whose name ends in
{}, for exampleemail.to{}. - Each attribute of an array of objects becomes a multivalue field named
<array>{}.<attribute>, for exampleobservables{}.value,attacks{}.technique.uid, andunmapped.evidences{}.process.name.
Failed logons, using the q syntax:
MITRE ATT&CK techniques in recent Detection Findings:
axsearch returns at most limit events, and stats runs on the search head over them, so these counts cover only the returned events.
For exact counts over the whole dataset, and for the full APL language, including map fields and arrays, run an APL query with axquery:
For more information, see Commands.
Choose between the Portal and the app
| Axiom Portal for Splunk | Axiom for Splunk app | |
|---|---|---|
| Address the dataset | index=ocsf, or index=federated:ocsf in standard mode | dataset="ocsf" in an ax command |
Arrays of objects such as observables | One JSON field. Extract elements with spath | Multivalue fields such as observables{}.value |
Arrays of scalar values such as email.to | Multivalue field email.to | Multivalue field email.to{} |
Nested fields under unmapped | Dotted fields. Filter and aggregate in the base search, up to 8 segments below unmapped | Dotted fields. Filter inside Axiom with APL in axquery |
| Full APL, including map fields | No | Yes, with axquery |
For a general comparison of the two integrations, see Axiom and Splunk.