Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.tumban.com/llms.txt

Use this file to discover all available pages before exploring further.

When your organization has a webhook secret configured, Tumban signs every webhook body with HMAC SHA-256 and sends the digest in the X-Sherlock-Signature header.
X-Sherlock-Signature: sha256=<hex-digest>
The digest is computed over the raw request body — verify before parsing JSON, since any whitespace or key reordering you apply will change the bytes.

Setting up

  1. Call Rotate webhook secret to obtain a secret. The value is shown exactly once.
  2. Store the secret in your secret manager.
  3. Verify every incoming webhook against it.

Verification

import hmac
import hashlib

def verify(secret: str, body: bytes, header_value: str) -> bool:
    if not header_value or not header_value.startswith("sha256="):
        return False
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    received = header_value.removeprefix("sha256=")
    return hmac.compare_digest(expected, received)
Always use a constant-time comparison (hmac.compare_digest, crypto.timingSafeEqual, Rack::Utils.secure_compare) to avoid timing-attack leakage.

Rotation

When you rotate the secret, Tumban switches over immediately — incoming webhooks are signed with the new secret only. Update your verification code first, then call Rotate webhook secret.

When the header is absent

If your organization has no webhook secret configured, Tumban does not send the X-Sherlock-Signature header. Generate one with Rotate webhook secret before trusting webhook bodies in production.