Splunk cloud integration guide
Splunk Cloud integration guide
Splunk is a security information and event management (SIEM) product that is able to ingest events from multiple sources and provide real-time operational intelligence.
This guide can be used to send real-time identity and threat/anomaly events to Splunk Cloud. The technology used in this guide is a push-based event notification Web Hook.
Creating a Splunk Cloud Trial Account
This guide requires a Splunk Cloud account. If you have an account, skip this section.
-
-
You will receive an email containing the Splunk Cloud platform URL, username and a temporary password. Login with your username and password on the Splunk Cloud Platform URL and provide a new password when prompted.
Note
Trials are more limited, as expected, and the user experience may differ on Splunk. Also, you may need to include a proxy for trial endpoints. This is covered in the section below.
Configuring Splunk
-
Login with your Splunk Cloud account using your admin credentials.
-
Go to "Settings" -> "Data inputs".
-
Select the "HTTP Event Collector". Create a new token by clicking on "New Token".
-
Provide the new token name and source name override, and click on "Next".
-
Under "Input Settings", click on the "Select" tab, then choose
_jsonas the source type. Specify "Search and Reporting" for "App Context". Choose the appropriate index or create a new index.
-
Click on "Review" and then "Submit". Copy the token value, you will need to configure this on the Verify admin console.
-
Navigate back to "Settings" -> "Data Inputs" -> "HTTP Event Collector"
-
Select "Global Settings". Specify the default source type of
_json. Port "8088" is the default. You can specify a default index if needed.
-
You have now configured the HTTP event collector.
-
You can test the HTTP event collector (HEC) using a curl request as below. The URL used below will be used in the next section when configuring the webhook.
curl -k https://yourdomain.splunkcloud.com:8088/services/collector \ -H 'Authorization: Splunk <hec_token>' \ -d '{"event":"hello world", "sourcetype": "manual"}' -
In the navigation bar, under "Apps", click on "Search and reporting".
-
Search for
source="ibmwebhooks". You should see the newly created event.
For Splunk trials: Set up a proxy
Verify notification webhooks require the endpoint to have a valid certificate. Splunk Cloud trials do not use certificates with the hostname in the subject or in the subject alternative names.
You can use IBM Application Gateway or any other reverse proxy for this purpose. A sample resource_server configuration for IBM Application Gateway is as below.
resource_servers:
- path: /splunk
transparent_path: false
connection_type: ssl
identity_headers:
encoding: utf8_uri
basic_auth: ignore
ip_address: true
servers:
- host: yourinstance.splunkcloud.com
port: 8088
ssl:
certificate:
- "B64:LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNakNDQWhvQ0NRRHVnalhCOTBFRENEQU5CZ2txaGtpRzl3MEJBUXNGQURCL01Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1EwRXhGakFVQmdOVkJBY01EVk5oYmlCR2NtRnVZMmx6WTI4eER6QU5CZ05WQkFvTQpCbE53YkhWdWF6RVhNQlVHQTFVRUF3d09VM0JzZFc1clEyOXRiVzl1UTBFeElUQWZCZ2txaGtpRzl3MEJDUUVXCkVuTjFjSEJ2Y25SQWMzQnNkVzVyTG1OdmJUQWVGdzB5TXpFeU1ERXhNakkzTkRsYUZ3MHlOakV4TXpBeE1qSTMKTkRsYU1EY3hJREFlQmdOVkJBTU1GMU53YkhWdWExTmxjblpsY2tSbFptRjFiSFJEWlhKME1STXdFUVlEVlFRSwpEQXBUY0d4MWJtdFZjMlZ5TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFtM1E4CmVFbnFMeUFValVvcUlPUGgwaysvWEY5NjhtOEp3bTVNTDlEZU1UMGo0K1VwMHZ6VWtmUFJQMkZ4Sm5nM2kxRGUKTG9NOWtTZERkKytKWUJLSHR0ZDJJampRbjBtcFNGOVFmUU5DUEJRWVM2bnNrOVU4NjJOdnozYUQ4blVHeVBiMwpMaVkvMFh3YzhVNVpoTlk4MUhzc3p3bWlIRnpJdEkwVUZJRnF1dzFrL3V5bmdxdzRVU3ZFZHJ5bHhwemVpNWt6CjdqdjI2MzBhUVNtMEVOTGhsUmhLc24xNTJhK0Q5U2lmUk42b0VBcU15Mzk0WXVMZ0IydXkyOFYxa0d2RURpdEIKcXMvaWxBQ2U5Ui9sbjF3SURsYTg0QWZaV05MRGV0QmU1TXA2UmVoNWRhMHRCUGV3bGUwK3FDdTJIcjJIemtzRwoxUThTVm9UN0hqaDJuOTFaZXdJREFRQUJNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUJRMTJMY3Q4VUNLVVQ1CmFGTTdQV1RTdWR5eFpWNHZldFBjdjd2Yk51UzlVTVk1bTNyUE44WUxBQnBkT0ZKZVUvbVJTZzBBd2VlVDc5dFMKU2FQK2trbG1DbWVBMHF1eEt6amhPWHE1ZGV6cWFvNnVxU1ZxQ0IxY3FzbktpK2VZYmZRR2xac3ltaFNDUmFBcgpVQ2VHd2NHWUovcTVlZWoySWtnRGIrdWkyWjNDT3RsRUhYUnZJSnlTKzMrMjdnVFA2L2pFdnRuckxlZmtsekxECk9xZlAzRWdxYUNFbVVNQ2dsNWxVenNtTlI4cktSeEFLSjZpZlpTek5NRUlVbzRESXU2aENOOVFjbS9zQVRJUFYKRDM1M29RWHBQUFRCWDVlRVlmSUZRY2JGdkt1ako3RXI3TEZDL1Izd1pYN1FLNXExRkhLZzd0QUFXSHh3bWhGWgo2Ky9nazJGZgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t"
- "B64:LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURlakNDQW1JQ0NRQ05IQk44dGovRnd6QU5CZ2txaGtpRzl3MEJBUXNGQURCL01Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1EwRXhGakFVQmdOVkJBY01EVk5oYmlCR2NtRnVZMmx6WTI4eER6QU5CZ05WQkFvTQpCbE53YkhWdWF6RVhNQlVHQTFVRUF3d09VM0JzZFc1clEyOXRiVzl1UTBFeElUQWZCZ2txaGtpRzl3MEJDUUVXCkVuTjFjSEJ2Y25SQWMzQnNkVzVyTG1OdmJUQWVGdzB4TnpBeE16QXlNREkyTlRSYUZ3MHlOekF4TWpneU1ESTIKTlRSYU1IOHhDekFKQmdOVkJBWVRBbFZUTVFzd0NRWURWUVFJREFKRFFURVdNQlFHQTFVRUJ3d05VMkZ1SUVaeQpZVzVqYVhOamJ6RVBNQTBHQTFVRUNnd0dVM0JzZFc1ck1SY3dGUVlEVlFRRERBNVRjR3gxYm10RGIyMXRiMjVEClFURWhNQjhHQ1NxR1NJYjNEUUVKQVJZU2MzVndjRzl5ZEVCemNHeDFibXN1WTI5dE1JSUJJakFOQmdrcWhraUcKOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXpCOWx0VkVHazczUXZQbHhYdEEwcU1XL1NMRFFsUU1GSi9DLwp0WFJWSmRRc21jVzRXc2FFVHRlZVdaaDhBZ296TzFMcU9hM0k2VW1yV0xjdjRMbVVBaC9UM2laV1h6SExJcUZOCldMU1ZVKzJnMFhrbjQzeFNnUUVQU3ZFSzFOcVpSWnYxU1d2eDMrb0dIZ3UwM0FacnFUajBIeUx1anFVREFSRlgKc1J2QlBXL1ZmRGtvbUhqOWI4SXVLM3FPVXdRdElPVXIrb0t4MXRNMUo3Vk5ONU5mbEx3OU5kSHRsZmJsdzBZcwo1eEk1UXh1M3JjQ3hrS1F1d3o5S1JlNGlpak9JUk1BS1gyOHBiYWt4VTlOazM4QWMzUE5hZGdJazBzN1I4MjlrCjk4MHNxR1drZDA2K0MxN094Z2pwUWJ2TE9SMjBGdG1ReWJ0dFVzWEdSN0JwMDdZU3R3SURBUUFCTUEwR0NTcUcKU0liM0RRRUJDd1VBQTRJQkFRQ3hoUWQ2S1hQMlZ6SzJjd0FxZEs3NGJHd2w1V252c3lxZFBXa2RBTmlLa3NyNApaeWJKWk5mZGZSc28zZkEyb0sxUjhpNUNhOExLM1YvVXVBc1h2RzYvaWtKdFdzSjlqZitlWUxvdThsUzZOVkpPCnhETi9neFBjSHJoVG9HcWkxd2ZQd0RRck5Wb2ZaY3VRTmtsY2RnWjErWFZ1b3RmVENPWEhyUm9ObVpYK0hna1kKZ0V0UEcrcjFWd1NGb3dmWXF5RlhRNUNVZVJhM0pCNy9PYkYxNVdmR1VZcGxiZDN3UXovTTNQTE5LTHZ6NWExegpMTU5YRHdONVB2eWIyZXB5TzhMUEp1NGRHVEI0ak9HcFlMVWpHMVVVcUpvOU9hNkQ5OXJ2NnNJZCs4cWpFUnRsClpaYzFvYUMwUEtTekJtcStUcGJSMjdCOFpyYTNncG9BK2dhdmRSWmoKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ=="
Configuring Verify
-
Log into the Verify admin console (https://yourtenant.verify.ibm.com/ui/admin).
-
Navigate to "Integrations" -> "Notification webhooks".
-
Click on "Create webhook".
-
Specify all the compulsory fields to create a notification webhook.
- Specify a unique webhook name.
- In the URL field, enter the Splunk URL. This usually follows the patternhttps://yourdomain.splunkcloud.com:8088/services/collector. If you are using a proxy, use the proxy hostname and path.
- Choose "Header" as the "Authentication type".
- Enter "Authorization" as header name and specify the value asSplunk <token>. The Splunk token was generated in the previous section on Splunk Cloud.
-
Then click on "Next".
-
Now configure the events depending on your need. You can set some predefined events by clicking on "Add predefined events" section.
-
Consult the event payloads to craft a custom condition. The example here shows you how to send all tenant events to the SIEM tool.
-
Optional: Configure Webhook Transforms
Use Webhook transforms to modify the event payload before it's sent to the external endpoint. This capability is useful for removing sensitive data, restructuring the payload, or filtering specific attributes.
To add a transform, edit the saved webhook and go to Connection details> Transforms> Add Transform +
Test the transform rule by using the sample payloads as shown in the UI.
Transform Example 1: Basic Splunk-Optimized Event Format
{ "body": {}.put("event", body.data.put("time",double(body.time)/1000.0)).put("timestamp", body.time).put("sourcetype", "_json").put("time",double(body.time)/1000.0).put("host",body.tenantname) }Understanding Transform Example 1:
This transform restructures the payload to match Splunk's HTTP Event Collector (HEC) format with basic timestamp handling:
{ "body": {}.put(...) }- Creates a new structure with abodywrapper, then builds the Splunk-compatible structure inside it..put("event", body.data.put("time",double(body.time)/1000.0))- Maps the originaldataobject to Splunkâseventfield and adds atimefield. Thetimevalue is converted from milliseconds to seconds and stored as a numeric floatingâpoint number (usingdouble(...)in CEL)..put("timestamp", body.time)- Adds atimestampfield containing the original milliseconds timestamp (For example, 1768440335372)..put("sourcetype", "_json")- Sets the Splunk sourcetype to_jsonfor proper JSON parsing..put("time",double(body.time)/1000.0)- Converts the numeric milliseconds timestamp to seconds and stores it as a numeric floatingâpoint number (usingdouble(...)in CEL) for Splunk's time indexing (For example, 1768440335.372). Note that the value returned byint(now)represents the execution time of the CEL transform rather than the eventâs original generation time..put("host",body.tenantname)- Maps the tenant name to Splunk'shostfield for filtering and organization.
Before Transform:
{ "body": { "servicename": "profilemgmt", "tenantid": "f4f3c8f2-1e4a-4d65-9d4c-0f7ce0e0bd32", "tenantname": "test.data.com", "event_type": "management", "time": 1768440335372, "data": { "action": "modified", "cause": "The system modified the user \"jessica\".", "resource": "user", "result": "success", "target": "jessica", "targetid": "3230011AM9" } } }After Transform:
{ "body": { "event": { "action": "modified", "cause": "The system modified the user \"jessica\".", "resource": "user", "result": "success", "target": "jessica", "targetid": "3230011AM9", "time": 1768440335.372 }, "timestamp": 1768440335372, "sourcetype": "_json", "time": 1768440335.372, "host": "test.data.com" } }Why This Transform is Useful for Splunk:
- Proper Event Structure: The Splunk HEC fields (
event,time,host,sourcetype) are nested underbodywhich is the structure that is sent to Splunk. - Flexible Timestamp Formats: Provides both a numeric timestamp (for reference) and a double precision time value (for accurate indexing with millisecond precision).
- Sourcetype Definition: Setting
sourcetypeto_jsonensures that Splunk correctly parses the JSON structure. - Millisecond Precision: Using
double(body.time)/1000.0preserves millisecond precision (For example, 1768440335.372) rather than truncating to seconds. - Host-Based Filtering: Mapping
tenantnametohostallows easy filtering based on the value oftenantnamein Splunk searches. - Simple and Efficient: Minimal transformation overhead while maintaining Splunk compatibility.
Note: The webhook system will extract the
bodycontent when sending to Splunk, so Splunk receives the properly formatted HEC payload withevent,time,host, andsourcetypeat the top level.This format enables efficient Splunk queries like:
host="test.data.com"- Find all events from a specific tenant.sourcetype="_json"- Filter by JSON events.event.time>1768440000- Search by using the numeric time field within event data.- Time-based searches that use the
timefield with millisecond precision.
Transform Example 2: Removing fields from body and removing nested fields
{ "body": body.remove("servicename").remove("tenantid").put("data", body.data.remove("action")) }Understanding Transform Example 2:
The transform above performs the following operations on the outgoing webhook payload:
body.remove("servicename")- Removes theservicenameattribute from the top-level body..remove("tenantid")- Removes thetenantidattribute from the top-level body..put("data", body.data.remove("action"))- Modifies the nesteddataobject by removing theactionattribute from it, then replaces the originaldataobject with this modified version.
Before Transform:
{ "body": { "servicename": "verify-service", "tenantid": "abc123", "data": { "action": "login", "user": "john.doe" } } }After Transform:
{ "body": { "data": { "user": "john.doe" } } }
Transform Example 3: Creating a New Payload Structure
{ "body": {}.put("data", body.data).put("key", "Hello World!") }Understanding Transform Example 3:
This transform creates a completely new payload structure by starting with an empty object and selectively adding fields:
{}- Starts with an empty object, discarding all original top-level attributes..put("data", body.data)- Adds adatafield containing the original nesteddataobject from the source payload..put("key", "Hello World!")- Adds a new custom fieldkeywith the static value"Hello World!".
Before Transform:
{ "body": { "servicename": "verify-service", "tenantid": "abc123", "event_type": "authentication", "data": { "user": "john.doe", "status": "success" } } }After Transform:
{ "body": { "data": { "user": "john.doe", "status": "success" }, "key": "Hello World!" } }This approach is useful when you want to:
- Create a clean payload with only specific fields.
- Add custom metadata or identifiers to the payload.
- Completely restructure the event format for the receiving system.
- Discard all top-level attributes except those explicitly included.
Transform Example 4: Creating Custom Formatted Messages
{ "body": {}.put("data", body.data).put("key", "Hello World!").put("message", "Hello " + body.data.user + ", your authentication result was " + body.data.status + ".") }Understanding Transform Example 4:
This transform demonstrates how to create custom formatted messages by combining static text with dynamic data from the original payload:
{}- Starts with an empty object to create a clean structure..put("data", body.data)- Preserves the original nesteddataobject..put("key", "Hello:World")- Adds a static custom field..put("message", "Hello " + body.data.user + ", your authentication result was " + body.data.status + ".")- Creates a formatted message by concatenating:- Static text:
"Hello " - Dynamic value:
body.data.user(For example, "john.doe") - Static text:
", your authentication result was " - Dynamic value:
body.data.status(For example, "success") - Static text:
"."
- Static text:
Before Transform:
{ "body": { "servicename": "verify-service", "tenantid": "abc123", "event_type": "authentication", "data": { "user": "john.doe", "action": "login", "status": "success", "timestamp": "2026-01-20T01:15:00Z" } } }After Transform:
{ "body": { "data": { "user": "john.doe", "action": "login", "status": "success", "timestamp": "2026-01-20T01:15:00Z" }, "key": "Hello World!", "message": "Hello john.doe, your authentication result was success." } }Use Cases for Custom Formatted Messages:
- Human-Readable Summaries: Create easy-to-read event summaries for dashboards or alerts.
- Pre-Formatted Notifications: Generate message text that can be directly used in email or Slack notifications.
- Audit Trail Messages: Combine multiple fields into a single descriptive audit message.
- Search-Friendly Text: Create searchable text fields that combine multiple data points.
- Custom Logging: Format log messages according to specific organizational standards.
Additional Examples:
- User modification:
"User " + body.data.target + " was " + body.data.action + " by " + body.data.performedby_username - Access attempt:
"Access " + body.data.result + " for user " + body.data.user + " from " + body.data.origin - Resource change:
body.data.resource + " '" + body.data.target + "' " + body.data.action + " - Result: " + body.data.result
Note: While this example may not be essential for Splunk integration (since Splunk can perform similar operations at search time), it's valuable for:
- Systems that don't support complex query-time field manipulation.
- Reducing processing load on the receiving system.
- Creating standardized message formats across multiple integrations.
- Pre-formatting data for systems with limited query capabilities.
Common Transform Operations:
remove(attribute)- Removes an attribute from the object.put(key, value)- Adds or updates a key-value pair.body.attribute- Accesses nested attributes.{}- Creates an empty object (useful for starting fresh).int(now)- Returns the current Unix timestamp as an integer.- Chain multiple operations using dot notation.
Use Cases for Transforms:
- Data Privacy: Remove sensitive attributes like internal IDs, service names, or tenant identifiers before sending to external systems.
- Payload Optimization: Reduce payload size by removing unnecessary fields.
- Data Restructuring: Reorganize the event structure to match the external system's expected format.
- Attribute Filtering: Remove specific nested attributes while preserving the parent structure.
- Custom Metadata: Add static values or identifiers to help categorize or route events in the receiving system.
-
Edit the notification webhook you just created. Click on "Test Connection".
-
Click "Send Test". If the connection is successful, you will see the success message.
Note
Events synced to Splunk will only include the ones created after the integration has been configured. If there is an interest in historical events, you may make use of the Events API. However, the mechanism to add these events into Splunk will require a custom integration that is not covered in this guide.
Validating events received on Splunk Cloud
-
Re-login to your Splunk Cloud account and go to "Search and Reporting" section.
-
In the search field, use an appropriate criteria. Alternatively, use
**to see all the logs.
The steps below are optional and are meant to be a guide for you to add alerts from Splunk, if needed.
-
Save the search criteria and any alerts and triggers, as desired.
-
Select actions you would like to take.
-
Set the contact information and then click on "Save".
-
Now, when the selected events are received on Splunk, the email notification is sent.
Updated 22 days ago
