> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rxscale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

> Verify webhook signatures to ensure authenticity

# Webhook Security

Every webhook delivery includes a signature that you should verify to ensure the request originated from RxScale and was not tampered with.

## Signature Verification

Each webhook request includes a signature header. Verify it by computing an HMAC-SHA256 hash of the request body using your `signing_secret`.

### Example (Python)

```python theme={null}
import hmac
import hashlib

def verify_webhook(payload_body: bytes, signature: str, signing_secret: str) -> bool:
    expected = hmac.new(
        signing_secret.encode(),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
```

### Example (Node.js)

```javascript theme={null}
const crypto = require('crypto');

function verifyWebhook(payloadBody, signature, signingSecret) {
  const expected = crypto
    .createHmac('sha256', signingSecret)
    .update(payloadBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always verify signatures">
    Never process webhook payloads without verifying the signature first. This protects against spoofed requests.
  </Accordion>

  <Accordion title="Use constant-time comparison">
    Always use `hmac.compare_digest` (Python) or `crypto.timingSafeEqual` (Node.js) to prevent timing attacks.
  </Accordion>

  <Accordion title="Respond quickly">
    Return a `2xx` response within 5 seconds. If you need to do heavy processing, acknowledge the webhook first, then process asynchronously.
  </Accordion>

  <Accordion title="Handle duplicates">
    Webhook deliveries may be retried. Use the `event_type` + `timestamp` + `data.uid` to deduplicate events.
  </Accordion>
</AccordionGroup>
