feat(splunk): full Splunk REST integration (search, jobs, KV Store, events)

20 commands over the management port (8089) with token or basic auth:
SPL search (oneshot) as an ingestion source with an OCSF mapper for
notable/CIM findings; async search jobs (create/status/results); index
listing; event submission (receivers/simple + HEC); the complete KV Store
command set (collection create/config/delete, list, data list/add/delete,
entry search/delete/update); user list/delete; and a connectivity test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Guillaume BOURGEOIS
2026-06-26 16:08:58 +02:00
parent 76812ef128
commit dd1ca83d7d
22 changed files with 2046 additions and 0 deletions
+279
View File
@@ -0,0 +1,279 @@
id: splunk
name: Splunk
version: 1.1.0
description: "Splunk (REST API, management port 8089) — run SPL searches with notable/CIM finding ingestion and an OCSF mapper, manage search jobs, indexes and event submission (incl. HEC), full KV Store collection/entry management, and user administration. Token or basic authentication."
changelog: "1.1.0 — Full coverage: search jobs (create/status/results), indexes listing, event submission (receivers/simple + HEC), and the complete KV Store command set (collection create/config/delete, list, data list/add/delete, entry search/delete/update). 1.0.0 — Initial release: SPL search (oneshot) ingestion with a bundled OCSF mapper for notable/CIM events, get_users, delete_user and a KV Store entry update."
category: siem
# Per-instance configuration. The REST API lives on the Splunk management port (default 8089),
# NOT the web port. Token auth uses an authentication token (Settings → Tokens); basic auth
# uses a username + password. HEC fields are only needed for splunk-submit-event-hec.
config_schema:
properties:
host:
type: string
description: "Splunk server host or URL (e.g. splunk.example.com or https://splunk.example.com)"
port:
type: string
description: "REST management port (default 8089)"
default: "8089"
auth_type:
type: string
description: "Authentication method: token (Bearer authentication token) or basic (username + password)"
default: token
username:
type: string
description: "Username (basic auth only)"
password:
type: string
description: "Authentication token (token auth) or password (basic auth)"
x-soar-sensitive: true
app:
type: string
description: "Default app namespace for KV Store operations (default 'search')"
default: search
hec_url:
type: string
description: "HTTP Event Collector base URL for splunk-submit-event-hec (e.g. https://splunk.example.com:8088)"
hec_token:
type: string
description: "HTTP Event Collector token for splunk-submit-event-hec"
x-soar-sensitive: true
verify:
type: boolean
description: "Verify the server TLS certificate (default false; Splunk often uses self-signed certs)"
default: false
required:
- host
- password
# Documented for reference; the bundled scripts build the Authorization header themselves.
# token: Authorization: Bearer <token> basic: Authorization: Basic base64(user:pass)
auth:
- id: apikey
type: api_key
in: header
name: Authorization
value_template: "Bearer {{secret}}"
secret_field: password
commands:
# ── Ingestion / search ────────────────────────────────────────────────────
- id: search
name: splunk-search
description: "Run an SPL search (oneshot) and return the result rows. Use as an ingestion source by searching for notable events; results are under the 'results' array."
risk: read
inputs_schema:
properties:
query: { type: string, description: "SPL query (a leading 'search ' is added automatically if missing)" }
earliest: { type: string, description: "Earliest time (e.g. -24h, -7d@d, or an epoch); incremental fetch watermark" }
latest: { type: string, description: "Latest time (e.g. now)" }
limit: { type: number, description: "Maximum result rows (default 100)" }
app: { type: string, description: "App namespace to run the search in (defaults to the instance 'app' config)" }
required: [query]
outputs_schema: { properties: {} }
ingest:
results_path: results
dedup_key: event_id
incremental_field: earliest
# ── Search jobs ───────────────────────────────────────────────────────────
- id: job_create
name: splunk-job-create
description: "Dispatch an asynchronous search job and return its sid. Poll with splunk-job-status, then fetch with splunk-job-results."
risk: read
inputs_schema:
properties:
query: { type: string, description: "SPL query (a leading 'search ' is added automatically if missing)" }
earliest: { type: string, description: "Earliest time (e.g. -24h)" }
latest: { type: string, description: "Latest time (e.g. now)" }
app: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
required: [query]
outputs_schema: { properties: {} }
- id: job_status
name: splunk-job-status
description: "Return the status (dispatchState, doneProgress, resultCount) of a search job by sid."
risk: read
inputs_schema:
properties:
sid: { type: string, description: "Search job id" }
required: [sid]
outputs_schema: { properties: {} }
- id: job_results
name: splunk-job-results
description: "Fetch the results of a completed search job by sid."
risk: read
inputs_schema:
properties:
sid: { type: string, description: "Search job id" }
offset: { type: number, description: "Result offset (default 0)" }
limit: { type: number, description: "Maximum result rows (default 100; 0 = all)" }
required: [sid]
outputs_schema: { properties: {} }
# ── Indexes & event submission ────────────────────────────────────────────
- id: get_indexes
name: splunk-get-indexes
description: "List the indexes configured on the Splunk instance with their event counts and sizes."
risk: read
inputs_schema:
properties: {}
required: []
outputs_schema: { properties: {} }
- id: submit_event
name: splunk-submit-event
description: "Submit a single event to an index via the REST receivers/simple endpoint."
inputs_schema:
properties:
index: { type: string, description: "Target index name" }
event: { type: string, description: "Event payload (raw string)" }
sourcetype: { type: string, description: "Sourcetype to assign (optional)" }
source: { type: string, description: "Source to assign (optional)" }
host: { type: string, description: "Host to assign (optional)" }
required: [index, event]
outputs_schema: { properties: {} }
- id: submit_event_hec
name: splunk-submit-event-hec
description: "Submit an event through the HTTP Event Collector (HEC). Requires hec_url and hec_token in the instance config."
inputs_schema:
properties:
event: { type: string, description: "Event payload (string or JSON object as a string)" }
index: { type: string, description: "Target index (optional)" }
sourcetype: { type: string, description: "Sourcetype (optional)" }
source: { type: string, description: "Source (optional)" }
host: { type: string, description: "Host (optional)" }
fields: { type: object, description: "Indexed fields object (optional)" }
required: [event]
outputs_schema: { properties: {} }
# ── User management ───────────────────────────────────────────────────────
- id: get_users
name: splunk-get-users
description: "List Splunk users with their roles and metadata."
risk: read
inputs_schema:
properties: {}
required: []
outputs_schema: { properties: {} }
- id: delete_user
name: splunk-delete-user
description: "Delete a Splunk user by username."
inputs_schema:
properties:
username: { type: string, description: "Username to delete" }
required: [username]
outputs_schema: { properties: {} }
# ── KV Store: collections ─────────────────────────────────────────────────
- id: kv_store_collections_list
name: splunk-kv-store-collections-list
description: "List the KV Store collections defined in an app."
risk: read
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
required: []
outputs_schema: { properties: {} }
- id: kv_store_collection_create
name: splunk-kv-store-collection-create
description: "Create a new KV Store collection in an app."
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_name: { type: string, description: "Name of the collection to create" }
required: [kv_store_name]
outputs_schema: { properties: {} }
- id: kv_store_collection_config
name: splunk-kv-store-collection-config
description: "Define field types on a KV Store collection (e.g. field.name=string). Pass a JSON object mapping field name to type."
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_collection_name: { type: string, description: "Collection name" }
fields: { type: object, description: "Object mapping field name to type (string|number|bool|time|cidr)" }
required: [kv_store_collection_name, fields]
outputs_schema: { properties: {} }
- id: kv_store_collection_delete
name: splunk-kv-store-collection-delete
description: "Delete a KV Store collection and all of its data."
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_collection_name: { type: string, description: "Collection name to delete" }
required: [kv_store_collection_name]
outputs_schema: { properties: {} }
# ── KV Store: data ────────────────────────────────────────────────────────
- id: kv_store_collection_add_entries
name: splunk-kv-store-collection-add-entries
description: "Insert one or more entries into a KV Store collection (batch_save). Pass a JSON array of objects."
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_collection_name: { type: string, description: "Collection name" }
entries: { type: array, description: "Array of entry objects to insert" }
required: [kv_store_collection_name, entries]
outputs_schema: { properties: {} }
- id: kv_store_collection_data_list
name: splunk-kv-store-collection-data-list
description: "List all entries in a KV Store collection."
risk: read
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_collection_name: { type: string, description: "Collection name" }
limit: { type: number, description: "Maximum entries (default 0 = all)" }
required: [kv_store_collection_name]
outputs_schema: { properties: {} }
- id: kv_store_collection_data_delete
name: splunk-kv-store-collection-data-delete
description: "Delete ALL entries in a KV Store collection (the collection itself is kept)."
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_collection_name: { type: string, description: "Collection name" }
required: [kv_store_collection_name]
outputs_schema: { properties: {} }
- id: kv_store_collection_search_entry
name: splunk-kv-store-collection-search-entry
description: "Search entries in a KV Store collection with a Mongo-style query (JSON object)."
risk: read
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_collection_name: { type: string, description: "Collection name" }
query: { type: object, description: "Mongo-style query object, e.g. {\"name\": \"foo\"}" }
required: [kv_store_collection_name, query]
outputs_schema: { properties: {} }
- id: kv_store_collection_delete_entry
name: splunk-kv-store-collection-delete-entry
description: "Delete entries in a KV Store collection matching a Mongo-style query (JSON object)."
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_collection_name: { type: string, description: "Collection name" }
query: { type: object, description: "Mongo-style query object selecting entries to delete" }
required: [kv_store_collection_name, query]
outputs_schema: { properties: {} }
- id: kv_store_update_entry
name: splunk-kv-store-update-entry
description: "Update a single field of an existing KV Store entry by key, preserving the other fields."
inputs_schema:
properties:
app_name: { type: string, description: "App namespace (defaults to the instance 'app' config)" }
kv_store_collection_name: { type: string, description: "KV Store collection name" }
entry_key: { type: string, description: "The _key of the entry to update" }
field_name: { type: string, description: "Field to update" }
new_value: { type: string, description: "New value for the field" }
required: [kv_store_collection_name, entry_key, field_name, new_value]
outputs_schema: { properties: {} }
# ── Connectivity ──────────────────────────────────────────────────────────
- id: test_connection
name: splunk-test-connection
description: "Verify connectivity and credentials against the Splunk REST API (used by the Test button)."
risk: read
inputs_schema:
properties: {}
required: []
outputs_schema: { properties: {} }