How to receive webhooks safely in Python services with verified signatures, bounded replay windows, idempotent processing and observable delivery outcomes.

Production principle

Verify the raw payload before parsing it, reject stale or repeated deliveries deliberately and make processing idempotent at the database boundary.

01

Verify the message you actually received

Signature schemes usually cover the exact bytes and a timestamp. Parsing JSON and reserializing it before verification can change whitespace, ordering or encoding and invalidate the security decision. Read the raw body once, verify it with a constant-time comparison and only then decode it.

Keep signing secrets scoped to the provider and environment. Rotate them without making all in-flight deliveries unverifiable, and record which key version accepted a message without logging the secret or full payload.

02

Make replay a defined case

A valid signature does not prove freshness. Include a timestamp tolerance and a durable event identifier or digest. Store the identifier with a uniqueness constraint before applying an irreversible effect so concurrent deliveries cannot both pass an in-memory check.

If the provider retries a request while processing is still running, return a deliberate response and let the worker or state machine own completion. Do not acknowledge work merely because the HTTP handler accepted bytes.

03

Test failure and delivery evidence

Test invalid signatures, stale timestamps, duplicate events, malformed payloads and provider retries. Assert both the HTTP contract and the durable state after each case.

Track accepted, rejected, duplicate and failed deliveries separately. Without those outcomes, an apparent webhook outage can be confused with a provider retry storm or an application bug.

Review checklist

Evidence to take into review

  • Raw payloads are verified before parsing.
  • Timestamps and event identifiers limit replay.
  • Duplicate processing is protected by a durable constraint.
  • Secret rotation and key identity are observable.
  • Failure and retry outcomes have integration tests and metrics.
ShareLinkedInX
Continue the inspection

Explore all engineering notes.

Use PRODUCTION-7 to connect this concern with the other dimensions of a trustworthy backend.

View all articles Get the checklist