Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Feature: Webhook Signatures

When pg_tide sends outgoing webhooks (via the HTTP webhook sink) or receives incoming webhooks (via the webhook receiver source), it can sign and verify messages using HMAC-based signatures. This ensures the recipient can verify the webhook came from pg_tide (outgoing) and that pg_tide can verify webhooks come from a trusted sender (incoming).

Outgoing Webhook Signatures

When publishing to an HTTP webhook endpoint, pg_tide can sign the request body and include the signature in a header. The receiving service verifies the signature to ensure the request is authentic and hasn't been tampered with.

Configuration (Outgoing)

SELECT tide.relay_set_outbox(
    'order-notifications',
    'order_events',
    '{
        "sink_type": "webhook",
        "url": "https://partner.example.com/webhooks/orders",
        "signature": {
            "scheme": "hmac-sha256",
            "secret": "${env:WEBHOOK_SIGNING_SECRET}",
            "header": "X-Signature-256"
        }
    }'::jsonb
);

The signature is computed as HMAC-SHA256(secret, request_body) and sent as a hex-encoded string in the configured header.

Incoming Webhook Verification

When receiving webhooks from external services via the webhook receiver source, pg_tide verifies the signature before accepting the message. Requests with invalid signatures are rejected with HTTP 401.

Configuration (Incoming)

SELECT tide.relay_set_inbox(
    'stripe-events',
    'payment_inbox',
    '{
        "source_type": "webhook",
        "listen_addr": "0.0.0.0:8080",
        "path": "/webhooks/stripe",
        "signature_scheme": "stripe",
        "signature_secret": "${env:STRIPE_WEBHOOK_SECRET}"
    }'::jsonb
);

Supported Signature Schemes

hmac-sha256 — Standard HMAC

The most common webhook signing scheme. Computes HMAC-SHA256 of the request body using a shared secret.

  • Header: Configurable (default: X-Signature-256)
  • Format: sha256=<hex-encoded-hmac>
  • Verification: Recompute HMAC and compare (constant-time)

github — GitHub Webhooks

GitHub's webhook signature format using X-Hub-Signature-256.

  • Header: X-Hub-Signature-256
  • Format: sha256=<hex-encoded-hmac>
  • Secret: Your GitHub webhook secret

stripe — Stripe Webhooks

Stripe's signature includes a timestamp to prevent replay attacks.

  • Header: Stripe-Signature
  • Format: t=<timestamp>,v1=<hmac>
  • Verification: HMAC computed over timestamp.body
  • Replay protection: Rejects signatures with timestamps too far in the past

svix — Svix Webhook Platform

Svix is a webhook delivery platform. pg_tide can verify Svix-signed webhooks.

  • Header: svix-signature
  • Format: Svix-specific signature scheme
  • Includes: Message ID, timestamp, and signature

Security Considerations

  • Always use HTTPS for webhook endpoints. Signatures prove authenticity but don't encrypt the payload.
  • Rotate secrets periodically. When rotating, you can temporarily accept both old and new secrets.
  • Use environment variables for secrets (never hardcode): ${env:SECRET_NAME}
  • Reject stale timestamps (Stripe scheme does this automatically) to prevent replay attacks.

Further Reading