Skip to main content

Signature verification (Ed25519)

Webhook authenticity and integrity are ensured using Ed25519 asymmetric signatures.

Key material from TechWolf

For each webhook endpoint, TechWolf provides:
  • Public key (Ed25519) - used by you to verify webhook signatures
Private keys are held only by TechWolf and securely managed.

Signed message format

The signature is computed over:
The result is sent in the X-Signature-V1 header:
TechWolf supports non-breaking key rotation. During a rotation window, the same request may be signed with multiple active private keys, so X-Signature-V1 can contain several signatures. Validate the webhook by verifying that at least one signature matches using any of the currently active public keys. This allows key updates without downtime.

Security responsibilities

You must:
  • Verify the Ed25519 signature using the provided public key
  • Validate timestamp freshness to prevent replay attacks (e.g. reject requests where the X-Signature-Timestamp is older than 5 minutes)
  • Reject invalid or stale requests with a 401 response

Python example: signature verification


OAuth2 endpoint authentication (optional)

In addition to signature verification, TechWolf can authenticate webhook requests to your endpoint using OAuth2. This protects against unauthorised callers reaching your endpoint. OAuth2 is optional and does not replace signature verification; authenticity and integrity are always guaranteed by Ed25519.

Request format

When OAuth2 is enabled, TechWolf sends an access token in the Authorization header:

Enabling OAuth2

To enable OAuth2 for webhook delivery, you must provide:

Client authentication method

When TechWolf requests an access token from your token endpoint (client credentials grant), the client_id and client_secret can be sent in one of two ways:

Custom headers (optional)

You can configure custom headers that TechWolf will send with every webhook request to your endpoint (e.g. for routing or internal auth). The standard headers (including signature headers) are always sent; custom headers are added on top.