Skip to main content

HMAC-based webhook signature generation and verification with timing-safe comparison

Project description

philiprehberger-webhook-signature

Tests PyPI version Last updated

HMAC-based webhook signature generation and verification with timing-safe comparison.

Installation

pip install philiprehberger-webhook-signature

Usage

Signing a Payload

from philiprehberger_webhook_signature import sign

signed = sign(payload='{"event": "order.created"}', secret="whsec_abc123")

print(signed.signature)   # HMAC hex digest
print(signed.timestamp)   # Unix timestamp
print(signed.to_header()) # "t=1234567890,sha256=abc..."

Verifying a Signature

from philiprehberger_webhook_signature import verify, parse_header

# Parse the signature header
header = request.headers["X-Webhook-Signature"]
signature, timestamp = parse_header(header)

# Verify (raises on failure)
verify(
    payload=request.body,
    secret="whsec_abc123",
    signature=signature,
    timestamp=timestamp,
    max_age=300.0,  # reject signatures older than 5 minutes
)

Key Rotation

Use verify_with_rotation for zero-downtime secret rotation. It tries the current secret first and falls back to the previous secret if verification fails:

from philiprehberger_webhook_signature import verify_with_rotation, parse_header

header = request.headers["X-Webhook-Signature"]
signature, timestamp = parse_header(header)

verify_with_rotation(
    payload=request.body,
    signature=signature,
    current_secret="whsec_new_secret",
    previous_secret="whsec_old_secret",  # optional fallback
    tolerance=300,
    timestamp=timestamp,
)

Error Handling

from philiprehberger_webhook_signature import (
    verify,
    SignatureError,
    SignatureExpiredError,
    SignatureMismatchError,
)

try:
    verify(payload, secret, signature, timestamp)
except SignatureExpiredError as e:
    print(f"Signature too old: {e.age}s > {e.max_age}s")
except SignatureMismatchError:
    print("Invalid signature")
except SignatureError as e:
    print(f"Verification failed: {e}")

Custom Algorithm

signed = sign(payload="data", secret="secret", algorithm="sha512")
verify(payload="data", secret="secret", signature=sig, timestamp=ts, algorithm="sha512")

Disable Expiry Check

verify(payload, secret, signature, timestamp, max_age=None)

API

Function / Class Description
sign(payload, secret, algorithm, timestamp) Generate an HMAC signature for a webhook payload
verify(payload, secret, signature, timestamp, algorithm, max_age) Verify a webhook signature with timing-safe comparison
verify_with_rotation(payload, signature, current_secret, previous_secret, tolerance, algorithm, timestamp) Verify with key rotation support (tries current then previous secret)
parse_header(header, prefix) Parse a signature header string into (signature, timestamp) tuple
SignedPayload Signed payload with signature, timestamp, body, and to_header()
SignatureError Base exception for signature errors
SignatureExpiredError Raised when signature age exceeds max_age
SignatureMismatchError Raised when signature verification fails

Development

pip install -e .
python -m pytest tests/ -v

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

philiprehberger_webhook_signature-0.2.1.tar.gz (6.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file philiprehberger_webhook_signature-0.2.1.tar.gz.

File metadata

File hashes

Hashes for philiprehberger_webhook_signature-0.2.1.tar.gz
Algorithm Hash digest
SHA256 29571c832632c9918b29804f88bf009528c185db370ba046bc0a12c43d06c904
MD5 9c946e1071c464de700bc0edf2cfcd50
BLAKE2b-256 97af2a0f10c3ad1e171fffebda09d2e14ee72c79c8c6f6538bc67c852190a302

See more details on using hashes here.

File details

Details for the file philiprehberger_webhook_signature-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for philiprehberger_webhook_signature-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 da1f0e8b566522bfa99ea6368f168b19924952ab9f5aec7c0a0b44aa20d42bbb
MD5 b82c9379b78bbab9eb9b64179ce89029
BLAKE2b-256 87b0fc32b1602dbaaf508af18fc498bc96d640a22edf3f9313233da76291d840

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page