--- title: "Splunk" description: "Connect Splunk so OpenSRE can search logs using SPL during investigations" --- OpenSRE queries Splunk using the REST API to surface relevant log evidence during alert investigations — searching indexes with SPL, correlating error patterns with incidents, and identifying root causes. ## Prerequisites - Splunk Enterprise or Splunk Cloud instance (version 8.x or later) - REST API access on port 8089 - A bearer token with search capability (see [Generating a Bearer Token](#generating-a-bearer-token)) ## Setup ### Option 1: Interactive CLI ```bash opensre integrations setup ``` Select **Splunk** when prompted and provide your REST API base URL and bearer token. ### Option 2: Environment variables Add to your `.env`: ```bash SPLUNK_URL=https://splunk.corp.com:8089 # REST API base URL (port 8089 default) SPLUNK_TOKEN=your-bearer-token # API bearer token (NOT an HEC token) SPLUNK_INDEX=main # Default index to search (optional) SPLUNK_VERIFY_SSL=true # Set false to skip SSL verification (optional) SPLUNK_CA_BUNDLE=/etc/ssl/certs/corp-ca.pem # Path to custom CA bundle (optional) ``` | Variable | Default | Description | | --- | --- | --- | | `SPLUNK_URL` | — | **Required.** REST API base URL including port | | `SPLUNK_TOKEN` | — | **Required.** Bearer token with search capability | | `SPLUNK_INDEX` | `main` | Default index searched when no index is specified in the alert | | `SPLUNK_VERIFY_SSL` | `true` | Set to `false` to disable SSL verification (dev/local only) | | `SPLUNK_CA_BUNDLE` | — | Path to a PEM CA bundle for enterprise self-signed certificates | ### Option 3: Persistent store ```json { "version": 1, "integrations": [ { "id": "splunk-prod", "service": "splunk", "status": "active", "credentials": { "base_url": "https://splunk.corp.com:8089", "token": "your-bearer-token", "index": "main", "verify_ssl": true, "ca_bundle": "/etc/ssl/certs/corp-ca.pem" } } ] } ``` ### Multi-instance setup To connect multiple Splunk instances (e.g. separate prod and staging clusters): ```bash SPLUNK_INSTANCES='[ {"name":"prod","tags":{"env":"prod"},"credentials":{"base_url":"https://splunk-prod:8089","token":"prod-token","index":"prod"}}, {"name":"staging","tags":{"env":"staging"},"credentials":{"base_url":"https://splunk-staging:8089","token":"staging-token","index":"staging"}} ]' ``` When `SPLUNK_INSTANCES` is set it overrides the single-instance `SPLUNK_URL` / `SPLUNK_TOKEN` variables. ## Generating a bearer token OpenSRE uses bearer tokens — not basic auth and not HEC tokens. To generate one: **Via the Splunk UI:** 1. Go to **Settings** → **Tokens** 2. Click **New Token** 3. Set a name (e.g. `opensre`) and an expiry date 4. Copy the generated token **Via the REST API** (replace `` with your admin password): ```bash curl -sk -u admin: \ https://splunk.corp.com:8089/services/authorization/tokens \ -X POST \ --data-urlencode "name=opensre" \ --data-urlencode "expires_on=+90d" \ --data-urlencode "output_mode=json" \ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['entry'][0]['content']['token'])" ``` The token needs the `search` capability. The `admin` role includes this by default. For a dedicated service account, ensure the role includes: - `search` - `read_splunkd_private_settings` (needed for the verify call against `/services/server/info`) ## Verify ```bash opensre integrations verify splunk ``` Expected output: ``` Service: splunk Status: passed Detail: Connected to Splunk 9.x.x ``` ## How queries are generated OpenSRE builds SPL queries deterministically from the alert payload — the LLM selects which tool to call but never writes the query itself. This keeps investigations reproducible and auditable. Query construction priority: | Priority | Source | Example | | --- | --- | --- | | 1 | `annotations.splunk_query` — verbatim SPL from your alert | `index=prod "PaymentTimeout" \| head 50` | | 2 | `annotations.query` or `annotations.log_query` | Any pre-populated query field | | 3 | `error_message` field — keyword search built automatically | `search index=main "NullPointerException" \| head 50` | | 4 | `alert_name` — last-resort keyword search | `search index=main "payments-error-spike" \| head 50` | | 5 | Fallback — index scan | `search index=main \| head 50` | To pass a specific SPL query through an alert, set `commonAnnotations.splunk_query`: ```json { "alert_name": "Payment service errors", "commonAnnotations": { "splunk_query": "index=prod sourcetype=app_logs \"NullPointerException\" | head 50" } } ``` ## Test with the built-in alert template ```bash opensre investigate --template splunk ``` This runs a synthetic investigation using a pre-built alert fixture — no live alert infrastructure needed. ## Troubleshooting | Symptom | Fix | | --- | --- | | `SSL: CERTIFICATE_VERIFY_FAILED` | Set `SPLUNK_CA_BUNDLE=/path/to/corp-ca.pem` (preferred) or `SPLUNK_VERIFY_SSL=false` (dev only) | | `HTTP 401 Unauthorized` | Token expired or was generated with the wrong account — regenerate | | `HTTP 403 Forbidden` | Token lacks `search` capability — check the role assigned to the token | | Empty search results | Data may not have been ingested yet, or the index name is wrong | | `Connection refused` on port 8089 | Splunk management port may be firewalled; confirm network access | | `opensre integrations verify` fails | Check `SPLUNK_URL` includes the protocol and port (`https://host:8089`) | ## Security best practices - Use a **read-only bearer token** — never use an admin token in production. - Store `SPLUNK_TOKEN` in `.env` or the credential store, not in source code or CI logs. - Prefer a dedicated `opensre` service account with only the `search` capability. - For enterprise self-signed certificates, set `SPLUNK_CA_BUNDLE` to the CA bundle path rather than disabling verification entirely. - Set `SPLUNK_VERIFY_SSL=false` only in local or dev environments when you cannot supply a CA bundle. - Rotate tokens on a schedule and revoke them when no longer needed.