Workers post-quantum Web Crypto: Sume webhooks stay HMAC-SHA-256
Cloudflare Workers Web Crypto now supports ML-KEM and ML-DSA. Sume webhook signatures are still HMAC SHA-256, and verifyWebhook runs on Workers with WebCrypto.

Cloudflare's Sep 28, 2026 changelog says Workers Web Crypto now supports ML-KEM-768, ML-KEM-1024, ML-DSA-44, ML-DSA-65 and ML-DSA-87. That does not change how you verify a Sume webhook: the signature is still HMAC SHA-256 over the timestamp and raw body, and verifyWebhook from @sume-com/sdk runs on Workers using WebCrypto.
What changed on Workers, and what did not
The new algorithms are for key encapsulation (ML-KEM) and digital signatures (ML-DSA). They are additions to what a Worker can do; nothing in Sume's delivery format moved to them.
| Item | Value |
|---|---|
| New in Workers Web Crypto (Sep 28, 2026) | ML-KEM-768, ML-KEM-1024, ML-DSA-44, ML-DSA-65, ML-DSA-87 |
| Sume webhook signature | HMAC SHA-256 over <timestamp>.<raw_body> |
| Signature header | x-sume-webhook-signature: sume-v1=<hex> |
| Timestamp header | x-sume-webhook-timestamp |
Sume's scheme is a shared-secret MAC
HMAC uses a shared secret that you and Sume both hold, so verification is symmetric and has no public key. Sume derives the signing secret per workspace; read it from the Webhooks tab or GET /v1/webhooks/signing-secret, and store it as SUME_COM_WEBHOOK_SIGNING_SECRET.
Nothing about post-quantum signatures changes that choice for you. If Sume ever changes its scheme, the docs will say so; until then, keep verifying the sume-v1= header.
A Worker that verifies and acks
The SDK check reads the raw body before any JSON parsing, compares against every sume-v1= entry during a secret rotation and rejects a stale timestamp. Return a fast 2xx after storing the event, and use job_id as your idempotency key because deliveries can repeat. The sketch refuses to run with an empty secret.
- Read the raw body first.
- Refuse an empty secret.
- Ack with 2xx fast; process afterwards.
- Keep status_url polling as a fallback.
import { verifyWebhook } from "@sume-com/sdk";
export default {
async fetch(request: Request, env: { SUME_COM_WEBHOOK_SIGNING_SECRET?: string }) {
const secret = env.SUME_COM_WEBHOOK_SIGNING_SECRET;
if (!secret) return new Response("secret not configured", { status: 500 });
const body = await request.text(); // raw, before JSON.parse
const ok = await verifyWebhook({ body, headers: request.headers, secret });
if (!ok) return new Response("bad signature", { status: 401 });
const event = JSON.parse(body);
// store event keyed by event.job_id, then ack
return new Response(null, { status: 204 });
},
};Sources
Related posts
More in Developers
- Workflow DevKit 5 fail-fast refusals: which Sume errors to retry
Workflow DevKit 5.0.1 now fails fast on dynamic start() refusals. Apply the same rule to Sume: do not retry a 400 or 402, retry 429 and 503 with the same key.
- Workflow DevKit 5: 12 MiB frames, pass Sume URLs not video
Workflow DevKit 5.0.1 splits WebSocket frames over 12 MiB by default (16 MiB at most). Pass Sume artifact URLs between steps instead of video bytes.
- Workflow DevKit replays: a stable Idempotency-Key for Sume submits
Workflow DevKit 4.8.12 fixed replay clock tracking. A replayed step must send the same Sume Idempotency-Key, so derive it from the run id, not Date.now.
- Which MCP server lets Claude Code or Cursor generate video and images?
MCP servers that let Claude Code and Cursor make video and images: Sume, fal, Replicate, Runway, Higgsfield. Endpoints, sign-in, billing, setup.
Written by Sume