Docs
DocumentationQuery ReferenceAPI Reference
Open Console→→
DocumentationQuery ReferenceAPI Reference

Platform overview

What is Axiom?QuickstartArchitectureFeatures
Fundamentals
Datasets
Edge deployments
Limits
Performance
Optimize usage
Requirements
Semantic conventions
Glossary
Tour
SecurityRoadmap

Send data

Reference architecturesMethods

Understand data

Console
Query
Builder
Editor
Query results
Visualize
Traces
Metrics
Correlations
Save queries
Stream
Dashboard
Create
Elements
Create
Configure
Element types
Gauge
Heatmap
Log stream
Monitor list
Note
Pie chart
Scatter plot
Statistic
Table
Time series
Sections
Configure
Filter
Annotate
Monitor
Overview
View status
Configure
Examples
Monitor types
Anomaly
Match
Threshold
Alerting
Overview
Configure
Notifier types
Custom Webhook
Discord
Email
Microsoft Teams
Opsgenie
PagerDuty
Slack
Manage
Datasets
Overview
Views
Virtual fields
Access
RBAC
Tokens
CLI
Organization
Audit log
Settings
Usage and billing
Profile
Extend
Overview
AWS Lambda
AWS PrivateLink
Cloudflare Workers
Cloudflare Logpush
Convex
Grafana
Hex
Netlify
Supabase
Tailscale
Terraform
Unkey
Vercel
Intelligence
Overview
Spotlight
AI agents
Overview
MCP Server
Overview
Tools
Query cost limits
Agent-created orgs
Skills
Overview
Axiom alerting
Build dashboards
Control costs
Query metrics
SRE
Translate SPL to APL
Splunk
Overview
Splunk app
Install and configure
Commands
Examples
Portal
How it works
Set up standard mode
Set up transparent mode
Observability Cloud
OCSF data
OCSF as CIM
SPL command support
Examples
Monitor and troubleshoot

Use cases

ObservabilityProduct analytics
OCSF security data
Overview
Send data
Query data
LLM observability
Overview
Use Axiom AI SDK
Manual instrumentation
GenAI attributes
Redaction policies

Miscellaneous

LLMs
Overview
List of docs pages
Full docs
Query reference
FAQs
Legal
Acceptable use policy
Cookies
Data processing
HIPAA
Partner agreement
Partner program guide
Privacy policy
SLA
Terms of service
Terms of use
Understand data/Splunk

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.

Rendering diagram…

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.

Info

In transparent mode, the Portal can also present an OCSF dataset as Splunk CIM data for CIM data models, tstats, and Enterprise Security searches. For more information, see Search OCSF data as Splunk CIM.

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:

SPL
index=ocsf | stats count by class_uid, class_name

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:

SPL
index=ocsf class_uid=3002 activity_id=1 status_id=2
| stats count by "user.name", "src_endpoint.ip"
| sort - count

Bytes by destination for network traffic over time:

SPL
index=ocsf class_uid=4001
| timechart span=1h sum("traffic.bytes") by "dst_endpoint.ip"

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):

SPL
index=ocsf class_uid=2004
| spath input=_raw path=observables{}.value output=observable
| mvexpand observable
| stats count by observable

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:

SPL
index=ocsf class_uid=2004
| spath input=_raw path=observables{}.value output=observable
| search observable="192.0.2.145"
| table _time, "device.hostname", "finding_info.title", observable

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:

SPL
index=ocsf class_uid=3002 "unmapped.device.os.name"="Windows Server 2022"
| stats count by "user.name"
SPL
index=ocsf class_uid=3002
| stats count by "unmapped.device.os.name"

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:

SPL
index=ocsf class_uid=2004
| spath input=_raw path=unmapped.PATH output=deep_field
| stats count by deep_field

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:

SPL
index=ocsf class_uid=2004
| spath input=_raw path=unmapped.evidences{}.process.name output=evidence_process
| stats count by evidence_process

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 example email.to{}.
  • Each attribute of an array of objects becomes a multivalue field named <array>{}.<attribute>, for example observables{}.value, attacks{}.technique.uid, and unmapped.evidences{}.process.name.

Failed logons, using the q syntax:

SPL
| axstats dataset="ocsf" q="class_uid=3002 activity_id=1 status_id=2" stats="count" by="user.name,src_endpoint.ip"

MITRE ATT&CK techniques in recent Detection Findings:

SPL
| axsearch dataset="ocsf" q="class_uid=2004" limit=1000
| stats count by "attacks{}.technique.uid", "device.hostname"

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:

SPL
| axquery apl="['ocsf'] | where class_uid == 2004 | mv-expand observables | where toint(observables['type_id']) == 2 | summarize count() by ip = tostring(observables['value'])"

For more information, see Commands.

Choose between the Portal and the app

Axiom Portal for SplunkAxiom for Splunk app
Address the datasetindex=ocsf, or index=federated:ocsf in standard modedataset="ocsf" in an ax command
Arrays of objects such as observablesOne JSON field. Extract elements with spathMultivalue fields such as observables{}.value
Arrays of scalar values such as email.toMultivalue field email.toMultivalue field email.to{}
Nested fields under unmappedDotted fields. Filter and aggregate in the base search, up to 8 segments below unmappedDotted fields. Filter inside Axiom with APL in axquery
Full APL, including map fieldsNoYes, with axquery

For a general comparison of the two integrations, see Axiom and Splunk.

What’s next

  • Search OCSF data as Splunk CIM
  • Query OCSF data with APL
  • SPL command support
  • Axiom for Splunk app commands
Was this page helpful?
Suggest edits on GitHub
PreviousView Axiom logs in Splunk Observability CloudNextSearch OCSF data as Splunk CIM
On this page
Search OCSF data with the PortalArrays of objectsFields in unmappedSearch OCSF data with the Axiom appChoose between the Portal and the appWhat’s next