verify-webhook

Checks a webhook’s signature at the edge, so forged events never reach your service.

Phaseson_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