webhook is a protocol-independent Go module for exact-byte webhook
verification, replay protection, deterministic outbound signing, and bounded
delivery. It uses net/http, HMAC-SHA-256 or HMAC-SHA-512, explicit clocks and
limits, and no production unsafe or cgo.
The module does not claim support for any vendor preset. The generic v1
scheme is specified by the signature reference and has
independently generated Python fixtures in testdata/vectors/v1.json.
Protocol ambiguities and application policies are recorded in the
specification decision register against the
pinned source manifest.
go get github.com/faustbrian/go-webhookGo 1.26 or newer is required because the optional published outbox
adapter requires it.
verifier, err := webhook.NewVerifier(webhook.VerifierConfig{
Algorithm: webhook.SHA256,
Keys: []webhook.VerificationKey{{ID: "2026-07", Secret: secret}},
Tolerance: 5 * time.Minute,
})
if err != nil { return err }
handler, err := verifier.Middleware(webhook.MiddlewareConfig{
Request: webhook.RequestOptions{
MaxBodyBytes: 1 << 20,
HeaderLimits: webhook.HeaderLimits{MaxSignatures: 2, MaxBytes: 1024},
},
}, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, _ := webhook.VerifiedBodyFromContext(r.Context())
_ = body // decode only after verification
w.WriteHeader(http.StatusNoContent)
}))
if err != nil { return err }When replay protection is configured, provide an atomic ReplayStore and an
event-ID extractor. See the inbound guide.
Construct a Signer, a strict SSRFPolicy, and a Deliverer. A delivery must
have an endpoint and event ID. More than one attempt additionally requires an
idempotency key. Redirects are never followed by NewSecureHTTPClient.
See the outbound guide and executable examples in
example_test.go.
Optional packages integrate idempotency, log, telemetry,
queue, and outbox. webhooktest supplies deterministic consumer
fixtures.
- exact received bytes are hashed before application decoding;
- every signing operation uses a signed, injectable random nonce;
- signature comparison uses
hmac.Equal; - malformed or duplicate signature fields are rejected deterministically;
- replay storage is atomic and fails closed;
- request, response, header, attempt, DNS, and fan-out work are bounded;
- endpoint policy is checked before every attempt and again at dial time;
- observations exclude payloads, signatures, event IDs, keys, and URLs.
- API and compatibility
- Inbound verification and raw bodies
- Signatures, canonicalization, timestamps, and rotation
- Specification decisions and non-conformance boundaries
- Replay and idempotency
- Delivery, retries, dead letters, and replay
- Threat model and SSRF policy
- Adapters and observability
- Providers and interoperability
- Audit matrices and evidence
- Operations and troubleshooting
- Release verdict
- Migration and SemVer
- FAQ
make check
make safety
make interoperability
make conformanceSecurity reports follow SECURITY.md. Contributions follow CONTRIBUTING.md. The project is MIT licensed. Dependency attribution is recorded in THIRD_PARTY_NOTICES.md.