Webhook security

Snapdocs webhooks post to endpoints outside Snapdocs' control, so the delivery pipeline is built around a set of security features. Use as many of them as your listener can support; most are changes on the integrator's side, so Snapdocs recommends them but cannot enforce them.

FeatureQuick summary
No PIIEvent messages contain event names and identifiers for transactions or documents. All PII requires a follow-on authenticated call.
IP whitelistingSnapdocs broadcasts from a single set of IP addresses for all outbound traffic, so you can lock your endpoint down to our broadcast.
Authenticated endpointsSnapdocs can POST with a bearer token (OAuth2 client credentials) or Basic Auth if your endpoint requires authentication.
HMAC signatureEvery message carries an HMAC signature you can validate with the secret from subscription creation.
HTTPS / TLSWebhook endpoints must be HTTPS. Keep TLS current (1.3+).

Beyond these, build your listener with rate limiting and per-client uniqueness where you serve multiple companies: unique keys, URLs, or identifiers per client so one company's traffic can never be mistaken for another's. Rotate HMAC keys regularly by creating a replacement subscription, and always rotate them after a security incident.

No PII in payloads

Broadcast events never contain PII or sensitive information — only identifiers, statuses, and document statuses. When an event calls for more detail, retrieve it with an authenticated API call.

IP whitelisting

Snapdocs supports IP whitelisting for both test and production environments. Your Snapdocs representative can provide the current list of IP addresses for each; update your firewall rules to allow only those, so only authorized Snapdocs traffic reaches your systems.

Authenticated endpoints

The Create a Subscription endpoint takes optional OAuth2 details (token_url, client_id, client_secret) for a client-credentials flow, or Basic Auth credentials. Snapdocs then obtains a token and sends an authenticated call to your endpoint for every event.

The HMAC signature

Every webhook is signed with an HMAC hash of the secret returned at subscription creation. Validate the timestamp and signature to confirm the data was sent by Snapdocs and not tampered with in transit. Each message includes three HTTP headers:

  • X-Authorization-Digest — the algorithm used to generate the signature, HMACSHA256
  • X-Authorization-Timestamp — an ISO-8601 timestamp, for example 2021-12-17T19:08:59Z
  • X-Authorization-Signature — the base64-encoded HMAC signature to compare against

To verify a delivery:

  1. Extract the digest and timestamp from the headers.
  2. Compute the HMAC of timestamp + body with your subscription's secret, using the digest algorithm.
  3. Base64-encode the result and compare it to X-Authorization-Signature.
  4. If they match, process the event. If not, discard the message; it didn't originate from Snapdocs.
require 'openssl'
require 'base64'

timestamp = request.headers["X-Authorization-Timestamp"]
request_signature = request.headers["X-Authorization-Signature"]
data = request.body.read

hash_bytes = OpenSSL::HMAC.digest('sha256', hmac_key, timestamp.concat(data))
computed_signature = Base64.strict_encode64(hash_bytes)
if computed_signature == request_signature
   # normal process
else
   # did not come from SD