Attributes¶
[Webhook<TValidator>]¶
Marks a dispatch handler as a webhook endpoint that requires signature validation before processing. Applied alongside [CommandHandler] and an HTTP method attribute.
[CommandHandler]
[HttpPost("/webhooks/twilio/sms")]
[Webhook<TwilioWebhookValidator>]
public static Eff<AppRuntime, Unit> HandleInboundSms(AcceptSmsReply cmd) => ...
| Property | Type | Description |
|---|---|---|
TValidator |
Type parameter | Must implement IWebhookValidator |
How It Works¶
- The generated endpoint reads the signature header and raw request body
- A
WebhookValidationContextis constructed with the signature, body, timestamp, and headers TValidator.Validate(context)is called before the handler executes- If validation fails, the endpoint returns 401 Unauthorized
- If validation passes, the handler processes the webhook
Dispatch Pipeline Integration¶
[Webhook<T>] works with standard dispatch attributes:
[CommandHandler]
[HttpPost("/webhooks/stripe")]
[Webhook<StripeWebhookValidator>]
[Public] // Webhooks are unauthenticated (validated by signature instead)
public static Eff<AppRuntime, Unit> HandleStripeEvent(ProcessStripeEvent cmd) => ...
The [Public] attribute bypasses auth for the endpoint — webhook authentication is handled by the validator.
WebhookValidationContext¶
The context record passed to validators:
| Property | Type | Description |
|---|---|---|
Signature |
string |
Raw signature from the request header |
RawBody |
string |
Raw request body as string |
Timestamp |
string? |
Timestamp header (e.g., Slack's X-Slack-Request-Timestamp) |
RequestUrl |
string? |
Full request URL (used by Twilio's validation scheme) |
Headers |
IReadOnlyDictionary<string, string>? |
Additional headers (case-insensitive keys) |
Provider-Specific Context¶
Each provider uses different fields from the context:
| Provider | Signature Source | Uses Timestamp | Uses URL |
|---|---|---|---|
| Slack | X-Slack-Signature |
Yes | No |
| Stripe | Stripe-Signature |
Yes (embedded) | No |
| Twilio | X-Twilio-Signature |
No | Yes |
| Bandwidth | Basic auth header | No | No |
| SNS | X-Amz-Sns-* headers |
No | No |