verify-webhook
Checks a webhook’s signature at the edge, so forged events never reach your service.
| Phases | on_http_request |
| Terminating | No — the next action runs after it. |
| Cost | 1 Traffic Policy unit per run · not on the Free plan |
Example
policy.yaml
on_http_request:
- expressions:
- "req.url.path == '/webhooks/stripe'"
actions:
- type: verify-webhook
config:
provider: stripe
secret: whsec_your_signing_secret
Start an agent endpoint with it: devgate http 8080 --traffic-policy-file policy.yaml, or paste it into a
reserved or cloud endpoint’s Traffic Policy tab in the dashboard.
Configuration
| Field | Type | Description |
|---|---|---|
provider required | string | stripe, github, gitlab, bitbucket, slack, shopify, twilio, telegram, paddle, discord, linear, zoom, mailgun, intercom, or svix (also clerk and resend — the Standard Webhooks scheme). |
secret required | string | The signing secret from the provider’s webhook settings (Stripe’s whsec_…, GitHub’s secret, Telegram’s secret_token; Discord’s public key). |
enforce | boolean | When false, nothing is blocked: the result is only recorded for a later rule. Default: true. |
Result variables
After it runs, later rules can read what it decided:
-
actions.ngrok.verify_webhook.verified— Whether the signature checked out.
Behaviour
- A missing or wrong signature gets 403 with the reason, and the request never reaches your service.
- Timestamped schemes (Stripe, Slack, Paddle, Zoom, Mailgun, Svix) also refuse signatures older than five minutes, so a captured webhook can’t be replayed.
- The tunnel URL is public and easy to find: anyone could post a fake “payment succeeded” to it. Checking at the edge protects you even while your code skips verification in development.
Other actions
add-headers remove-headers compress-response basic-auth oauth openid-connect jwt-validation custom-response deny redirect url-rewrite restrict-ips rate-limit circuit-breaker http-request set-vars log close-connection forward-internal