Security

Taskhook provides multiple security features to protect both incoming and outgoing communications. This guide covers request signing and payload encryption.

Security Overview

Taskhook implements several security measures for different types of communication:

  1. API Authentication - For requests to Taskhook API

  2. Request Signing - For webhook requests from Taskhook

    • Verifies that incoming webhooks are genuinely from Taskhook
    • Prevents webhook spoofing and tampering
    • Covered in detail below
  3. Payload Encryption - Optional

    • Encrypts sensitive data in task payloads
    • Keeps data encrypted while stored in Taskhook
    • Covered in detail below

Request Signing

Taskhook signs all webhook deliveries with a unique signature, allowing you to verify that requests come from Taskhook and not a malicious third party. We strongly recommend implementing signature verification for all webhook endpoints.

Signature Format

Each webhook request includes an X-Taskhook-Signature header containing one or more signatures. Multiple signatures may be present to support zero-downtime secret rotation.

X-Taskhook-Signature: v1=5257a869e7bcd8d1f549b49a38fb9254...

Signatures are computed using HMAC-SHA256, with your webhook secret as the key and the complete request body as the message.

Obtaining Your Webhook Secret

When creating a webhook endpoint in the Taskhook Dashboard, a unique signing secret is automatically generated. Keep this secret secure and never expose it in client-side code.

Verifying Signatures with SDKs

Our SDKs provide built-in signature verification:

import { TaskhookReceiver } from '@taskhook/sdk'

const receiver = new TaskhookReceiver({
  secret: 'your_webhook_secret',
})

// In your webhook handler
const isValid = receiver.verifySignature(
  request.body,
  request.headers['x-taskhook-signature'],
)

Manual Signature Verification

If you're not using our SDKs, here's how to verify signatures manually:

  1. Extract the signature from the X-Taskhook-Signature header
  2. Compute HMAC-SHA256 of the raw request body using your webhook secret
  3. Compare the computed signature with the received signature using a constant-time comparison
const crypto = require('crypto')

function verifySignature(secret, body, signature) {
  const computed = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex')

  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(computed))
}

Payload Encryption

For additional security, Taskhook supports end-to-end payload encryption. While all data is encrypted in transit via HTTPS, payload encryption ensures data remains encrypted while processed and stored within Taskhook.

Using SDK Encryption

For sending encrypted payloads, initialize the client with an encryption key:

import { TaskhookClient } from '@taskhook/client'

const client = new TaskhookClient(token, {
  encryption: {
    key: 'your_secret_key', // Must be shared between sender/receiver
  },
})

// The payload will be automatically encrypted
await client.tasks.create({
  target: 'https://example.com/webhook',
  payload: { sensitive: 'data' },
})

For receiving and decrypting payloads in your webhook handler:

import { TaskhookReceiver } from '@taskhook/sdk'

const receiver = new TaskhookReceiver({
  secret: 'your_webhook_secret',
  encryption: {
    key: 'your_secret_key', // Same key used for sending
  },
})

// In your webhook handler
app.post('/webhook', (req, res) => {
  // Verify signature and decrypt in one step
  const payload = receiver.verifyAndDecrypt(
    req.body,
    req.headers['x-taskhook-signature'],
  )
  // Process verified and decrypted payload
  res.sendStatus(200)
})

Note: The encryption key must be the same for both sending and receiving. Keep this key secure and never expose it in client-side code.

Custom Encryption

You can implement your own encryption solution if you need more control. Taskhook doesn't need to know about your encryption method or keys - it simply delivers the encrypted payload.

Security Best Practices

  • Store webhook secrets and encryption keys securely
  • Rotate secrets immediately if compromised
  • Use different secrets for development and production
  • Implement signature verification for all webhook endpoints
  • Use constant-time comparison when verifying signatures
  • Consider payload encryption for sensitive data

Was this page helpful?