Documentation
¶
Overview ¶
Package webhook verifies bounded original webhook bytes before typed decoding. Verified identities are bound to a configured provider/account and are not a replacement for current domain authorization or durable idempotency.
Index ¶
- Constants
- Variables
- type Config
- type Delivery
- type DeliveryID
- type HMACAlgorithm
- type HMACScheme
- type Protocol
- type Provider
- type SignatureEncoding
- type Verifier
- func (Verifier[A]) Format(state fmt.State, _ rune)
- func (v *Verifier[A]) FromContext(ctx context.Context) (Delivery[A], bool)
- func (v *Verifier[A]) Validate() error
- func (v *Verifier[A]) Verify(ctx context.Context, headers http.Header, body []byte) (Delivery[A], error)
- func (v *Verifier[A]) VerifyRequest(r *http.Request) (Delivery[A], error)
- func (v *Verifier[A]) WithDelivery(ctx context.Context, d Delivery[A]) (context.Context, error)
Constants ¶
const ( SHA256 HMACAlgorithm = "sha256" SHA512 HMACAlgorithm = "sha512" // SHA1 exists only for legacy providers; prefer SHA256 when offered. SHA1 HMACAlgorithm = "sha1" Hex SignatureEncoding = "hex" Base64 SignatureEncoding = "base64" )
Variables ¶
var ( InvalidSignature = safeerror.New("webhook signature or freshness is invalid") BodyTooLarge = safeerror.New("webhook body exceeds its configured limit") )
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
Provider Provider
Protocol Protocol
MaxBodyBytes int64
Tolerance time.Duration
// HMAC configures the HMAC protocol and must be zero for the others.
HMAC HMACScheme
}
Config selects the provider, signature protocol and verification bounds.
func DefaultConfig ¶
DefaultConfig returns verification settings with a one-megabyte body limit and five-minute timestamp tolerance.
func GitHubConfig ¶
GitHubConfig verifies X-Hub-Signature-256 (hex HMAC-SHA256 of the body). GitHub signs no timestamp or ID: the delivery ID is the body digest and X-GitHub-Delivery is unverified metadata.
func ShopifyConfig ¶
ShopifyConfig verifies X-Shopify-Hmac-Sha256 (base64 HMAC-SHA256 of the body). Shopify signs no timestamp or ID: the delivery ID is the body digest and X-Shopify-Webhook-Id is unverified metadata.
func SlackConfig ¶
SlackConfig verifies X-Slack-Signature ("v0=" hex HMAC-SHA256 of "v0:{X-Slack-Request-Timestamp}:{body}") with freshness checking. Slack sends no delivery header; the delivery ID digests the signed timestamp and body.
type Delivery ¶
type Delivery[A any] struct { // contains filtered or unexported fields }
Delivery contains only signature-authenticated metadata and the configured account. Its unexported proof prevents construction of a verified zero value.
func (Delivery[A]) Account ¶
func (d Delivery[A]) Account() A
Account returns the verifier's account, or its zero value for an uninitialized delivery.
func (Delivery[A]) ID ¶
func (d Delivery[A]) ID() DeliveryID
ID returns the verified delivery identifier.
func (Delivery[A]) Provider ¶
Provider returns the verifier's provider, or an empty provider for an uninitialized delivery.
func (Delivery[A]) UnverifiedProviderID ¶
UnverifiedProviderID returns the provider's delivery header of an HMAC scheme (for example X-GitHub-Delivery). The signature does not cover it, so it is diagnostic metadata only: never use it for deduplication or authorization. ID is the authenticated identity.
type DeliveryID ¶
type DeliveryID string
DeliveryID identifies a webhook delivery within its provider.
type HMACScheme ¶
type HMACScheme struct {
SignatureHeader string
Prefix string
Algorithm HMACAlgorithm
Encoding SignatureEncoding
TimestampHeader string
PayloadPrefix string
Separator string
DeliveryHeader string
}
HMACScheme describes a provider's HMAC signature. SignatureHeader carries one signature, optionally after Prefix (for example "sha256="). The signed content is the exact body, or, with TimestampHeader, PayloadPrefix + timestamp + Separator + body (Slack signs "v0:" + timestamp + ":" + body). A timestamp is Unix seconds checked against Config.Tolerance; without one no freshness check is possible. The delivery ID is always "sha256-" + the digest of the verified signed content, because these schemes sign no ID: durable idempotency then rejects replays of identical signed content, but a provider that legitimately resends an identical body without a signed timestamp is indistinguishable from a replay. DeliveryHeader names an optional provider delivery header exposed only as Delivery.UnverifiedProviderID. Endpoint secrets are used verbatim as HMAC keys.
type SignatureEncoding ¶
type SignatureEncoding string
SignatureEncoding selects the textual representation of a signature digest.
type Verifier ¶
type Verifier[A any] struct { // contains filtered or unexported fields }
Verifier retains immutable configuration and a bounded rotation keyring. Use separate endpoint secrets for each account; account comes from trusted setup, never from an unsigned header. Account values should be immutable domain IDs.
func New ¶
func New[A any](config Config, account A, keys []secret.String, source clock.Clock) (*Verifier[A], error)
New supports Standard Webhooks whsec_ HMAC keys and whpk_ Ed25519 public keys, Stripe endpoint secrets, or HMAC-protocol secrets (both used verbatim). No keys are loaded from requests.
func (*Verifier[A]) FromContext ¶
FromContext returns typed metadata attached by this exact verifier. It is not a credential and does not authorize future requests or application resources.
func (*Verifier[A]) Validate ¶
Validate checks that keys and a clock are configured and validates verification settings.
func (*Verifier[A]) Verify ¶
func (v *Verifier[A]) Verify(ctx context.Context, headers http.Header, body []byte) (Delivery[A], error)
Verify authenticates the original bytes. It intentionally permits a valid duplicate within the freshness window; use existing idempotency for effects.
func (*Verifier[A]) VerifyRequest ¶
VerifyRequest reads at most MaxBodyBytes+1 bytes, closes the body it reads and restores the exact signed bytes after successful verification for typed decoding. Place it before middleware that transforms/decompresses the body.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package outbound delivers signed webhooks to registered endpoints.
|
Package outbound delivers signed webhooks to registered endpoints. |
|
command
Package command supplies outbound webhook delivery inspection and replay.
|
Package command supplies outbound webhook delivery inspection and replay. |