Activepieces webhook authentication failed run: Sume signature

Activepieces 0.92 shows a failed run when webhook authentication fails. Sume sends an HMAC signature header you verify yourself in a code step.

4 min readSume
All posts

Activepieces release notes say a failed webhook authentication now shows a failed run and stops sync flows (#14954). Sume does not authenticate to Activepieces that way: it signs each delivery with HMAC SHA 256 and sends x-sume-webhook-signature: sume-v1=<hex_signature>. Verifying it is a step you write, then you fail the run when it does not match.

The Activepieces line is from its releases page; I did not read how its built-in authentication is configured, so this post does not describe it. Signature details are from Sume's Webhooks docs, read 2026-09-30.

What does Sume sign?

When signing is configured, Sume signs the raw JSON body over <timestamp>.<raw_body>. Two headers arrive: x-sume-webhook-timestamp and x-sume-webhook-signature. During a secret rotation the signature header carries one sume-v1= entry per live secret, newest first, comma separated; accept the delivery if any entry matches.

Sume webhook signature inputs, from the docs read 2026-09-30
InputValue
Signed string<timestamp>.<raw_body>
AlgorithmHMAC SHA 256, hex digest
Header formatsume-v1=<hex_signature>
Replay windowReject outside your tolerance; five minutes is the suggested default
Secret env nameSUME_COM_WEBHOOK_SIGNING_SECRET

What should the verifier look like?

The docs ship a TypeScript verifier. The sketch below is a shorter single-entry version; use the docs version if you rotate secrets. It must have the raw body, not re-serialized JSON, and it refuses an empty secret.

import crypto from "node:crypto";

export function verify(raw: string, ts: string, header: string, secret: string) {
  if (!secret) return false;
  const t = Number(ts);
  if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
  const want = Buffer.from(
    "sume-v1=" + crypto.createHmac("sha256", secret).update(t + "." + raw).digest("hex"),
  );
  return header.split(",").some((e) => {
    const got = Buffer.from(e.trim());
    return got.length === want.length && crypto.timingSafeEqual(got, want);
  });
}

How do I make a failed check visible?

Throw an error from the code step when verify returns false. Given the release note, whether Activepieces then marks the run failed in your version is something to confirm with a test delivery. If it does not match, compare x-sume-webhook-secret-fingerprint on the delivery with the fingerprint beside the secret in the dashboard; neither side sends the secret itself.

What happens to a rejected delivery?

Sume treats non-2xx responses as failures and retries: up to 10 attempts, a fixed 30s delay by default, 10s timeout per attempt. Keep status_url polling as a fallback, as in the sync webhook 408 case.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume