Splunk
Splunk's HTTP Event Collector authenticates with a header - Authorization: Splunk <token> - and that is the only method its documentation offers. There is no query-string parameter and no Basic authentication alternative, so HEC cannot be a direct webhook target.
The fix is a relay: a few lines of code that receive our POST, add the header, and forward the body to HEC. This page uses a Cloudflare Worker, but the pattern is identical on a Lambda Function URL, an Azure Function or anything else that can receive an HTTP request.
The same relay works for anything else that authenticates by header - Elasticsearch with an API key, Google SecOps, Grafana Cloud, Opsgenie. Only the destination URL and the header change.
How it fits together
Report URI ──POST──▶ Relay ──POST + Authorization──▶ Splunk HEC
(URL only) (header added here)
The relay
Deploy this as a Cloudflare Worker. The HEC token is stored as a secret in the Worker, never in a URL.
export default {
async fetch(request, env) {
if (request.method !== 'POST') {
return new Response('Method not allowed', { status: 405 })
}
if (request.headers.get('x-relay-key') !== env.RELAY_KEY) {
return new Response('Forbidden', { status: 403 })
}
const event = await request.json()
return fetch(env.HEC_URL, {
method: 'POST',
headers: {
'Authorization': `Splunk ${env.HEC_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
sourcetype: '_json',
source: 'report-uri',
event,
}),
})
},
}
Set HEC_URL (your collector endpoint, ending /services/collector/event), HEC_TOKEN and RELAY_KEY as Worker secrets.
Locking the relay down
An open relay that forwards anything into your SIEM is a liability, so the Worker above rejects requests without a shared key. Our webhook cannot send that header either, so put the key in the URL as a query parameter and check it there instead:
const url = new URL(request.url)
if (url.searchParams.get('k') !== env.RELAY_KEY) {
return new Response('Forbidden', { status: 403 })
}
Then use https://your-worker.workers.dev/?k=LONG_RANDOM_VALUE as the webhook target. Generate the value randomly and treat it as a credential - it appears in your Report URI audit trail, since we record the target of every delivery attempt.
Sending the audit trail to it
Paste the Worker URL into the Audit Trail webhook field - Account Settings for a personal account, or the Teams page for a team. See Audit Trail for the payload reference.
Things to watch for
- Return the upstream status. We retry on a non-2xx response and stop after five attempts. A relay that always returns 200 turns a Splunk outage into silent data loss; returning HEC's own status lets our retries do their job.
- HEC's
eventfield is where your data goes. Posting our payload at the top level instead produces an indexing error rather than an event. - The
sourcetypedecides how Splunk parses the body._jsonis right for our payload; leaving it unset gives you a single unparsed string. - If your Splunk is not internet-facing, the relay has to run somewhere that can reach it - a Worker cannot, but a function inside your own network can.
Official documentation
Splunk - Set up and use HTTP Event Collector
Start Monitoring with Report URI
Already using us? Deploy the relay, then paste its URL into the Audit Trail webhook field.
New to Report URI? The Audit Trail webhook is available on Business and Enterprise plans.