Documentation
¶
Overview ¶
Package webhookverify provides tiny, dependency-free HMAC webhook verifiers - the Go twin of github.com/JacobStephens2/webhook-verify.
Every provider's scheme is the same primitive - a shared secret, an HMAC over bytes both sides can reconstruct, a constant-time compare - in one of three dialects: raw body (GitHub-style), timestamped with replay tolerance (Stripe-style), and URL + sorted params (Twilio, Mandrill).
Every verifier returns a bool and treats a missing or malformed header as false - nothing panics on attacker-controlled input.
Index ¶
- func SafeEqual(a, b string) bool
- func SignBody(rawBody []byte, secret string, opts *BodyOptions) string
- func SignTimestamped(rawBody []byte, secret string, timestampSeconds int64) string
- func VerifyBody(rawBody []byte, signature, secret string, opts *BodyOptions) bool
- func VerifyGitHub(rawBody []byte, header, secret string) bool
- func VerifyMandrill(url string, params map[string]string, header, webhookKey string) bool
- func VerifyTimestamped(rawBody []byte, header, secret string, opts *TimestampedOptions) bool
- func VerifyTwilio(url string, params map[string]string, header, authToken string) bool
- type Algorithm
- type BodyOptions
- type Encoding
- type TimestampedOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SafeEqual ¶
SafeEqual reports whether two strings are equal, in constant time. Length differences return false immediately - length is not a secret in any scheme here.
func SignBody ¶
func SignBody(rawBody []byte, secret string, opts *BodyOptions) string
SignBody is the raw-body dialect, producer side: an HMAC over the exact bytes you send. Pair with VerifyBody on the receiving service. A nil opts means HMAC-SHA256, hex-encoded.
func SignTimestamped ¶
SignTimestamped is the timestamped dialect, producer side: Stripe-style "t=<unix>,v1=<hex>" where the signed payload is "<t>.<rawBody>". The timestamp is what gives the receiver a replay defense.
func VerifyBody ¶
func VerifyBody(rawBody []byte, signature, secret string, opts *BodyOptions) bool
VerifyBody is the raw-body dialect, receiver side. rawBody must be the unparsed request bytes - verifying a re-serialized parse is the classic way this fails.
func VerifyGitHub ¶
VerifyGitHub verifies GitHub's X-Hub-Signature-256 header: "sha256=" + hex HMAC-SHA256 of the raw body, keyed with the webhook secret.
func VerifyMandrill ¶
VerifyMandrill verifies Mandrill's X-Mandrill-Signature: same construction as Twilio's, keyed with the webhook key from the Mandrill webhook settings page. The signed URL is the webhook URL exactly as configured in Mandrill.
func VerifyTimestamped ¶
func VerifyTimestamped(rawBody []byte, header, secret string, opts *TimestampedOptions) bool
VerifyTimestamped is the timestamped dialect, receiver side. Accepts multiple v1 entries in one header (sent during key rotation); any single match passes. Rejects timestamps outside the tolerance window in either direction.
func VerifyTwilio ¶
VerifyTwilio verifies Twilio's X-Twilio-Signature: base64 HMAC-SHA1 over the URL + sorted params base, keyed with the account's auth token. url must be the public URL Twilio called, query string included - not what your app sees behind a proxy.
Types ¶
type BodyOptions ¶
BodyOptions configures the raw-body dialect. The zero value (and a nil pointer) means HMAC-SHA256, hex-encoded.
type Encoding ¶
type Encoding int
Encoding selects how the HMAC digest is encoded into the signature string. The zero value is Hex.
type TimestampedOptions ¶
type TimestampedOptions struct {
// Tolerance is the maximum allowed age (and future clock skew),
// truncated to whole seconds. Zero means the default, 5 minutes.
Tolerance time.Duration
// Now is an injectable clock for tests. The zero value means time.Now().
Now time.Time
}
TimestampedOptions configures VerifyTimestamped. The zero value (and a nil pointer) means a 5-minute tolerance and the real clock.