Browse documentation

Webhooks.

Outbound: a generic webhook connector that signs payloads with HMAC-SHA256 when a shared secret is configured. Inbound: provider signatures verified before any payload is trusted, failing closed.

Signature header X-SignatureAlgorithm HMAC-SHA256Timestamp X-TimestampUpdated October 2026

Outbound events

  1. In the console, open Integrations → Ticketing and add a Generic webhook.
  2. Enter your HTTPS endpoint URL.
  3. Set a shared secret. Without one, events are sent unsigned — always set it in production.
  4. Optionally change the signature header (default X-Signature), the signature prefix (default sha256=) or add static headers your endpoint expects.

Each finding event is posted as JSON:

POST https://hooks.example.com/securityvault
Content-Type: application/json
User-Agent: ESOS-Webhook/1.0
X-Timestamp: 2026-10-05T09:12:41.118000+00:00
X-Signature: sha256=7c4a…d3f1

{
  "event": "esos.finding",
  "timestamp": "2026-10-05T09:12:41.118000+00:00",
  "payload": { "finding_id": "…", "severity": "high", "title": "…", … }
}

Verifying the signature

The signature is an HMAC-SHA256, keyed with your shared secret, over the canonical JSON of the payload object only: keys sorted, no whitespace between tokens, and non-ASCII characters escaped as \uXXXX. The event, timestamp and X-Timestamp values are not covered by the signature. The unsigned timestamp is not replay protection. Use receiver-side state to handle duplicate or replayed payloads, and reconcile records through the API.

# Python
import hashlib, hmac, json

def is_valid(body: dict, header: str, secret: bytes) -> bool:
    canonical = json.dumps(body["payload"], sort_keys=True, separators=(",", ":")).encode()
    expected = "sha256=" + hmac.new(secret, canonical, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)
Compare in constant time, reject any request whose signature does not match, and serve your endpoint over HTTPS only.

Inbound webhooks

Provider webhooks that reach SecurityVault — GitHub, GitLab, Bitbucket, Azure DevOps, Slack, Microsoft Teams and ticketing systems — are verified before any payload is trusted, using each provider's own signing scheme, constant-time comparison and a five-minute timestamp window where the provider supplies a timestamp. A malformed or unsigned request is rejected. Ticketing webhooks additionally carry a per-organisation, per-provider key with an X-SV-Body-Signature header and an X-SV-Nonce replay guard.

Delivery

Respond with a 2xx status quickly and process the event asynchronously. Treat webhooks as a notification channel: to reconcile after downtime on your side, page through GET /api/v2/findings with a cursor (see the API reference).

Next steps