Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 22 additions & 18 deletions docs/pages/references/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,17 @@ Global configurations are provided through env variables or a YAML file. ConfigM
| `DESTINATIONS_AWS_KINESIS_METADATA_IN_PAYLOAD` | If true, includes Outpost metadata (event ID, topic, etc.) within the Kinesis record payload. | `true` | No |
| `DESTINATIONS_INCLUDE_MILLISECOND_TIMESTAMP` | If true, includes a 'timestamp-ms' field with millisecond precision in destination metadata. Useful for load testing and debugging. | `false` | No |
| `DESTINATIONS_METADATA_PATH` | Path to the directory containing custom destination type definitions. This can be overridden by the root-level 'destination_metadata_path' if also set. | `config/outpost/destinations` | No |
| `DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_EVENT_ID_HEADER` | If true, disables adding the default 'X-Outpost-Event-Id' header to webhook requests. | `false` | No |
| `DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_SIGNATURE_HEADER` | If true, disables adding the default 'X-Outpost-Signature' header to webhook requests. | `false` | No |
| `DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_TIMESTAMP_HEADER` | If true, disables adding the default 'X-Outpost-Timestamp' header to webhook requests. | `false` | No |
| `DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_TOPIC_HEADER` | If true, disables adding the default 'X-Outpost-Topic' header to webhook requests. | `false` | No |
| `DESTINATIONS_WEBHOOK_HEADER_PREFIX` | Prefix for custom headers added to webhook requests (e.g., 'X-MyOrg-'). | `x-outpost-` | No |
| `DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_EVENT_ID_HEADER` | If true, disables adding the default 'X-Outpost-Event-Id' header to webhook requests. Only applies to 'default' mode. | `false` | No |
| `DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_SIGNATURE_HEADER` | If true, disables adding the default 'X-Outpost-Signature' header to webhook requests. Only applies to 'default' mode. | `false` | No |
| `DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_TIMESTAMP_HEADER` | If true, disables adding the default 'X-Outpost-Timestamp' header to webhook requests. Only applies to 'default' mode. | `false` | No |
| `DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_TOPIC_HEADER` | If true, disables adding the default 'X-Outpost-Topic' header to webhook requests. Only applies to 'default' mode. | `false` | No |
| `DESTINATIONS_WEBHOOK_HEADER_PREFIX` | Prefix for metadata headers added to webhook requests. Defaults to 'x-outpost-' in 'default' mode and 'webhook-' in 'standard' mode. | `x-outpost-` | No |
| `DESTINATIONS_WEBHOOK_MODE` | Webhook mode: 'default' for customizable webhooks or 'standard' for Standard Webhooks specification compliance. Defaults to 'default'. | `nil` | No |
| `DESTINATIONS_WEBHOOK_PROXY_URL` | Proxy URL for routing webhook requests through a proxy server. Supports HTTP and HTTPS proxies. When configured, all outgoing webhook traffic will be routed through the specified proxy. | `nil` | No |
| `DESTINATIONS_WEBHOOK_SIGNATURE_ALGORITHM` | Algorithm used for signing webhook requests (e.g., 'hmac-sha256'). | `hmac-sha256` | No |
| `DESTINATIONS_WEBHOOK_SIGNATURE_CONTENT_TEMPLATE` | Go template for constructing the content to be signed for webhook requests. | `{{.Timestamp.Unix}}.{{.Body}}` | No |
| `DESTINATIONS_WEBHOOK_SIGNATURE_ENCODING` | Encoding for the signature (e.g., 'hex', 'base64'). | `hex` | No |
| `DESTINATIONS_WEBHOOK_SIGNATURE_HEADER_TEMPLATE` | Go template for the value of the signature header. | `t={{.Timestamp.Unix}},v0={{.Signatures \| join ","}}` | No |
| `DESTINATIONS_WEBHOOK_SIGNATURE_ALGORITHM` | Algorithm used for signing webhook requests (e.g., 'hmac-sha256'). Only applies to 'default' mode. | `hmac-sha256` | No |
| `DESTINATIONS_WEBHOOK_SIGNATURE_CONTENT_TEMPLATE` | Go template for constructing the content to be signed for webhook requests. Only applies to 'default' mode. | `{{.Timestamp.Unix}}.{{.Body}}` | No |
| `DESTINATIONS_WEBHOOK_SIGNATURE_ENCODING` | Encoding for the signature (e.g., 'hex', 'base64'). Only applies to 'default' mode. | `hex` | No |
| `DESTINATIONS_WEBHOOK_SIGNATURE_HEADER_TEMPLATE` | Go template for the value of the signature header. Only applies to 'default' mode. | `t={{.Timestamp.Unix}},v0={{.Signatures \| join ","}}` | No |
| `DESTINATION_METADATA_PATH` | Path to the directory containing custom destination type definitions. Overrides 'destinations.metadata_path' if set. | `nil` | No |
| `DISABLE_TELEMETRY` | Global flag to disable all telemetry (anonymous usage statistics to Hookdeck and error reporting to Sentry). If true, overrides 'telemetry.disabled'. | `false` | No |
| `GCP_PUBSUB_DELIVERY_SUBSCRIPTION` | Name of the GCP Pub/Sub subscription for delivery events. | `outpost-delivery-sub` | No |
Expand Down Expand Up @@ -186,34 +187,37 @@ destinations:

