Introduction
BabySOARus runs sandboxed code over Splunk events. You write a few lines of Python in the search bar, or drop in a compiled WebAssembly component, and it runs against every event flowing through the pipeline.
index=proxy
| exec inline="for e in events: e['host_upper'] = e['dest_host'].upper()"

That much you could do with eval. The point of BabySOARus is everything eval
cannot do: loops, dictionaries, entropy calculations, statistics, JSON
parsing, outbound HTTP calls, and the parts of the Python standard library you
already know, all inside a sandbox that cannot touch the host.
Why It Exists
Splunk's own extension points make you choose between two bad options.
SPL is fast and safe, but it is not a programming language. Expressing
"work out the standard deviation of the gaps between these timestamps, and
score how regular they look" in eval is possible and nobody enjoys reading
the result.
Custom search commands give you a real language, but Splunk starts a fresh operating system process for every search. The interpreter boots, imports its libraries and shuts down again, for every single search, and you pay that before your code does any work. Teams end up avoiding them.
BabySOARus keeps the real language and removes the startup cost. A background daemon holds one WebAssembly engine and a pool of interpreters that are already warmed up. A search connects to it over a Unix socket and starts streaming events immediately.
| What happens | Process-per-search | BabySOARus |
|---|---|---|
| Engine construction | every search | once per host |
| Interpreter startup | every search | once per pooled instance |
| Compiling your snippet | every batch | once per search |
| Overhead of a warm search | seconds | microseconds |
| Time to first result | after a 50,000-event buffer | after 32 events |
The performance chapter explains where the time goes and how to measure it on your own hardware.
What You Get
A real language in the search bar. Loops, comprehensions, try/except,
json, re, hashlib, statistics, ipaddress, datetime, and the rest
of the standard library.
Outbound HTTP. Enrich against threat intelligence, look up an asset owner, call the Splunk REST API, post to a case management system. From the search bar, without an add-on.
Compiled functions when you need speed. Ship a .wasm component built
from Rust, Go, or any language that targets the component model. Drop it in a
directory and it is callable before your next search, with no restart.
A sandbox you can reason about. Guest code gets no sockets, no filesystem beyond the lookup directories you expose, no environment variables and a hard execution deadline. It is a WebAssembly component, not a subprocess.
The same code in three places. A search, a scheduled alert action, and a generating command all run the identical guest. What you prototype interactively is what runs on a schedule.
Where It Fits
Detection engineers use it to express logic that SPL makes awkward: entropy, beaconing intervals, sequence analysis, decoding nested payloads.
![]()
Threat hunters use it to iterate. Change five characters, press enter, see the result. No app to package, no restart, no deployment.
Incident responders use it as the glue that would otherwise require a SOAR platform: enrich, decide, call an API, all triggered by a scheduled search. See Replacing SOAR workflows.
And increasingly, AI agents use it as their execution surface, because "generate a short Python snippet and run it over these events" is a far more reliable thing to ask a model for than "generate correct SPL". See AI agents.
Getting Started
- Installation takes about five minutes.
- Your first search is a one-liner.
- A tour in five searches covers most of what you will ever need.
If you would rather read code, the app ships thirty-one library entries -- detections, hunts, enrichment, response actions, lookup builders -- and every one is readable source in the editor: open the file tree and the built-ins are all there.