go-service

🪝 Webhooks (Standard Webhooks)

← Back to README

Configured via hooks.Config:

hooks:
  key: current
  secrets:
    current: env:WEBHOOK_SECRET_CURRENT
    previous: env:WEBHOOK_SECRET_PREVIOUS
  leeway: 30s

Each secrets value is a source string. The resolved value must be accepted by the Standard Webhooks library, such as a secret generated by hooks.Generator with or without the whsec_ prefix. Empty resolved secrets fail startup.

Signing uses the active key. Verification accepts signatures from every configured secret, trying the active secret first. Standard Webhooks includes a message id (Webhook-Id) but not a signing key id, so go-service does not extend the protocol with a custom selector header.

leeway is optional clock-skew tolerance applied to the Webhook-Timestamp freshness check during verification. A zero value (the default) keeps the Standard Webhooks library’s fixed 5-minute freshness window; a non-zero value replaces that fixed window with this configured tolerance, matching the clock-skew leeway already exposed by the JWT and PASETO token verifiers. Like those, leeway is a Go duration string and must be a positive whole-second duration.

Inbound verification checks Standard Webhooks signatures and timestamps, but does not store or reject previously seen webhook ids. Receivers that perform non-idempotent work should deduplicate or process idempotently using Webhook-Id or the event id, backed by durable shared storage when running more than one receiver instance.

[!IMPORTANT] Webhook-protected CloudEvents must use structured HTTP encoding. Binary-mode CloudEvents with ce-* headers are rejected before signature verification.