Securing Your Webhooks

Exposing scripts to the web requires careful security considerations. Webhookd provides multiple layers of security to protect your endpoints.

Authentication with HTTP Basic Auth

You can restrict access to all webhooks using HTTP Basic Authentication. When enabled, clients must provide a valid username and password to trigger any script.

Setup:

  1. Create a .htpasswd file: Use the htpasswd utility (commonly available with Apache) to create a file with users and their hashed passwords. The -B flag is recommended for bcrypt hashing.

    # Create a new file with the user 'api'
    htpasswd -B -c .htpasswd api
    # You will be prompted to enter a password for 'api'.
  2. Configure Webhookd: Tell Webhookd where to find the password file using the WHD_PASSWD_FILE environment variable or the --passwd-file flag.

    export WHD_PASSWD_FILE=/path/to/.htpasswd
    webhookd --passwd-file /path/to/.htpasswd

Usage:

Clients must now include the credentials in their requests.

curl -u api:the_password http://localhost:8080/my/secret/hook

Request Signature Verification

Signature verification ensures that incoming webhook requests are authentic (they came from a trusted source) and have not been tampered with. This is more secure than a simple secret token.

To enable signature verification, you must provide a truststore file containing the public keys of trusted clients via WHD_TRUSTSTORE_FILE or --truststore-file.

Webhookd supports two signature schemes:

1. HTTP Signatures

This method follows the IETF draft standard for signing HTTP messages. It is a flexible and robust way to sign requests.

Client Request Example:

curl -X POST \
  -H 'Date: <request-date>' \
  -H 'Signature: keyId="my-key-id",algorithm="rsa-sha256",headers="(request-target) date",signature="<base64-signature>"' \
  http://localhost:8080/echo
Webhookd will use the keyId from the Signature header to look up the corresponding public key in the truststore and verify the signature.

A helper client is available in the repository to forge these signatures.

2. Ed25519 Signatures

This is a simpler signature scheme used by services like Discord. It uses a public-key signature algorithm based on Ed25519.

Client Request Example:

curl -X POST \
  -H 'X-Signature-Ed25519: <hex-encoded-signature>' \
  -H 'X-Signature-Timestamp: <unix-timestamp>' \
  --data '{"payload":"..."}' \
  http://localhost:8080/echo
Webhookd verifies the signature using the request timestamp, the request body, and a public key named default in the truststore.

Securing Communications with TLS (HTTPS)

You can enable TLS to encrypt all traffic to and from the Webhookd server.

How to Enable: Set the --tls-enabled flag to true or the environment variable WHD_TLS_ENABLED=true.

Webhookd supports two modes for TLS:

1. Using Your Own Certificate

By default, webhookd will look for server.pem and server.key in the current directory. You can specify custom paths using:

  • --tls-cert-file: Path to your certificate file.
  • --tls-key-file: Path to your private key file.

2. Automatic Certificates with ACME (Let's Encrypt)

Webhookd can automatically obtain and renew a TLS certificate from Let's Encrypt for a public domain name.

To enable this, provide your domain name using:

  • --tls-domain=hook.example.com
  • WHD_TLS_DOMAIN=hook.example.com

Note: For ACME to work, webhookd must be accessible from the public internet on ports 80 and 443, and your domain's DNS must point to the server where webhookd is running. On Unix-like systems, you may need to grant the binary permission to bind to privileged ports:

sudo setcap CAP_NET_BIND_SERVICE=+ep /path/to/webhookd