# Configuration specific to webhook destinations.
webhook:
# If true, disables adding the default 'X-Outpost-Event-Id' header to webhook requests.
# If true, disables adding the default 'X-Outpost-Event-Id' header to webhook requests. Only applies to 'default' mode.
disable_default_event_id_header: false

# If true, disables adding the default 'X-Outpost-Signature' header to webhook requests.
# If true, disables adding the default 'X-Outpost-Signature' header to webhook requests. Only applies to 'default' mode.
disable_default_signature_header: false

# If true, disables adding the default 'X-Outpost-Timestamp' header to webhook requests.
# If true, disables adding the default 'X-Outpost-Timestamp' header to webhook requests. Only applies to 'default' mode.
disable_default_timestamp_header: false

# If true, disables adding the default 'X-Outpost-Topic' header to webhook requests.
# If true, disables adding the default 'X-Outpost-Topic' header to webhook requests. Only applies to 'default' mode.
disable_default_topic_header: false

# Prefix for custom headers added to webhook requests (e.g., 'X-MyOrg-').
# Prefix for metadata headers added to webhook requests. Defaults to 'x-outpost-' in 'default' mode and 'webhook-' in 'standard' mode.
header_prefix: "x-outpost-"

# Webhook mode: 'default' for customizable webhooks or 'standard' for Standard Webhooks specification compliance. Defaults to 'default'.
mode: ""

# Proxy URL for routing webhook requests through a proxy server. Supports HTTP and HTTPS proxies. When configured, all outgoing webhook traffic will be routed through the specified proxy.
proxy_url: ""

# Algorithm used for signing webhook requests (e.g., 'hmac-sha256').
# Algorithm used for signing webhook requests (e.g., 'hmac-sha256'). Only applies to 'default' mode.
signature_algorithm: "hmac-sha256"

# Go template for constructing the content to be signed for webhook requests.
# Go template for constructing the content to be signed for webhook requests. Only applies to 'default' mode.
signature_content_template: "{{.Timestamp.Unix}}.{{.Body}}"

# Encoding for the signature (e.g., 'hex', 'base64').
# Encoding for the signature (e.g., 'hex', 'base64'). Only applies to 'default' mode.
signature_encoding: "hex"

