Rotate the Sume webhook secret twice in one 24-hour window: what dies

Sume signs with both secrets for 24 hours after a rotation. Rotate a second time inside that window and the secret from two rotations back stops at once.

5 min readSume
All posts

A Sume signing-secret rotation is not a cutover. For 24 hours after you rotate, every delivery carries two signatures, newest first, and a receiver holding either secret verifies it. If you rotate a second time inside that window, Sume immediately retires the secret from two rotations back, so a receiver still on that oldest secret stops verifying. That is the intended way to make a leaked secret stop working, and it is also the way to break your own receiver by accident.

Timeline of two rotations

Call the secrets A, B and C. A is current, you rotate to B, then rotate again to C before 24 hours pass. The table follows the rules in the Sume docs.

Which secrets verify after each step, as of 2026-10-08
StepHeader carriesReceiver on AReceiver on BReceiver on C
Before rotationsume-v1=Apassesfailsfails
After rotating to Bsume-v1=B,sume-v1=Apassespassesfails
After rotating to C inside the windowsume-v1=C,sume-v1=Bfailspassespasses
After the 24-hour windowsume-v1=Cfailsfailspasses

Rules that follow

  • Upgrade the receiver before you rotate. A verifier that compares the whole header for equality fails on every delivery during the window; verifyWebhook in @sume-com/sdk 0.2.0 already handles several entries.
  • Deploy the new secret to every receiver before the deadline. rotation.previous_valid_until on both signing-secret API responses gives the time.
  • x-sume-webhook-secret-fingerprint names the new secret from the moment you rotate. It tells you which secret to move to, not which secrets Sume still accepts.
  • If you rotate for a leak, rotate twice. The first rotation starts the window and the second removes the leaked secret.

Rotating through the API

The dashboard has a Rotate secret button on the Webhooks tab. The API route is POST /v1/webhooks/signing-secret/rotate and needs a key with account:write. Reading the current secret uses GET /v1/webhooks/signing-secret with account:read.

The script below rotates and prints the deadline. Run it from a machine that holds the key, and then deploy the new secret.

import os
import httpx

key = os.environ.get("SUME_API_KEY", "")
if not key:
    raise SystemExit("set SUME_API_KEY (needs account:write)")

r = httpx.post(
    "https://api.sume.com/v1/webhooks/signing-secret/rotate",
    headers={"Authorization": f"Bearer {key}"},
    timeout=20,
)
r.raise_for_status()
body = r.json()
# Do not print the secret itself; print only the deadline.
print(body.get("rotation", {}).get("previous_valid_until"))

What to check after

Send a test from the dashboard to your endpoint and confirm the fingerprint in the delivery matches the fingerprint next to the new secret. If a signature does not verify, compare fingerprints before anything else. They are the only part of the secret data that is safe to paste into a ticket.

A rotation runbook

Write the order down before you need it. A calm single rotation takes four steps: upgrade every receiver to a verifier that accepts several sume-v1 entries, rotate, deploy the new secret to every receiver, then confirm that deliveries carry the new fingerprint. You have 24 hours for the third step, and the dashboard shows the deadline while the window is open.

An emergency rotation after a leak has one more step. Rotate, deploy the new secret, and rotate again once every receiver is on the new secret. The second rotation retires the leaked secret at once instead of waiting 24 hours. During the short period between the two rotations, a receiver that is still on the leaked secret also stops verifying, so deploy first.

Each delivery carries x-sume-webhook-secret-fingerprint, and the receipt carries the same value as webhook_delivery.signing_secret_fingerprint. Log the fingerprint your receiver expected next to the one in the header. A mismatch tells you in one line which environment still holds an old secret. Neither side needs to send the secret itself, which is why the fingerprint is the only part that is safe to paste into a ticket.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume