# Autenticar el webhook: header estático vs firma

Cada entrega viaja SIEMPRE firmada, y ADEMÁS puede llevar un **header estático** (un token fijo en un header propio, ej. `X-Connect-Token`) si lo activás en tu endpoint. No son modos excluyentes: elegís cómo validar.

**Header estático** — más cómodo y más débil. Sobre HTTPS prueba que quien llama conoce el token, pero **NO verifica que el cuerpo no haya sido alterado, ni impide un replay**. Es la opción para herramientas sin código (n8n/Make/Zapier), que lo validan con su autenticación nativa por header.

**Firma HMAC** — verifica **integridad del cuerpo Y anti-replay** (el timestamp va dentro del HMAC). Requiere escribir un poco de código. Es la garantía fuerte.

Elegir comodidad está bien; elegirla sin saber qué perdés, no. Si podés, validá la firma; si usás no-code, activá el header estático y validalo con tu herramienta.

## Ejemplos

### 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
```

## Notas

- El header se llama como vos quieras (default `X-Connect-Token`), NUNCA `Authorization`. Lo generás/rotás en tu endpoint (Webhooks) y se muestra UNA sola vez.
- Compará el token en **tiempo constante** (como abajo). El ejemplo de verificación de firma está en 'Verificar la firma'.
