Difficulty: Expert
Type: security
Background
packages/webhook-utils provides webhook verification utilities, but as a young, optional package it likely implements a single-secret HMAC scheme without provisions for key rotation or replay protection — common gaps in early-stage webhook implementations.
Problem
A single long-lived signing secret with no timestamp/nonce checking is vulnerable to secret compromise (no rotation path) and replay attacks (a captured valid request can be re-sent indefinitely).
Expected outcome
packages/webhook-utils supports versioned signing secrets (so a secret can be rotated without breaking in-flight integrations), includes a timestamp in the signed payload with a bounded tolerance window (e.g., 5 minutes) to reject stale/replayed requests, and rejects duplicate nonces within that window.
Suggested implementation
- Extend the signature scheme to include a
keyId/version alongside the signature (e.g., header like X-Webhook-Signature: v1=<hmac> supporting multiple concurrently valid keys during rotation).
- Include a
timestamp and nonce in the signed payload; verification rejects requests outside the tolerance window or with a previously-seen nonce (in-memory nonce cache acceptable for now, documented as needing a shared store like Redis for multi-instance deployments).
- Provide a
rotateSigningKey() / multi-key verification path so old and new secrets both validate during a rotation window.
- Write a comprehensive test suite: valid signature, expired timestamp, replayed nonce, wrong key version, tampered payload.
- Document the full protocol (headers, payload format, rotation procedure, replay window) in
packages/webhook-utils/README.md.
Acceptance criteria
Likely affected files/directories
packages/webhook-utils/
packages/integration-client/
Difficulty: Expert
Type: security
Background
packages/webhook-utilsprovides webhook verification utilities, but as a young, optional package it likely implements a single-secret HMAC scheme without provisions for key rotation or replay protection — common gaps in early-stage webhook implementations.Problem
A single long-lived signing secret with no timestamp/nonce checking is vulnerable to secret compromise (no rotation path) and replay attacks (a captured valid request can be re-sent indefinitely).
Expected outcome
packages/webhook-utilssupports versioned signing secrets (so a secret can be rotated without breaking in-flight integrations), includes a timestamp in the signed payload with a bounded tolerance window (e.g., 5 minutes) to reject stale/replayed requests, and rejects duplicate nonces within that window.Suggested implementation
keyId/version alongside the signature (e.g., header likeX-Webhook-Signature: v1=<hmac>supporting multiple concurrently valid keys during rotation).timestampandnoncein the signed payload; verification rejects requests outside the tolerance window or with a previously-seen nonce (in-memory nonce cache acceptable for now, documented as needing a shared store like Redis for multi-instance deployments).rotateSigningKey()/ multi-key verification path so old and new secrets both validate during a rotation window.packages/webhook-utils/README.md.Acceptance criteria
Likely affected files/directories
packages/webhook-utils/packages/integration-client/