n8n Webhook node IP allowlist: Sume publishes no sender IPs

n8n can limit a Webhook trigger to listed IPs, but Sume's docs list no sender addresses. Verify the signature instead, with a Python check.

5 min readSume
All posts

Do not use the n8n Webhook node's IP allowlist for Sume callbacks, because Sume's webhook docs do not publish a list of sender IP addresses to enter. Verify the HMAC signature on every delivery instead, using the raw request body.

I searched the Sume webhook, run-webhook, SDK webhook and authentication docs on origin/main for egress addresses or an allowlist and found none. A rule you cannot fill in correctly would either block real deliveries or be left open, so rely on the signature scheme the docs describe.

What the n8n Webhook node offers

The n8n page (read 2026-10-10) lists these options on the node: authentication of Basic auth, Header auth, JWT auth or none; a Raw Body option for data in a raw format such as JSON or XML; four respond modes (immediately, when the last node finishes, using a Respond to Webhook node, and streaming); an IP allowlist; and Ignore Bots. It states a maximum payload size of 16MB.

None of those authentication types is Sume's scheme. Sume signs the raw JSON body with HMAC SHA-256 over <timestamp>.<raw_body> and sends x-sume-webhook-timestamp and x-sume-webhook-signature: sume-v1=<hex>. So you take the headers from the node and check the signature in a Code node, or in a small service in front of n8n.

n8n Webhook node options, read 2026-10-10, against Sume's signature scheme
n8n optionWhat it doesFit for Sume
Header authCompares one static header valueNot the Sume scheme; the signature changes per delivery
JWT authValidates a JWTNot used by Sume
IP allowlistLimits callers by addressNo Sume sender list is documented
Raw BodyReceives data in raw formatUse it, so the signed bytes are not re-serialized
Max payload 16MBUpper bound for a requestFar above a job event; Sume says a run receipt can overflow to a null payload

Verify the signature with the raw body

The check has to hash the exact bytes Sume signed. Re-stringifying parsed JSON can change spacing or key order and break the match. The docs say to reject a stale timestamp (five minutes is a reasonable default), to accept any sume-v1= entry during a secret rotation, and to compare every entry. The sketch below does that in Python and returns false for an empty secret.

import hashlib, hmac, time

def verify(raw_body: bytes, timestamp: str, header: str,
           secret: str, tolerance: int = 300) -> bool:
    if not secret:
        return False
    try:
        ts = int(timestamp)
    except ValueError:
        return False
    if abs(time.time() - ts) > tolerance:
        return False
    msg = f"{ts}.".encode() + raw_body
    digest = hmac.new(secret.encode(), msg, 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

After it verifies

Return a 2xx only after you store the event. Sume retries network errors and non-2xx responses up to 10 attempts in total, 30 seconds apart by default, with a 10 second timeout per attempt. A slow n8n workflow that does heavy work before it answers can burn attempts, so answer with the Immediately respond mode and do the work in a second step.

Use job_id as the idempotency key in n8n, for example in a data table or an IF node that checks for a seen id. If the signature does not verify, compare x-sume-webhook-secret-fingerprint with the fingerprint beside the secret in the dashboard. Neither side has to send the secret itself.

  • Read the secret from GET /v1/webhooks/signing-secret or the dashboard Webhooks tab.
  • Keep status polls as a backup for events that never arrive.
  • Use Send test to check wiring; it sends a dummy webhook.test and never replays a real job.

Which Sume webhook surface you are receiving

Sume has two webhook surfaces, and one verifier covers both because the signature scheme is identical. Generation jobs send job.completed, job.failed or job.canceled. Action, Format and Agent Completion runs send action.run.terminal, format.run.terminal or agent.run.terminal, and the run payload carries a full receipt rather than a job result.

In n8n, route on the event field right after verification. For run events, branch on outcome (ok, degraded, error) rather than on status, because a run can complete and bill but fail to project its media into the output schema. The run webhooks page also says Sume validates the URL as public HTTPS at delivery time and does not follow redirects, so a 3xx from a proxy in front of n8n counts as a failed attempt.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume