fygaro-webhook
Webhook signature verification for Fygaro — pure Python stdlib, zero runtime deps
This helper validates the Fygaro-Signature header of incoming webhooks.
It supports secret rotation (multiple active secrets), deterministic unit‑testing, and is ready for future
hash algorithms.
Installation
pip install fygaro-webhook
Requires Python ≥ 3.8.
Quick start
from fygaro.webhook import FygaroWebhookValidator
validator = FygaroWebhookValidator(
secrets=[
"my-primary-secret", # str or bytes
# "my-previous-secret", # include during rotation windows
]
)
if not validator.verify_signature(
signature_header=request.headers["Fygaro-Signature"],
body=request.body, # raw bytes exactly as sent
):
raise ValueError("Invalid signature")
# …process JSON, return 200…
Opt-in: detailed error handling
from fygaro.webhook import FygaroWebhookValidator, SignatureVerificationError
validator = FygaroWebhookValidator(
secrets=["my-primary-secret"],
raise_exceptions=True, # Opt-in to detailed errors
)
try:
validator.verify_signature(
signature_header=request.headers["Fygaro-Signature"],
body=request.body,
)
except SignatureVerificationError as exc:
logger.warning("Webhook rejected: %s", exc)
return 400
API reference
class FygaroWebhookValidator
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
secrets |
Sequence[str | bytes] |
✔ | — | One or more active webhook secrets. Provide all currently valid secrets during a rotation window. Each secret can be a UTF‑8 str or raw bytes. |
max_age |
int |
✖ | 300 |
Maximum allowable clock skew (in seconds) between the timestamp in the header and the server time. A low value mitigates replay attacks |
unsafe_skip_ts_validation |
bool |
✖ | False |
Test only. When True, the timestamp‑freshness check is skipped and a RuntimeWarning is emitted on instantiation. Never enable in production. |
raise_exceptions |
bool |
✖ | False |
When True, verify_signature raises specific subclasses of SignatureVerificationError instead of returning False. |
validator.verify_signature(signature_header: str, body: bytes) -> bool
| Argument | Type | Description |
|---|---|---|
signature_header |
str |
The exact value of the incoming Fygaro‑Signature HTTP header. |
body |
bytes |
The unmodified request body (raw bytes). Do not .decode() or re‑serialize. |
Return value:
True— signature is valid and timestamp is withinmax_age(unless skipped).False— signature mismatch, stale timestamp, or malformed header.
Exceptions exposed at package root
SignatureVerificationError– base classMissingHeaderErrorTimestampInvalidErrorTimestampExpiredErrorSignatureMismatchError
Writing deterministic unit tests
To keep fixtures stable you can bypass the timestamp‑freshness check without touching production code:
validator = FygaroWebhookValidator(
secrets=[b"test-secret"],
unsafe_skip_ts_validation=True, # ← test‑only flag
)
The first instance created with unsafe_skip_ts_validation=True emits a
RuntimeWarning to remind you that this path is unsafe for live traffic.
License
MIT © Fygaro — support: support@fygaro.com
Changelog – @fygaro/webhook
[1.2.0] – 2025-07-10
Added
raise_exceptionsconstructor flag – opt-in detailed failure reasons without breaking the legacyTrue/Falsereturn contract.
[1.1.0] – 2025-07-10
Added
unsafe_skip_ts_validationconstructor flag that bypasses the timestamp-freshness check. Meant only for local/unit tests; not safe for production. Emits aRuntimeWarningthe first time an instance is created with the flag enabled, to minimise accidental misuse.
[1.0.0] – 2025-06-19
Added
- Initial release with
FygaroWebhookValidatorclass. - Supports multiple secrets & multiple
v1=hashes. - Constant-time compare and configurable timestamp window.
Metadata
Release files for fygaro-webhook 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| fygaro_webhook-1.2.0.tar.gz | 8.0 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fygaro_webhook-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.5 kB
Release files / fygaro_webhook-1.2.0.tar.gz
| Download URL | fygaro_webhook-1.2.0.tar.gz |
|---|---|
| Size | 8.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
abffbff5692578fe3b605ad2cc0cdadd80e257b88f21bb47efae4578c8defe5b
|
|
BLAKE2b-256 checksum How to use checksums |
4d1a2e486f2f43fcf3540e72055440caf1220ceb964a63f0ab3ee4ba4afe9f1d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 11, 2025.
Transparency logRelease files / fygaro_webhook-1.2.0-py3-none-any.whl
| Download URL | fygaro_webhook-1.2.0-py3-none-any.whl |
|---|---|
| Size | 7.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
411e32d20c39508980e89c6720feb3d9cacc2a7c0675d3ea4d347cbc574ced7e
|
|
BLAKE2b-256 checksum How to use checksums |
857a6f4fb60a7e8a7f864e9d2df4e655ce40f6505eb990345891699cf0b042de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 11, 2025.
Transparency logSecurity for fygaro-webhook 1.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for fygaro_webhook-1.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 11, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.