# Go template for the value of the signature header.
# Go template for the value of the signature header. Only applies to 'default' mode.
signature_header_template: "t={{.Timestamp.Unix}},v0={{.Signatures | join \",\"}}"


Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ require (
github.com/redis/go-redis/v9 v9.6.1
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
github.com/spf13/viper v1.19.0
github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20250711233419-a173a6c0125c
github.com/stretchr/testify v1.10.0
github.com/testcontainers/testcontainers-go v0.36.0
github.com/testcontainers/testcontainers-go/modules/clickhouse v0.33.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20250711233419-a173a6c0125c h1:Mm99t6GdFMtZOwyyvu3q8gXeZX0sqnjvimTC9QCJwQc=
github.com/standard-webhooks/standard-webhooks/libraries v0.0.0-20250711233419-a173a6c0125c/go.mod h1:L1MQhA6x4dn9r007T033lsaZMv9EmBAdXyU/+EF40fo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand Down
24 changes: 15 additions & 9 deletions internal/config/destinations.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,27 @@ type DestinationWebhookConfig struct {
// ProxyURL may contain authentication credentials (e.g., http://user:pass@proxy:8080)
// and should be treated as sensitive.
// TODO: Implement sensitive value handling - https://github.com/hookdeck/outpost/issues/480
Mode string `yaml:"mode" env:"DESTINATIONS_WEBHOOK_MODE" desc:"Webhook mode: 'default' for customizable webhooks or 'standard' for Standard Webhooks specification compliance. Defaults to 'default'." required:"N"`
ProxyURL string `yaml:"proxy_url" env:"DESTINATIONS_WEBHOOK_PROXY_URL" desc:"Proxy URL for routing webhook requests through a proxy server. Supports HTTP and HTTPS proxies. When configured, all outgoing webhook traffic will be routed through the specified proxy." required:"N"`
HeaderPrefix string `yaml:"header_prefix" env:"DESTINATIONS_WEBHOOK_HEADER_PREFIX" desc:"Prefix for custom headers added to webhook requests (e.g., 'X-MyOrg-')." required:"N"`
DisableDefaultEventIDHeader bool `yaml:"disable_default_event_id_header" env:"DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_EVENT_ID_HEADER" desc:"If true, disables adding the default 'X-Outpost-Event-Id' header to webhook requests." required:"N"`
DisableDefaultSignatureHeader bool `yaml:"disable_default_signature_header" env:"DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_SIGNATURE_HEADER" desc:"If true, disables adding the default 'X-Outpost-Signature' header to webhook requests." required:"N"`
DisableDefaultTimestampHeader bool `yaml:"disable_default_timestamp_header" env:"DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_TIMESTAMP_HEADER" desc:"If true, disables adding the default 'X-Outpost-Timestamp' header to webhook requests." required:"N"`
DisableDefaultTopicHeader bool `yaml:"disable_default_topic_header" env:"DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_TOPIC_HEADER" desc:"If true, disables adding the default 'X-Outpost-Topic' header to webhook requests." required:"N"`
SignatureContentTemplate string `yaml:"signature_content_template" env:"DESTINATIONS_WEBHOOK_SIGNATURE_CONTENT_TEMPLATE" desc:"Go template for constructing the content to be signed for webhook requests." required:"N"`
SignatureHeaderTemplate string `yaml:"signature_header_template" env:"DESTINATIONS_WEBHOOK_SIGNATURE_HEADER_TEMPLATE" desc:"Go template for the value of the signature header." required:"N"`
SignatureEncoding string `yaml:"signature_encoding" env:"DESTINATIONS_WEBHOOK_SIGNATURE_ENCODING" desc:"Encoding for the signature (e.g., 'hex', 'base64')." required:"N"`
SignatureAlgorithm string `yaml:"signature_algorithm" env:"DESTINATIONS_WEBHOOK_SIGNATURE_ALGORITHM" desc:"Algorithm used for signing webhook requests (e.g., 'hmac-sha256')." required:"N"`
HeaderPrefix string `yaml:"header_prefix" env:"DESTINATIONS_WEBHOOK_HEADER_PREFIX" desc:"Prefix for metadata headers added to webhook requests. Defaults to 'x-outpost-' in 'default' mode and 'webhook-' in 'standard' mode." required:"N"`
DisableDefaultEventIDHeader bool `yaml:"disable_default_event_id_header" env:"DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_EVENT_ID_HEADER" desc:"If true, disables adding the default 'X-Outpost-Event-Id' header to webhook requests. Only applies to 'default' mode." required:"N"`
DisableDefaultSignatureHeader bool `yaml:"disable_default_signature_header" env:"DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_SIGNATURE_HEADER" desc:"If true, disables adding the default 'X-Outpost-Signature' header to webhook requests. Only applies to 'default' mode." required:"N"`
DisableDefaultTimestampHeader bool `yaml:"disable_default_timestamp_header" env:"DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_TIMESTAMP_HEADER" desc:"If true, disables adding the default 'X-Outpost-Timestamp' header to webhook requests. Only applies to 'default' mode." required:"N"`
DisableDefaultTopicHeader bool `yaml:"disable_default_topic_header" env:"DESTINATIONS_WEBHOOK_DISABLE_DEFAULT_TOPIC_HEADER" desc:"If true, disables adding the default 'X-Outpost-Topic' header to webhook requests. Only applies to 'default' mode." required:"N"`
SignatureContentTemplate string `yaml:"signature_content_template" env:"DESTINATIONS_WEBHOOK_SIGNATURE_CONTENT_TEMPLATE" desc:"Go template for constructing the content to be signed for webhook requests. Only applies to 'default' mode." required:"N"`
SignatureHeaderTemplate string `yaml:"signature_header_template" env:"DESTINATIONS_WEBHOOK_SIGNATURE_HEADER_TEMPLATE" desc:"Go template for the value of the signature header. Only applies to 'default' mode." required:"N"`
SignatureEncoding string `yaml:"signature_encoding" env:"DESTINATIONS_WEBHOOK_SIGNATURE_ENCODING" desc:"Encoding for the signature (e.g., 'hex', 'base64'). Only applies to 'default' mode." required:"N"`
SignatureAlgorithm string `yaml:"signature_algorithm" env:"DESTINATIONS_WEBHOOK_SIGNATURE_ALGORITHM" desc:"Algorithm used for signing webhook requests (e.g., 'hmac-sha256'). Only applies to 'default' mode." required:"N"`
}

// toConfig converts WebhookConfig to the provider config - private since it's only used internally
func (c *DestinationWebhookConfig) toConfig() *destregistrydefault.DestWebhookConfig {
mode := c.Mode
if mode == "" {
mode = "default"
}
return &destregistrydefault.DestWebhookConfig{
Mode: mode,
ProxyURL: c.ProxyURL,
HeaderPrefix: c.HeaderPrefix,
DisableDefaultEventIDHeader: c.DisableDefaultEventIDHeader,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Webhook Configuration Instructions

To receive events from the webhook destination, you need to set up a webhook endpoint.

A webhook endpoint is a URL that you provide to an HTTP server. When an event is sent to the webhook destination, an HTTP POST request is made to the webhook endpoint with a JSON payload. Information such as the event type will be sent in the HTTP headers.

## Verifying Webhook Signatures

Webhooks include a cryptographic signature for security. To verify:

1. Extract the `webhook-id`, `webhook-timestamp`, and `webhook-signature` headers
2. Construct the signed content: `${webhook-id}.${webhook-timestamp}.${raw_body}`
3. Decode your `whsec_` secret (remove prefix and base64 decode)
4. Compute HMAC-SHA256 signature and compare

Verification libraries are available at: https://github.com/standard-webhooks
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "webhook",
"config_fields": [
{
"key": "url",
"type": "text",
"label": "Webhook URL",
"description": "The URL to send webhook events to via HTTP POST (Standard Webhooks compliant)",
"required": true,
"pattern": "^https?:\\/\\/[\\w\\-]+(?:\\.[\\w\\-]+)*(?::\\d{1,5})?(?:\\/[\\w\\-\\/\\.~:?#\\[\\]@!$&'\\(\\)*+,;=]*)?$"
}
],
"credential_fields": [],
"label": "Webhook",
"link": "https://hookdeck.com/webhooks/guides/what-are-webhooks-how-they-work",
"description": "Send events as webhooks (HTTP POST).",
"icon": "<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.79861 14.4C3.91361 14.4 3.15917 14.088 2.53528 13.464C1.9115 12.84 1.59961 12.0854 1.59961 11.2C1.59961 10.6222 1.7385 10.0861 2.01628 9.59169C2.29405 9.09725 2.68294 8.71114 3.18294 8.43336C3.38294 8.31114 3.58572 8.30836 3.79128 8.42502C3.99683 8.54169 4.09961 8.71747 4.09961 8.95236C4.09961 9.0698 4.06905 9.17653 4.00794 9.27253C3.94683 9.36864 3.86628 9.44447 3.76628 9.50002C3.46628 9.68891 3.23017 9.93025 3.05794 10.224C2.88572 10.5179 2.79961 10.8432 2.79961 11.2C2.79961 11.7556 2.99405 12.2278 3.38294 12.6167C3.77183 13.0056 4.24405 13.2 4.79961 13.2C5.35517 13.2 5.82739 13.0056 6.21628 12.6167C6.60517 12.2278 6.79961 11.7556 6.79961 11.2C6.79961 11.0334 6.86072 10.8917 6.98294 10.775C7.10517 10.6584 7.24961 10.6 7.41628 10.6H10.6663C10.7329 10.5334 10.8135 10.4834 10.9079 10.45C11.0024 10.4167 11.0996 10.4 11.1996 10.4C11.4218 10.4 11.6107 10.4778 11.7663 10.6334C11.9218 10.7889 11.9996 10.9778 11.9996 11.2C11.9996 11.4222 11.9218 11.6111 11.7663 11.7667C11.6107 11.9222 11.4218 12 11.1996 12C11.0996 12 11.0024 11.9861 10.9079 11.9584C10.8135 11.9306 10.7329 11.8778 10.6663 11.8H7.94961C7.82739 12.5667 7.46628 13.1917 6.86628 13.675C6.26628 14.1584 5.57705 14.4 4.79861 14.4ZM4.79961 12C4.57739 12 4.3885 11.9222 4.23294 11.7667C4.07739 11.6111 3.99961 11.4222 3.99961 11.2C3.99961 11.0189 4.04961 10.8625 4.14961 10.7309C4.24961 10.5992 4.37739 10.5056 4.53294 10.45L6.16628 7.92102C5.84405 7.62925 5.60239 7.2778 5.44128 6.86669C5.28017 6.45558 5.19961 6.03336 5.19961 5.60002C5.19961 4.71469 5.51161 3.96002 6.13561 3.33602C6.75961 2.71202 7.51428 2.40002 8.39961 2.40002C9.12183 2.40002 9.76628 2.61669 10.3329 3.05002C10.8996 3.48336 11.2774 4.05002 11.4663 4.75002C11.5218 4.94002 11.4897 5.11252 11.3699 5.26752C11.2502 5.42252 11.0934 5.50002 10.8996 5.50002C10.7552 5.50002 10.6285 5.45202 10.5196 5.35602C10.4108 5.26014 10.3375 5.14147 10.2996 5.00002C10.1774 4.5778 9.94128 4.23891 9.59128 3.98336C9.24128 3.7278 8.84405 3.60002 8.39961 3.60002C7.84405 3.60002 7.37183 3.79447 6.98294 4.18336C6.59405 4.57225 6.39961 5.04447 6.39961 5.60002C6.39961 5.95558 6.48572 6.29169 6.65794 6.60836C6.83017 6.92502 7.07183 7.17225 7.38294 7.35002C7.50517 7.4278 7.5885 7.5278 7.63294 7.65002C7.67739 7.77225 7.66628 7.89447 7.59961 8.01669L5.59961 11.1334C5.59961 11.3667 5.52183 11.5695 5.36628 11.7417C5.21072 11.9139 5.02183 12 4.79961 12ZM11.1989 14.4C10.9216 14.4 10.6524 14.3667 10.3913 14.3C10.1302 14.2334 9.88294 14.1334 9.64961 14C9.37183 13.8445 9.27183 13.6195 9.34961 13.325C9.42739 13.0306 9.61628 12.8834 9.91628 12.8834C10.0052 12.8834 10.0885 12.8945 10.1663 12.9167C10.2441 12.9389 10.3218 12.9722 10.3996 13.0167C10.5218 13.0722 10.649 13.1167 10.7811 13.15C10.9133 13.1834 11.0528 13.2 11.1996 13.2C11.7552 13.2 12.2274 13.0056 12.6163 12.6167C13.0052 12.2278 13.1996 11.7556 13.1996 11.2C13.1996 10.6445 13.0052 10.1722 12.6163 9.78336C12.2274 9.39447 11.7552 9.20002 11.1996 9.20002C11.0218 9.20002 10.8496 9.21669 10.6829 9.25002C10.5163 9.28336 10.3607 9.35002 10.2163 9.45002C10.0941 9.53891 9.96072 9.56114 9.81628 9.51669C9.67183 9.47225 9.56072 9.3778 9.48294 9.23336L8.04961 6.33336C7.90517 6.26669 7.79405 6.16669 7.71628 6.03336C7.6385 5.90002 7.59961 5.75558 7.59961 5.60002C7.59961 5.3778 7.67739 5.18891 7.83294 5.03336C7.9885 4.8778 8.17739 4.80002 8.39961 4.80002C8.62183 4.80002 8.81072 4.8778 8.96628 5.03336C9.12183 5.18891 9.19961 5.3778 9.19961 5.60002C9.19961 5.62225 9.19683 5.64725 9.19128 5.67502C9.18572 5.7028 9.18294 5.7278 9.18294 5.75002L10.3663 8.11669C10.5107 8.09447 10.6496 8.06947 10.7829 8.04169C10.9163 8.01391 11.0552 8.00002 11.1996 8.00002C12.0849 8.00002 12.8396 8.31241 13.4636 8.93719C14.0876 9.56186 14.3996 10.3174 14.3996 11.2039C14.3996 12.0902 14.0876 12.8445 13.4634 13.4667C12.8393 14.0889 12.0845 14.4 11.1989 14.4Z\" fill=\"#7A786E\"/></svg>"
}
Loading