--- description: Send the Report URI audit trail to Splunk HTTP Event Collector using a small relay to supply the Authorization header. --- # Splunk Splunk's HTTP Event Collector authenticates with a header - `Authorization: Splunk ` - 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. ```js 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: ```js 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](/security-operations/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 `event` field is where your data goes. Posting our payload at the top level instead produces an indexing error rather than an event. - The `sourcetype` decides how Splunk parses the body. `_json` is 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](https://help.splunk.com/en/splunk-enterprise/get-started/get-data-in/9.4/get-data-with-http-event-collector/set-up-and-use-http-event-collector-in-splunk-web) ## 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. [Start your free trial](https://report-uri.com/register/?plan=starter2025)