Skip to main content
Blog
Security5 min read

Webhook signing secret rotation: a receiver acceptance test

Test a webhook secret rotation across old and new signatures, in-flight deliveries, retries, and final key retirement before accepting an integration.

Rainier Software Solutions

Two signing-key paths overlap at a webhook receiver, then the old path closes while the new path stays open, drawn in indigo.

A webhook signing secret rotation is complete when the receiver accepts legitimate deliveries under the new secret, rejects signatures made only with the retired secret, and processes each business event according to its duplicate-handling contract. A changed value in a secrets manager is not enough evidence. The sender may still sign with the old key, a retry may arrive during the change, or one receiver instance may load a different configuration.

This guide is for engineering leads and prime contractors accepting a software integration. It gives a proposed acceptance test for a planned rotation. It does not assert a universal rotation window or claim that Rainier has performed this test for a named client. If a key is suspected compromised, OWASP's webhook guidance calls for immediate revocation rather than a convenience overlap.

Record the sender's contract first

Do not infer rotation behavior from the word “webhook.” Standard Webhooks permits multiple signatures in one header during a dual-signing period. Twilio's shared-key procedure instead has the receiver load the new key before the sender's rule moves to a new signing setting. OpenAI's endpoint rotation API offers an optional 24-hour old-secret period and defaults to immediate invalidation. These are examples of different provider contracts, not interchangeable instructions.

Record these answers before changing production configuration:

Contract questionWhat to captureWhy it affects the test
Signature inputExact raw body and any signed timestamp or delivery IDParsing and reserializing JSON can change the bytes being verified
Header formatAlgorithm, key identifier, and whether several signatures may appearThe receiver must match the provider's format, not accept an arbitrary header
Rotation behaviorDual signing, sender-side switch, or immediate replacement; expiry timeDetermines deployment order and the last valid old-key delivery
Retry behaviorWhether pending deliveries are re-signed and how to redeliver themAn old event may arrive after the key change
Receiver rolloutNumber of instances and how they refresh secretsMixed configuration can create intermittent failures
Business identityEvent or delivery ID used to prevent duplicate effectsSignature validity alone does not prevent a second action

GitHub's signature documentation signs the payload bytes with the configured secret; it specifies an HMAC-SHA256 signature header. The Standard Webhooks specification signs the message ID, delivery timestamp, and payload together. Use the sender's actual verifier or documented algorithm and compare securely. Do not assume that a test written for one provider verifies another.

Worked rotation: overlap, switch, retire

The following is a hypothetical fixture, not a production result or a provider promise. Assume sender S supports two signatures during a 30-minute planned overlap. Receiver R has two instances. Both can hold an allowlist of active signing secrets. A durable event ID prevents a second business effect when a valid delivery is retried. The deadline and outcomes below are assumptions for this fixture; replace them with the sender's documented behavior and the work package's agreed policy.

MomentSender stateReceiver stateExpected check
T0Signs with old keyBoth instances accept old keyA known event verifies and is processed once
T1Signs with old and new keysBoth instances accept old and new keysNew-key-only and old-key-only synthetic signatures both verify during the agreed overlap; altered bodies fail
T2Signs with new keyBoth instances accept old and new keysA new live delivery verifies on each instance; a retried event does not repeat its business effect
T3Signs with new keyBoth instances accept new key onlyNew-key delivery passes; old-key-only signature is rejected by every instance

The overlap is a transition state, not permission to keep the old key forever. At T3, test the rejection directly. Then check the provider's delivery logs for failed attempts and reconcile any missed event IDs. If the sender offers no overlap, coordinate a maintenance or dual-endpoint procedure that the provider actually supports; do not claim a zero-downtime switch without a demonstrated path.

A compromise changes the decision: old-key acceptance is an exposure window because someone holding that key may forge a signed request. Use the incident procedure and accept possible delivery interruption while revoking the compromised key. That distinction follows OWASP's planned-versus-compromised rotation guidance.

Acceptance matrix for the receiver

Run the checks against the actual deployed receiver build in an authorized test environment. Use test keys and synthetic payloads; do not paste production secrets into a ticket or test fixture. Exercise every instance or deployment revision that can receive traffic. This matrix is a proposed review aid, not a claim that a provider sends each synthetic combination.

Input or conditionDuring overlapAfter old-key retirementEvidence
Correct body, current keyAcceptAcceptVerification result and one business effect
Correct body, old key onlyAccept if contract allowsRejectStatus, key identifier, and no business effect after retirement
Body changed after signingRejectRejectRaw-body fixture and no accepted event
Missing or unknown signatureRejectRejectStatus and no accepted event
Same authenticated event retriedAuthenticate, then deduplicateAuthenticate if newly signed, then deduplicateOne durable event ID and one business result
Receiver instance still on old configDetect rollout failureMust not accept trafficPer-instance version and verification telemetry

GitHub states that a redelivery keeps its original X-GitHub-Delivery value. That makes it a useful duplicate-effect test for a GitHub integration, but the ID and retry-signing rule for another sender must be checked separately. The API retry and idempotency acceptance guide covers the wider business-effect boundary; this article asks whether rotation changes which deliveries can be authenticated.

Do not log the secret or full signature to prove success. A safe review record needs the key identifier or configuration revision, receiver build, event ID, decision, and resulting business state. If the provider does not expose a key identifier, record which controlled test secret generated the fixture without copying its value into the evidence package.

Decide whether the rotation can close

Use one decision record per endpoint. The engineering lead should be able to see both an accepted new-key delivery and a rejected old-key-only delivery after retirement. A successful dashboard test that never exercises the old key is incomplete.

Endpoint and sender protocol:
Receiver build / instance set / environment:
Rotation mode and agreed old-key expiry:
Synthetic fixture IDs; raw-body verification method:
New-key delivery result on each instance:
Old-key-only result after retirement:
Tampered and unsigned request results:
Retried event ID and observed business effect count:
Provider delivery failures and reconciliation owner:
Secret storage revision; rollback or incident path:
Reviewer decision: accept / hold / retest

For an integration delivered under subcontract, place that record beside the software acceptance package and name the party that controls the sender settings. Rainier's public Vennli delivery record describes a Python service, REST APIs, and a React portal delivered under subcontract. It does not claim webhook rotation work; it provides bounded context for integration ownership and handover. The software subcontracting page explains how Rainier scopes application and API work packages. Bring the provider contract and acceptance matrix to the scoping discussion.

Discuss an integration work package

  • Security
  • Software Delivery

Rainier Software Solutions

Principal-led software engineering for federal and state missions. Secure, scalable, audit-ready.

About Rainier

Building something that has to pass an audit?

Send us the scope and the compliance requirements. You will hear back from an engineer within one business day.