# Authenticate the webhook: static header vs signature

Every delivery ALWAYS travels signed, and it can ALSO carry a **static header** (a fixed token in a header of your choice, e.g. `X-Connect-Token`) if you enable it on your endpoint. They are not mutually exclusive: you choose how to validate.

**Static header** — more convenient and weaker. Over HTTPS it proves the caller knows the token, but it does **NOT verify that the body was not altered, nor does it prevent a replay**. It's the option for no-code tools (n8n/Make/Zapier), which validate it with their native header auth.

**HMAC signature** — verifies **body integrity AND anti-replay** (the timestamp is inside the HMAC). It requires writing a little code. It's the strong guarantee.

Choosing convenience is fine; choosing it without knowing what you give up is not. If you can, verify the signature; if you're no-code, enable the static header and validate it with your tool.

## Examples

### cURL

```bash
# Static header check on the server that RECEIVES the webhook.
# Connect sends your token in the "X-Connect-Token" header on every delivery.
# Compare it in CONSTANT time against the token you stored.
#   if [ "$http_x_connect_token" != "$YOUR_TOKEN" ]; then reject 401; fi
```

### Node.js

```javascript
import crypto from "crypto";
const TOKEN = "wct_YOUR_TOKEN"; // the wct_… you stored (from the panel)

function checkHeader(req) {
  const got = req.header("X-Connect-Token") || "";
  const a = Buffer.from(got), b = Buffer.from(TOKEN);
  // constant-time compare (avoid a length/timing leak)
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```

### PHP

```php
<?php
$TOKEN = "wct_YOUR_TOKEN"; // the wct_… you stored (from the panel)

function checkHeader(array $headers): bool {
  $got = $headers["X-Connect-Token"] ?? "";
  return hash_equals($GLOBALS["TOKEN"], $got); // constant-time compare
}
```

### Python

```python
import hmac

TOKEN = "wct_YOUR_TOKEN"  # the wct_… you stored (from the panel)

def check_header(headers) -> bool:
    got = headers.get("X-Connect-Token", "")
    return hmac.compare_digest(got, TOKEN)  # constant-time compare
```

## Notes

- The header is named however you like (default `X-Connect-Token`), NEVER `Authorization`. You generate/rotate it on your endpoint (Webhooks) and it is shown ONCE.
- Compare the token in **constant time** (as below). The signature example is in 'Verify the signature'.
