Securing webhooks with HMAC signatures and replay protection

Django Interview Q&A November 13, 2026 python

HMAC-SHA256 signature of the body together with a timestamp, comparison with hmac.compare_digest (constant time), rejection if the timestamp is old (replay protection), idempotent processing using the event id, a fast 2xx response and processing in Celery

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# ======================================================================
# Q: How do you secure webhooks (incoming and outgoing)?
#
# HMAC-SHA256 signature of the body together with a timestamp, comparison with
# hmac.compare_digest (constant time), rejection if the timestamp is old (replay
# protection), idempotent processing using the event id, a fast 2xx response and
# processing in Celery.
# ======================================================================

def verify(request, secret: bytes) -> bool:
    ts = request.headers['X-Timestamp']
    if abs(time.time() - int(ts)) > 300:
        return False
    expected = hmac.new(secret, ts.encode() + b'.' + request.body,
                        hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, request.headers['X-Signature'])