n8n browser OAuth2 webhook auth vs Sume HMAC-signed webhooks
n8n 2.42 adds a browser OAuth2 flow for User Auth webhooks. Sume's webhooks are server-to-server and HMAC-signed instead. A Python verifier that fails closed.

n8n's new browser OAuth2 flow for User Auth webhooks authenticates a person in a browser, and Sume's webhooks are sent by a server with no person present, so the two do not meet. Sume authenticates its deliveries with an HMAC signature that your endpoint verifies, not with a login. The 2.42.0 release (2026-09-29) lists the browser OAuth2 flow among its notable changes (read 2026-10-03), so if you were about to put that auth on the webhook that Sume calls, do not.
The n8n item is in the 2.42.0 release notes. The Sume scheme is in Webhooks and Run webhooks.
What Sume sends and what proves it
A Sume delivery is one POST with a JSON body and two headers: x-sume-webhook-timestamp and x-sume-webhook-signature. The signature is sume-v1= followed by the hex HMAC SHA-256 of <timestamp>.<raw_body> under your signing secret. During a secret rotation the header carries one entry per live secret, newest first, separated by commas, and you accept the delivery when any sume-v1= entry matches. Reject a timestamp outside your replay window; Sume suggests five minutes.
The secret is on the Webhooks tab of the dashboard, or from GET /v1/webhooks/signing-secret with an API key carrying account:read. One verifier covers both job webhooks and run webhooks.
| Property | n8n User Auth webhook (browser OAuth2) | Sume delivery |
|---|---|---|
| Who calls | A person in a browser | Sume's servers |
| Proof | An OAuth2 login | HMAC sume-v1= signature plus timestamp |
| Replay defense | Session handling | Timestamp window you enforce |
| Retries | Not applicable | Up to 10 attempts; Redeliver after |
A verifier that fails closed
n8n's Webhook node can hand you the raw body if configured to, and the signature is computed over the raw bytes, so verify before any parsing that re-serializes the JSON. The function below refuses an empty secret, checks the timestamp window, and compares every sume-v1= entry in constant time.
import hashlib, hmac, time
def verify_sume(raw_body: bytes, timestamp: str, header: str,
secret: str, tolerance: int = 300) -> bool:
if not secret:
raise ValueError("signing secret is empty; refusing to verify")
try:
ts = int(timestamp)
except ValueError:
return False
if abs(int(time.time()) - ts) > tolerance:
return False
digest = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body,
hashlib.sha256).hexdigest()
expected = f"sume-v1={digest}"
ok = False
for entry in header.split(","):
if hmac.compare_digest(entry.strip(), expected):
ok = True
return ok
if __name__ == "__main__":
body, ts, sec = b'{"event":"job.completed"}', str(int(time.time())), "test-secret"
sig = "sume-v1=" + hmac.new(sec.encode(), f"{ts}.".encode() + body,
hashlib.sha256).hexdigest()
print(verify_sume(body, ts, sig, sec), verify_sume(body, ts, sig, "other"))Wiring it into n8n
Leave the Sume-facing webhook path without User Auth, since a browser flow cannot complete for a server caller, and put the signature check first in the workflow, in a Code node or an HTTP step to a small verifier. If the check fails, return an error status and stop. Use job_id as the idempotency key in downstream steps, because a retry or a Redeliver can send the same event again; Redeliver does not consume one of the automatic ten attempts.
Respond with a 2xx quickly. Sume gives each attempt 10 seconds, and a slow endpoint burns the budget and gets retried. Do the real work after you acknowledge, and keep the secret in n8n credentials, not in the workflow JSON you export and share.
Testing the receiver without spending
Test before connecting real jobs. Sume's webhooks page describes Send test and Redeliver, so you can have a delivery sent to your endpoint without waiting for a job, and a Redeliver re-POSTs a stored delivery with a fresh timestamp and signature. Use them to confirm three cases: a valid delivery passes, a body altered by one character fails, and a request with an old timestamp fails.
If a valid delivery fails, the cause is almost always the body. Frameworks that parse JSON and re-serialize it change whitespace and key order, and the signature covers the raw bytes. Capture the raw body before parsing. The second most common cause is the wrong secret, and Sume exposes a fingerprint header, x-sume-webhook-secret-fingerprint, so you can compare the fingerprint with the one in the dashboard without sending the secret anywhere.
Once it passes, rotate the signing secret in a staging account and confirm your verifier accepts the comma-separated header with two entries during the overlap.
Sources
Related posts
More in Developers
- n8n durable agent message queue: replays and Sume idempotency keys
n8n 2.42 lays a durable agent message queue foundation. A queue that can redeliver means a paid Sume call needs a stable idempotency_key per message.
- Audit narration before posting a Short: flag 'here we see' lines
YouTube is reported to discount voice-over that only describes the screen. Transcribe a clip with Sume video inspect and flag describing lines first.
- How many video jobs can I send now? The in-flight budget, worked
Concurrency 100, queue 500, 30 processing and 10 queued gives a new in-flight budget of 60 on Sume. Why the 450 wave hint is a hint, not your limit.
- No queue position or ETA for a Sume video job: what to show users
Sume exposes queue counts and remaining capacity, not a per-job queue position or ETA, and has no queue expiry option. What a video UI can say honestly instead.
Written by Sume