Dmitriy Kononov.
Let’s talkContact

News and analysis

Webhook security: signatures, replays and operation state

Verify webhook origin, control repeated delivery and preserve business outcomes when an integration retries or loses an external API response.

SecurityPublished:

A webhook tells an application that an external process has changed: a payment completed, a document became available or a record was updated. The incoming request may trigger an action with a meaningful cost of failure. Its handler must answer separate questions about the sender, message integrity and the effect of receiving the same information again.

Verify before changing business data

Signature verification needs the original request bytes and the secret for the relevant connection. GitHub's documentation describes HMAC verification and secure comparison. Parsing JSON and serializing it again is unsuitable for recreating the signed input: whitespace and field ordering may change.

Verify the request before starting its business operation. The endpoint also needs request-size and processing-time limits. A valid signature establishes message integrity under the provider's protocol; it does not remove the need to validate the event type, data structure and ownership of the referenced object.

For example, a hypothetical payment handler must identify the order and decide whether the proposed state transition is allowed. A signed event should not grant permission to alter any order arbitrarily. This is a design scenario, not a claim about a particular customer implementation.

Separate malicious replays from delivery retries

An attacker may resend a previously captured signed message. Stripe includes a timestamp in the signed data and describes checking its age. That mechanism relies on accurate server time and the provider's protocol. Do not assume it applies to another service that does not sign a timestamp.

Legitimate repeated delivery also occurs when a sender misses an acknowledgement. GitHub's best practices use delivery identifiers to recognize a repeat. Retaining those identifiers helps, but the business action needs its own protection. Separate events may refer to one underlying operation, so that operation should have a stable identity.

A delivery identifier also needs a defined retention period. Expiring it immediately after processing allows later duplicates to look new. Keeping everything forever creates a storage and privacy obligation. Choose the policy from the provider's retry behavior and the consequences of repeating the action.

Persist accepted work before acknowledging it

One practical design verifies the request, durably records accepted work and then delegates execution to a worker. Acknowledge after persistence; otherwise a failure between the response and the write may lose the event. A queue still requires handling storage errors and monitoring processing delays.

Useful operation states include accepted, running, completed and awaiting review. Transitions must support retries and concurrent workers. A simple check-then-insert sequence can allow two simultaneous requests through. An atomic uniqueness constraint and coordinated state changes are needed to make duplicate handling reliable.

The difficult boundary is an external action that succeeds before its response is lost. Marking work complete beforehand can lose the action; marking it afterward can repeat it. Where the external API supports an idempotency key, reuse the operation's stable key. Where it does not, the design needs reconciliation and an explicit uncertain-outcome state.

Test the boundaries that cause ambiguity

Acceptance scenarios should include a changed body, invalid signature, repeated event and simultaneous deliveries. Also exercise queue failure, worker restart and a lost external response. These scenarios reveal considerably more than a single successful notification.

Logs should expose an event identifier, state and rejection reason. Full payloads may contain personal data, so retaining them needs a separate decision. An operator benefits from a task that can be reconciled and safely retried rather than an unexplained technical payload.

API integration planning should define how uncertain outcomes are handled. This establishes which failures can recover automatically and where a person must verify the result.

Sources checked on 7 October 2026. Provider protocols differ. The state model and acceptance scenarios are the author's recommendations to adapt to a specific integration.

Dent-Picks offers a practical context: I implemented creation of a GoHighLevel lead after an incoming IVR call, alongside other synchronization work. The result is a record the team can act on. It provides specific questions about repeated events and data ownership. The public case does not disclose message transport or signature validation; this article's requirements should not be read as implemented controls in that project.

My document, CRM and task workflow guide examines stable identifiers and retries after timeouts. Read it alongside the signature requirements: establishing the sender and preserving one business result call for separate checks.

Sources