Anyone who knows your URL can post to it. The Pawabase-Signature header proves a request came from Pawabase:
v1 is the hex HMAC-SHA256, keyed with the Signing secret, of the text "<t>.<raw body>". Reject requests more than 5 minutes old. Sign over the raw body, not re-serialised JSON.

How the signature is made

  1. Pawabase takes the current Unix time in seconds, t.
  2. It builds the text t + . + the exact bytes of the body it sends.
  3. It computes the HMAC-SHA256 of that text with the endpoint’s signing secret as the key, as lowercase hex.
  4. It sends Pawabase-Signature: t=<t>,v1=<hex>.
To verify, repeat steps 2 and 3 with the body you received and compare with v1 using a constant-time comparison. Then check t is within five minutes of your clock.

Why each step matters

The window checks the time of this attempt, so a retry sent hours later still verifies: each attempt is signed when it’s sent.

Framework notes

Several secrets during a rotation

While rotating a secret (see Webhooks), check the signature against each secret you currently accept and pass if any matches.

Receiving in another Pawabase project

To receive Pawabase webhooks in another Pawabase project, create an inbound hook with Verification set to Pawabase signature and Signature header Pawabase-Signature, using the same secret. Pawabase does the checking for you.

Troubleshooting