Saltar al contenido principal
Webhook signing · transparent

Webhook signing strategy

HMAC-SHA256 mandatory todos 6 inbound webhooks · timestamp replay protection <5min · idempotency keys mandatory · dual-key rotation window 24h zero downtime · 6 failure modes documented · 8-step rotation procedure transparent.

6 inbound webhooks · all signed

ProviderAlgoritmoSecretValidation
Meta WhatsApp Cloud APIHMAC-SHA256 con X-Hub-Signature-256 headerMETA_APP_SECRET · Cloudflare env · rotation trimestralConstant-time comparison · entire body hashed · timestamp ≤5min · idempotent via message_id
StripeStripe-Signature header con HMAC-SHA256 + timestampSTRIPE_WEBHOOK_SECRET · per-endpoint · rotation post-incident onlystripe.webhooks.constructEvent() SDK · timestamp tolerance 5min · event.id idempotent
Cal.comX-Cal-Signature-256 HMAC-SHA256CALCOM_WEBHOOK_SECRET · per-event-type · rotation trimestralHMAC verification · timestamp check · payload.uid idempotent
QStash (Upstash)Upstash-Signature header JWT · NextAuth verifyQSTASH_CURRENT_SIGNING_KEY + QSTASH_NEXT_SIGNING_KEY (dual)JWT verification · dual-key window 24h rotation · job_id idempotent
GitHub Actions (CI webhooks)X-Hub-Signature-256 HMAC-SHA256GITHUB_WEBHOOK_SECRET · rotation anual o post-secret-leakConstant-time HMAC compare · timestamp X-GitHub-Delivery idempotent
UptimeRobot alertsShared secret token query param + IP whitelist CloudflareUPTIMEROBOT_WEBHOOK_TOKEN · query string · rotation trimestralToken match + Cloudflare WAF IP whitelist UptimeRobot · alertContents idempotent via timestamp+monitorID

Replay protection · 6 mechanisms

Timestamp tolerance 5 minutes
Idempotency keys mandatory
Cada webhook event tiene unique ID (message_id · event.id · job_id) · DB unique constraint prevents duplicate processing · second delivery = no-op
Dual-key rotation window 24h
Durante rotation · old key + new key both valid 24h · prevents downtime · audit which key signed each request
Body hash full · not subset
ENTIRE request body hashed · partial body modifications detected · prevents selective tampering
Constant-time comparison
crypto.timingSafeEqual() en Node · prevents timing side-channel revealing secret length
TLS 1.3 enforced
Webhook MUST come via HTTPS TLS 1.3 (TLS 1.2 fallback acceptable) · NO plaintext webhook acceptable · Cloudflare enforces

Failure modes · 6 escenarios

Failure modeAction taken
Invalid signatureReturn HTTP 401 + log Sentry · NO process · alert si rate spike (potential attack)
Missing signature headerReturn HTTP 400 + log · usually misconfigured provider integration · alert founder review
Timestamp expired (>5min)Return HTTP 401 + log · could be legitimate clock skew o replay attack · investigate
Idempotency collision (already processed)Return HTTP 200 (success idempotent) · log info-level · NO re-process · prevents double-charging style bugs
DB write failure post-validationReturn HTTP 5xx · provider auto-retries · idempotency key prevents duplicate side-effects on retry
Secret rotation in-progress (dual-key window)Try CURRENT first · fallback NEXT · log which validated · transparent metric rotation progress

Rotation procedure · 8-step zero-downtime

Dual-key window allows providers update sin coordination instant · zero failed webhooks durante rotation.

  1. T-0 · Rotation decision · ADR documented WHY (scheduled vs incident · secret leakage suspected)
  2. T+1h · Generate NEXT signing key · upload to Cloudflare env as `<PROVIDER>_WEBHOOK_SECRET_NEXT`
  3. T+2h · Configure provider dashboard (Meta · Stripe · etc) con NEXT key · provider starts using NEXT
  4. T+2h-24h · Dual-validation window · accept signatures from CURRENT or NEXT · monitor metrics which validated
  5. T+24h · Verify 100% traffic using NEXT key via metrics · if any traffic still CURRENT investigate misconfigured provider
  6. T+25h · Remove CURRENT key from Cloudflare env · promote NEXT to CURRENT · zero downtime achieved
  7. T+25h · Audit log rotation event · ADR updated · runbook /rotate-secret marks completion · postmortem si issues
  8. T+30d · Verify zero issues post-rotation · update encryption-key-management page con last-rotated date
Outbound webhooks · planned post-tracción

Outbound webhooks (NOSOTROS hacia clientes) NO disponibles actualmente · roadmap post-tracción cuando clientes Enterprise lo soliciten para integrate sus CRM/EHR. Plan: same HMAC-SHA256 standard · signed con WEBHOOK_SECRET per-cliente · cliente verifies en su lado · idempotency keys provided.

Webhook retry policy: outbound futuro will follow Stripe-style exponential backoff (1m · 5m · 30m · 2h · 6h · 24h · max 72h total) · giving up logs event preserved DB para manual replay.

¿Tu engineering team necesita webhook integration details?

Para Enterprise procurement · code samples 4 idiomas verificación signatures · sample payloads · timing-attack hardened reference implementations disponibles bajo NDA.