Skip to main content
A signing secret lets your server prove each webhook delivery came from Sixtyfour and was not altered or replayed. Each organization has at most one active signing secret. Once it exists, every outgoing webhook (async-job callbacks and workflow outgoing_webhook blocks) carries a Sixtyfour-Signature header. Without a secret, deliveries are unsigned.

Manage the secret

Manage the secret in Settings → Webhooks, on the Signing Secret card. Every member can see whether a secret exists and when it was created; only organization admins and owners can create, roll or revoke it.

Signature format

The body is compact JSON. Compute the HMAC over the exact bytes you received, before any JSON parsing or re-serialization.

Verify signatures

  1. Read the raw request body.
  2. Parse Sixtyfour-Signature into t and every v1.
  3. Reject the request if t is more than 5 minutes from your clock.
  4. Compute HMAC-SHA256(secret, f"{t}." + raw_body) as hex.
  5. Accept if it matches any v1 with a constant-time comparison.
rawBody must be the unparsed request body, for example from express.raw({ type: "application/json" }).

Behavior

  • Fail closed. If a signing secret exists but Sixtyfour cannot load it, the delivery fails instead of going out unsigned.
  • Replay protection. The timestamp is inside the signed payload, so an old delivery cannot be replayed with a fresh t. Dedupe on Sixtyfour-Event-Id to ignore legitimate retries you already processed.
  • Rotation. Accept any matching v1 so deliveries keep verifying while you deploy a rolled secret.

Errors

For error responses (401, 403, etc.), see Handling Errors.