Security operations · Splunk · Elastic · Graylog

SaaS security alerts in your SIEM without opening a port

Okta, CrowdStrike, GitHub and your other security tools post their alerts to one public Webhook Relay URL. A relay agent inside your network connects out and delivers each one to Splunk HEC, Logstash or Graylog. The SIEM keeps no public address, and every alert is stored and retried until it lands.

Free plan · No credit card · SOC 2 Type II · Self-hosted option

Buying for a company? Talk to sales

One public URL in. One outbound connection out. Nothing else exposed.

Safe on company infrastructure

  • Outbound only

    The agent or operator connects out over TLS. No inbound port, no public IP.

  • Encrypted and scoped

    AES-256 at rest. Ephemeral buckets store no bodies or headers at all.

    Data handling →

  • Verified before forwarding

    Signatures checked and source IPs allowlisted on the input, so forged requests never reach you.

    Signatures →IP allowlist →

  • SOC 2 Type II

    Independently audited controls, SSO and audit logs.

    Security review kit →

Your SIEM is the last thing to expose

It holds every log you have. Alerts should reach it without making it a target.

Exposing your SIEM to SaaS

  • Publish a HEC or HTTP input to the internet
  • Allow-list every vendor's changing source addresses
  • Lose alerts while the indexer restarts
  • Get an inbound firewall rule to the SIEM approved

With Webhook Relay

  • The agent makes one outbound connection
  • Nothing new is reachable from the internet
  • Alerts are stored and retried for up to 30 days
  • Signatures checked before anything enters your network

No inbound path to the SIEM

The relay agent connects out over TLS. Vendors only ever talk to the Webhook Relay URL, so the indexer has no public address to scan.

No gaps during maintenance

Every alert is stored on arrival. With durable delivery it is retried for up to 30 days, so an indexer restart or upgrade doesn't lose detections.

Forward only what you trust

Check each vendor's HMAC signature or token in a function and drop anything unsigned. Add the HEC token in the same function, so it never leaves your account.

Works with the tools that send alerts

Anything that can POST JSON to an HTTPS URL. A few common ones:

  • Okta event hooks

    Sign-in, MFA and admin events. The one-time verification challenge can be answered by a function on the input.

  • CrowdStrike Falcon

    Detections and workflow notifications sent through a webhook action.

  • GitHub security events

    secret_scanning_alert, code_scanning_alert and dependabot_alert webhooks, signed with X-Hub-Signature-256.

  • Snyk, Wiz and others

    Any scanner or posture tool with a webhook integration.

Delivered to the collector you already run

Point the bucket's output at the collector's internal address.

  • Splunk HTTP Event Collector

    A function adds Authorization: Splunk <token> from a config variable.

    http://splunk.internal:8088/services/collector/raw
  • Elastic (Logstash http input)

    The http input plugin, then your usual pipeline into Elasticsearch.

    http://logstash.internal:8080
  • Graylog GELF HTTP

    A GELF HTTP input, with a function that maps the payload to GELF fields.

    http://graylog.internal:12201/gelf
  • Fluent Bit

    The http input, routing to any output Fluent Bit supports.

    http://fluent-bit.internal:9880

Signature verification

Check signatures before alerts enter your network

A Webhook Relay function runs on the input, before forwarding. This one verifies GitHub's X-Hub-Signature-256; change the header name and prefix for other vendors. Unsigned or tampered requests get a 401 and never reach the agent.

How signature verification works
function (Lua) · runs before forwarding
local crypto = require('crypto')

-- Reject anything that isn't signed with your shared secret,
-- before it is forwarded into your network.
local sig, err = crypto.hmac('sha256', r.RequestBody, cfg:GetValue("WEBHOOK_SECRET"))
if err then error(err) end

if "sha256=" .. sig ~= r.RequestHeader["X-Hub-Signature-256"] then
  r:SetResponseStatusCode(401)
  r:SetResponseBody("invalid signature")
  r:StopForwarding()
  return
end

Set up in three steps

One agent on a host that can reach the collector. No inbound rule, no public IP.

  1. 1

    Run the agent next to the SIEM

    Install the relay CLI (or the Docker image) on a host that can reach the collector, and log in with an access token scoped to this bucket.

    shell
    relay login -k $RELAY_KEY -s $RELAY_SECRET
    relay forward --bucket security-events \
      http://splunk.internal:8088/services/collector/raw
  2. 2

    Add the HEC token and signature check

    Attach a function to the input: verify the vendor's signature, then set the collector's auth header from a config variable.

    function (Lua)
    r:SetRequestHeader("Authorization", "Splunk " .. cfg:GetValue("HEC_TOKEN"))
  3. 3

    Paste the URL into each tool

    Use the bucket's public URL as the webhook or event hook destination in Okta, CrowdStrike or GitHub. Every delivery shows up in the bucket logs with the collector's response.

Start free, or buy through procurement

Try it on one pipeline

Free$0
150 webhooks a month, enough to wire up one tool
Business$79.99/mo
60,000 webhooks a month, long log retention, priority support

7-day money-back guarantee on paid plans.

Buying for a company?

  • Annual plans paid by invoice and purchase order
  • Help with your security review
  • Vendor onboarding paperwork

Questions

Does my SIEM need a public IP or an inbound firewall rule?

No. The relay agent runs inside your network and opens an outbound TLS connection to Webhook Relay. Vendors post to the public Webhook Relay URL, and the agent delivers each alert to the collector's internal address.

What happens to alerts while the indexer is down?

Webhook Relay stores each alert when it arrives and the vendor gets a success response. With durable delivery it is retried for up to 30 days, and any delivery can be replayed from the bucket logs.

Do you store the alert contents?

By default, each request is stored for delivery logs, retries and replay, encrypted with AES-256 at rest, and deleted automatically when your plan's retention ends. You can make a bucket ephemeral so bodies, headers and query strings are never stored.

How do I keep forged alerts out?

Attach a function to the input that checks the vendor's HMAC signature or token and stops forwarding when it doesn't match. Inputs also support basic auth and JWT verification.

Can we keep the data on our own servers?

Yes. A self-hosted version of Webhook Relay is available for teams that need every payload to stay inside their infrastructure. Talk to sales.

More security pages: GitOps webhooks into a private cluster · Alerts into internal runbook automation · Security review kit

Get your first alert into the SIEM

Run one agent, paste one URL into your security tool, watch the event land. No inbound port.

Free plan · No credit card required · 7-day money-back guarantee on paid plans