Production Readiness
Before launching your webhook pipeline to production, ensure your configuration follows security best practices and reliability standards. This guide provides a comprehensive checklist and detailed recommendations for running Hookbase securely and reliably.
Pre-Launch Checklist
Use this checklist to verify your production configuration:
| Category | Item | Status | Notes |
|---|---|---|---|
| Security | Signature verification enabled for all sources | ⬜ | See Signature Verification |
| API key scopes limited to minimum required | ⬜ | Use read:events instead of admin where possible | |
| HTTPS-only destinations configured | ⬜ | Never send webhooks to http:// endpoints | |
| IP filtering configured for sensitive sources | ⬜ | Allowlist provider IPs where available | |
| Field encryption enabled for PII fields | ⬜ | Encrypt sensitive data like emails, SSNs | |
rejectInvalidSignatures enabled on sources | ⬜ | Prevents processing of unverified webhooks | |
| Reliability | Retry policies configured with backoff | ⬜ | Recommended: 3-5 retries with exponential backoff |
| Failover destinations set for critical routes | ⬜ | Secondary destination for automatic failover | |
| Circuit breakers enabled on destinations | ⬜ | Prevents cascading failures | |
| Deduplication enabled to prevent duplicates | ⬜ | Use idempotencyKey or content-based dedup | |
| Notification channels linked to routes | ⬜ | Get alerted on delivery failures | |
| Cron monitoring active for scheduled jobs | ⬜ | Monitor cron execution success rates | |
| Monitoring | Alert channels configured for critical routes | ⬜ | Email, Slack, or webhook notifications |
| Audit logs reviewed periodically | ⬜ | Check for unauthorized access attempts | |
| Analytics dashboard checked for anomalies | ⬜ | Monitor event volume and failure rates | |
| Health endpoint monitored externally | ⬜ | Use uptime monitoring service | |
| Access Control | Organization roles assigned appropriately | ⬜ | Admin, Developer, Viewer roles |
| API key rotation scheduled (quarterly) | ⬜ | Rotate keys every 90 days minimum | |
| Unused API keys revoked | ⬜ | Remove keys for deactivated services | |
| Least privilege principle applied | ⬜ | Grant minimum scopes needed |
Signature Verification
Signature verification is the most critical security control for webhooks. It ensures that incoming webhooks are authentic and haven't been tampered with.
Why It Matters
Without signature verification:
- Attackers can send fake webhooks to trigger unauthorized actions
- Replay attacks can resubmit legitimate webhooks
- Man-in-the-middle attacks can modify webhook payloads
Enabling Verification
When creating a source, always enable signature verification:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/sources \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Stripe Payments",
"provider": "stripe",
"verifySignatures": true,
"rejectInvalidSignatures": true,
"signingSecret": "whsec_abc123..."
}'Provider-Specific Configuration
Each provider has different signature verification mechanisms:
| Provider | Header | Algorithm | Configuration |
|---|---|---|---|
| Stripe | Stripe-Signature | HMAC-SHA256 | Signing secret from webhook settings |
| GitHub | X-Hub-Signature-256 | HMAC-SHA256 | Secret token from webhook config |
| Slack | X-Slack-Signature | HMAC-SHA256 | Signing secret from app credentials |
| Shopify | X-Shopify-Hmac-SHA256 | HMAC-SHA256 | Shared secret from admin panel |
| Twilio | X-Twilio-Signature | HMAC-SHA1 | Auth token from console |
Reject vs. Accept Invalid Signatures
The rejectInvalidSignatures setting controls behavior when verification fails:
rejectInvalidSignatures: true (Recommended for Production)
- Invalid webhooks return
401 Unauthorized - Event is NOT stored in Hookbase
- No deliveries are attempted
- Audit log records the rejection
rejectInvalidSignatures: false (Development/Testing Only)
- Invalid webhooks return
200 OK - Event is stored with
verificationStatus: "failed" - Deliveries are still attempted (not recommended)
- Useful for debugging signature issues
Production Requirement
Always set rejectInvalidSignatures: true in production. Accepting unverified webhooks defeats the purpose of signature verification and exposes your system to attacks.
Secret & Key Rotation
Regular rotation of secrets and API keys is essential for security hygiene.
API Key Rotation
Rotate API keys on a regular schedule (recommended: every 90 days):
Step 1: Create new API key
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/api-keys \
-H "Authorization: Bearer CURRENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API Key (2026-Q2)",
"scopes": ["read:sources", "read:events", "write:routes"],
"expiresAt": "2026-06-01T00:00:00Z"
}'Step 2: Update services to use new key
- Deploy new key to all services that consume your webhooks
- Verify services are working with new key
- Monitor for authentication errors
Step 3: Revoke old key
curl -X DELETE https://api.hookbase.app/api/organizations/{orgId}/api-keys/{keyId} \
-H "Authorization: Bearer NEW_API_KEY"Zero-Downtime Rotation
Set expiresAt on the old key to 7 days in the future instead of immediately revoking it. This allows a grace period for services to migrate.
Source Signing Secret Rotation
For webhook sources, rotate signing secrets using the built-in rotation mechanism:
# Via CLI
hookbase sources rotate-secret src_abc123 --org myorg
# Via API
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/sources/{sourceId}/rotate-secret \
-H "Authorization: Bearer YOUR_API_KEY"This returns a new signingSecret. Update it in your webhook provider:
{
"id": "src_abc123",
"name": "Stripe Payments",
"signingSecret": "whsec_NEW_SECRET",
"previousSecret": "whsec_OLD_SECRET",
"secretRotatedAt": "2026-02-11T10:30:00Z"
}Graceful Migration
Hookbase keeps the previous secret active for 24 hours, allowing webhooks signed with either the old or new secret to pass verification. This prevents dropped webhooks during rotation.
Zero-Downtime Rotation Strategy
For critical production systems:
- Pre-rotate: Create new secret but don't activate yet
- Update provider: Configure webhook provider with new secret (but don't delete old config yet)
- Activate: Rotate secret in Hookbase (both secrets now valid for 24h)
- Monitor: Watch delivery success rates for any verification failures
- Clean up: After 24h, remove old secret from provider configuration
Replay Prevention
Replay attacks involve resubmitting valid webhooks to trigger duplicate actions (e.g., double-charging a customer).
Deduplication
Enable deduplication to automatically reject duplicate webhooks:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/sources \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Stripe Payments",
"provider": "stripe",
"deduplication": {
"enabled": true,
"strategy": "idempotency_key",
"keyPath": "id",
"windowMinutes": 1440
}
}'Deduplication Strategies:
idempotency_key: Uses provider's unique event ID (e.g., Stripe'sidfield)content_hash: SHA-256 hash of entire payload (catches exact duplicates)custom_field: Extract custom field via JSONPath (e.g.,$.transaction.id)
Timestamp Checking
Many providers include a timestamp in their signature. Hookbase automatically rejects webhooks with timestamps outside a tolerance window:
{
"provider": "stripe",
"timestampTolerance": 300
}This rejects webhooks older than 5 minutes (300 seconds), preventing replay of captured webhook requests.
Idempotency Keys in Destinations
For critical operations, ensure your destination endpoints support idempotency keys:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/transforms \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Add Idempotency Header",
"type": "jsonata",
"expression": "{\"headers\": {\"Idempotency-Key\": $.event.id}}"
}'Attach this transform to routes delivering to payment processors or other systems where duplicate requests could cause problems.
Network Security
Control which traffic can reach your webhook sources and where deliveries can be sent.
IP Filtering
Restrict webhook sources to accept only traffic from known provider IPs:
curl -X PATCH https://api.hookbase.app/api/organizations/{orgId}/sources/{sourceId} \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ipFiltering": {
"enabled": true,
"mode": "allowlist",
"rules": [
{
"cidr": "3.18.12.0/22",
"description": "Stripe webhooks (us-east-1)"
},
{
"cidr": "3.130.192.0/22",
"description": "Stripe webhooks (us-east-2)"
}
]
}
}'Provider IP Ranges:
| Provider | IP Ranges | Documentation |
|---|---|---|
| Stripe | Multiple /22 blocks | https://stripe.com/docs/ips |
| GitHub | https://api.github.com/meta | https://docs.github.com/webhooks/webhook-events-and-payloads#ip-addresses |
| Slack | Multiple /24 blocks | https://api.slack.com/changelog/2018-05-01-webhook-ip-ranges |
| Shopify | Multiple /22 blocks | https://shopify.dev/docs/apps/webhooks |
Dynamic IP Ranges
Some providers change their IP ranges. Subscribe to their change notifications and update your allowlist accordingly. Consider using denylist mode if allowlisting is not feasible.
HTTPS-Only Enforcement
Never send webhooks to unencrypted HTTP endpoints:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Payment Processor",
"url": "https://api.example.com/webhooks",
"requireHttps": true
}'With requireHttps: true, any attempt to use an http:// URL will fail validation.
Custom Domains with SSL
For inbound webhooks, use custom domains with SSL certificates:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/custom-domains \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "webhooks.example.com",
"sslMode": "full_strict"
}'This allows webhooks at https://webhooks.example.com/receive/{sourceSlug} with your own SSL certificate, improving trust and branding.
Data Protection
Protect sensitive data in webhook payloads both at rest and in transit.
Field Encryption
Encrypt PII fields before storing or forwarding webhooks:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/sources/{sourceId}/field-encryption \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": [
{
"path": "$.customer.email",
"algorithm": "AES-256-GCM"
},
{
"path": "$.customer.ssn",
"algorithm": "AES-256-GCM"
},
{
"path": "$.payment.cardNumber",
"algorithm": "AES-256-GCM"
}
]
}'Encrypted fields are stored as:
{
"customer": {
"email": "enc_AES256GCM_abc123...",
"name": "John Doe"
}
}Encryption Key Management
Hookbase uses your organization's encryption key (AES-256-GCM). This key is stored in Cloudflare KV and rotated annually. For compliance requirements (HIPAA, PCI-DSS), contact support for custom key management options.
Field Masking
For non-encrypted fields that shouldn't appear in logs:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/sources \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Payment Events",
"maskedFields": [
"$.customer.email",
"$.payment.last4",
"$.customer.phone"
]
}'Masked fields appear as *** in audit logs and the dashboard but are delivered normally to destinations.
Payload Retention Policies
Configure how long webhook payloads are stored:
curl -X PATCH https://api.hookbase.app/api/organizations/{orgId}/settings \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataRetention": {
"events": {
"retentionDays": 90,
"deletePayloadAfterDays": 30
},
"deliveries": {
"retentionDays": 90
},
"auditLogs": {
"retentionDays": 365
}
}
}'This configuration:
- Keeps event metadata for 90 days
- Deletes full payloads after 30 days (headers/status remain)
- Retains delivery attempts for 90 days
- Keeps audit logs for 1 year
Compliance
For GDPR, CCPA, or other privacy regulations, configure retention policies to automatically delete customer data. Use deletePayloadAfterDays to purge PII while keeping delivery status for debugging.
Reliability Configuration
Configure retry policies, circuit breakers, and failover for production-grade reliability.
Retry Policies
Configure retries with exponential backoff:
For Transient Failures (Network Issues, 5xx Errors):
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "External API",
"url": "https://api.example.com/webhooks",
"retryPolicy": {
"maxAttempts": 5,
"initialDelaySeconds": 2,
"maxDelaySeconds": 300,
"backoffMultiplier": 2,
"retryableStatusCodes": [408, 429, 500, 502, 503, 504]
}
}'This produces delays: 2s, 4s, 8s, 16s, 32s (capped at 300s).
For Rate-Limited APIs:
{
"retryPolicy": {
"maxAttempts": 10,
"initialDelaySeconds": 60,
"maxDelaySeconds": 3600,
"backoffMultiplier": 1.5,
"retryableStatusCodes": [429],
"respectRetryAfterHeader": true
}
}For Critical Webhooks (No Tolerance for Loss):
{
"retryPolicy": {
"maxAttempts": 20,
"initialDelaySeconds": 1,
"maxDelaySeconds": 86400,
"backoffMultiplier": 2,
"retryableStatusCodes": [0, 408, 429, 500, 502, 503, 504]
}
}Status Code 0
Status code 0 represents network failures (DNS resolution, connection timeout, etc.). Include it for maximum reliability.
Circuit Breaker Tuning
Prevent cascading failures by opening circuits on repeated errors:
curl -X PATCH https://api.hookbase.app/api/organizations/{orgId}/destinations/{dstId}/circuit-breaker \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"failureThreshold": 10,
"successThreshold": 3,
"timeoutSeconds": 10,
"halfOpenAttempts": 2,
"resetTimeoutSeconds": 60
}'Configuration Explained:
failureThreshold: 10- Open circuit after 10 consecutive failuressuccessThreshold: 3- Close circuit after 3 consecutive successestimeoutSeconds: 10- Treat requests taking >10s as failureshalfOpenAttempts: 2- Try 2 requests in half-open state before reopeningresetTimeoutSeconds: 60- Wait 60s before transitioning to half-open
For High-Traffic Destinations:
{
"failureThreshold": 50,
"successThreshold": 10,
"resetTimeoutSeconds": 300
}For Critical Low-Traffic Destinations:
{
"failureThreshold": 3,
"successThreshold": 1,
"resetTimeoutSeconds": 30
}Failover Setup
Configure automatic failover to secondary destinations:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/routes \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Payment Processing with Failover",
"sourceId": "src_abc123",
"destinationId": "dst_primary",
"failover": {
"enabled": true,
"destinationId": "dst_secondary",
"triggerConditions": [
"circuit_open",
"all_retries_exhausted",
"timeout"
]
}
}'Failover Triggers:
circuit_open- Primary destination's circuit breaker is openall_retries_exhausted- All retry attempts failedtimeout- Request exceeded timeout thresholdstatus_5xx- Any 5xx response (even if retries remain)
Failover Delivery Guarantee
Failover does NOT guarantee exactly-once delivery. A webhook may be delivered to both primary and secondary if the primary succeeds after a long delay. Ensure your secondary destination is idempotent.
Monitoring & Alerting
Set up proactive monitoring to catch issues before they impact customers.
Notification Channels
Configure notification channels for alerts:
Slack:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/notification-channels \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Engineering Alerts",
"type": "slack",
"config": {
"webhookUrl": "https://hooks.slack.com/services/T00/B00/xxx"
},
"events": [
"route.circuit_opened",
"route.high_failure_rate",
"source.quota_exceeded",
"destination.all_retries_failed"
]
}'Email:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/notification-channels \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "On-Call Email",
"type": "email",
"config": {
"recipients": ["[email protected]", "[email protected]"]
},
"events": [
"route.circuit_opened",
"cron.execution_failed"
]
}'Webhook (for PagerDuty, Datadog, etc.):
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/notification-channels \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "PagerDuty",
"type": "webhook",
"config": {
"url": "https://events.pagerduty.com/v2/enqueue",
"headers": {
"Authorization": "Token token=YOUR_INTEGRATION_KEY"
}
},
"events": [
"route.circuit_opened",
"source.signature_verification_failed"
]
}'What to Alert On
Recommended alerts for production systems:
| Event | Severity | Description |
|---|---|---|
route.circuit_opened | Critical | Circuit breaker opened, deliveries paused |
route.high_failure_rate | Warning | >10% failure rate over 5 minutes |
source.quota_exceeded | Warning | Monthly event quota reached |
destination.all_retries_failed | Error | Webhook delivery failed after all retries |
cron.execution_failed | Error | Scheduled cron job failed |
source.signature_verification_failed | Warning | Invalid signature (potential attack) |
organization.quota_approaching | Info | 80% of plan quota used |
CLI Monitoring Commands
Use the CLI for real-time monitoring:
# Watch live events
hookbase events tail --source src_abc123
# Monitor delivery success rate
hookbase analytics deliveries --source src_abc123 --last 1h
# Check circuit breaker status
hookbase destinations status dst_abc123
# View recent failures
hookbase deliveries list --status failed --limit 50
# Monitor cron executions
hookbase cron status cron_abc123 --last 24hHealth Endpoint Monitoring
Monitor Hookbase's health endpoint with external uptime services:
curl https://api.hookbase.app/healthResponse:
{
"status": "healthy",
"timestamp": "2026-02-11T10:30:00Z",
"services": {
"database": "healthy",
"queue": "healthy",
"storage": "healthy"
}
}Use services like Pingdom, UptimeRobot, or Better Uptime to monitor this endpoint and alert on outages.
Access Control
Implement role-based access control and least privilege principles.
RBAC Overview
Hookbase supports three organization roles:
| Role | Permissions | Use Case |
|---|---|---|
| Admin | Full access: manage members, billing, API keys, all resources | CTO, DevOps lead |
| Developer | Create/update sources, destinations, routes, transforms, filters | Engineering team |
| Viewer | Read-only access to events, deliveries, analytics | Support, monitoring |
Assign roles when inviting members:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/members \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"role": "developer"
}'API Key Scopes
API keys support fine-grained scopes for least privilege access:
| Scope | Permissions | Use Case |
|---|---|---|
read:events | List and retrieve events | Analytics, monitoring |
read:deliveries | List and retrieve deliveries | Debugging, monitoring |
read:sources | List and retrieve sources | Configuration audits |
write:sources | Create/update sources | Automation scripts |
write:routes | Create/update routes | Dynamic routing |
admin | Full API access | Service accounts, automation |
Example: Read-Only Monitoring Key
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/api-keys \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Datadog Monitoring",
"scopes": ["read:events", "read:deliveries"],
"expiresAt": "2027-02-11T00:00:00Z"
}'Example: Route Management Key
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/api-keys \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Dynamic Routing Service",
"scopes": ["read:sources", "write:routes", "read:destinations"],
"expiresAt": "2027-02-11T00:00:00Z"
}'Principle of Least Privilege
Grant the minimum scopes required:
Anti-Pattern
{
"name": "Frontend Dashboard",
"scopes": ["admin"]
}This grants full access to a client-side application, which could leak credentials.
Best Practice
{
"name": "Frontend Dashboard",
"scopes": ["read:events", "read:deliveries", "read:sources"]
}Read-only access prevents malicious users from modifying configuration.
Audit Logging
All API key usage is logged in audit logs:
curl https://api.hookbase.app/api/organizations/{orgId}/audit-logs \
-H "Authorization: Bearer YOUR_API_KEY"Review audit logs for:
- Unauthorized access attempts (
action: "api.unauthorized") - API key creation/deletion (
action: "api_key.created") - Source configuration changes (
action: "source.updated") - Member role changes (
action: "member.role_updated")
Set up alerts for suspicious patterns:
curl -X POST https://api.hookbase.app/api/organizations/{orgId}/notification-channels \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Security Alerts",
"type": "email",
"config": {
"recipients": ["[email protected]"]
},
"events": [
"audit.unauthorized_access",
"audit.api_key_created",
"audit.member_added"
]
}'Next Steps
- Custom Domains - Set up branded webhook URLs
- Audit Logs - Review security events
- Plans & Quotas - Understand plan limits
- Notification Channels - Configure alerts