Inbound Webhooks overview
KnoxCall’s Inbound Webhooks feature is a signature-verifying ingress for HMAC-signed webhooks. Point Stripe (or GitHub, Slack, AWS SNS, anything that signs requests) at a KnoxCall URL. KnoxCall verifies the signature, audits the call, and optionally forwards the request to your app with anX-Knox-Verified: true header.
The job your app would do — verify the HMAC, enforce the replay window, log the result — lives once in KnoxCall instead of being copy-pasted across every service that consumes webhooks.
Why use it
How it works
- Create an inbound webhook subscription in the admin UI — pick a format (Stripe, GitHub, Slack, AWS SNS, KnoxCall legacy, or custom-header), paste the shared secret, choose where to forward verified requests.
- KnoxCall hands you a receiver URL:
https://hooks.knoxcall.com/<your_tenant_slug>/<webhook_name>. - Paste that URL into the upstream provider’s webhook config. Stripe (or whoever) signs every event with HMAC-SHA256 of the body and sends it to KnoxCall.
- KnoxCall verifies the signature using the format’s wire spec and the secret you configured.
- If valid → forward to your app with
X-Knox-Verified: true(or audit-only if no forward URL). - If invalid → return
401(default), or forward withX-Knox-Verified: falseif you want your app to log unverified events without losing them.
Quick start (UI)
- Go to Automation → Webhooks in the admin UI, switch to the Inbound tab, and click New Inbound Webhook.
- Pick the format that matches the upstream provider (Stripe, GitHub, Slack, etc.).
- Paste the shared secret the provider gave you (e.g. Stripe’s
whsec_...). - Optional: enter a forward URL (your app’s webhook handler). Leave blank for verify-only auditing.
- Save. Copy the receiver URL that appears.
- Paste the receiver URL into the upstream provider’s webhook configuration.
X-Knox-Verified: true or appear in API Logs for inspection.
Supported formats
See the format guide for the exact wire format each verifier expects.
Replay protection
For formats with a timestamp header (Stripe, Slack), KnoxCall enforces a 5-minute window by default. A request with a timestamp older than that gets rejected withreplay_window_exceeded even if the signature is valid. This closes the attack where someone captures a real webhook and replays it later.
Configure the window per subscription (range: 0–86400 seconds, where 0 disables the check). The default of 300 matches Stripe’s and Slack’s recommended values.
What gets audited
Every ingest call writes a row to API Logs (/logs) with:
path—/<tenant_slug>/<webhook_name>signature_valid—true/falsesignature_error— the rejection reason if invalid (replay_window_exceeded,no v1 signature matched,missing X-Hub-Signature-256 header, etc.)meta_json.subscription_id— which subscription handled the requestmeta_json.forwarded— whether the verified request was sent on to your appmeta_json.forward_status— HTTP status from your app
Security model
KnoxCall stores the shared secret encrypted under the per-tenant master key (KCT1 envelope). The receiver URL is unauthenticated by design — authentication is the HMAC signature. A request that doesn’t verify either gets dropped (default) or markedX-Knox-Verified: false for your app to handle.
Forwarding is SSRF-safe: the forward URL is validated to use HTTPS, point at a DNS hostname (not a literal IP), and not resolve to a private / metadata-IP range.
Next steps
- Format guide →
- Outbound Webhook Signing → — the inverse direction (KnoxCall fires events out and signs them)
- Crypto Keys → — use a managed key for signature verification instead of a per-subscription shared secret