DEV Community

Cover image for I Built an Open Webhook Gateway — Here's Why and How
Upsec
Upsec

Posted on • Originally published at upsec.co

I Built an Open Webhook Gateway — Here's Why and How

I Built an Open Webhook Gateway — Here's Why and How
Every app I've built in the last few years has had the same problem: webhooks are unreliable.

Stripe sends a payment event, but my server is restarting. GitHub sends a push notification, but my endpoint returns a 500. Shopify fires an order webhook, but I have no idea if it actually arrived.

Sound familiar?

I got tired of rebuilding the same retry logic, signature verification, and logging infrastructure for every project. So I built UpSec — a webhook gateway that sits between providers and your application.

The Problem with Raw Webhooks
Webhooks are fire-and-forget. The sender makes one HTTP request and moves on. If your server is down, overloaded, or returning errors — that data is gone forever.

Here are the three critical risks:

Data Loss — Your server is offline for 30 seconds during a deploy. A Stripe payment_intent.succeeded event fires. You never receive it. The customer paid, but your system doesn't know.

Security — Anyone can POST to your webhook URL. Without HMAC signature verification, you're accepting unverified data into your system. That's an injection vector waiting to happen.

No Visibility — When something breaks, you're debugging blind. No logs. No replay. No way to see what was sent, when, or whether it was processed.

What UpSec Does
UpSec is a webhook gateway — a managed layer between webhook providers and your backend. Instead of pointing Stripe directly at your-api.com/webhooks/stripe, you point it at UpSec.

Here's the flow:

Provider (Stripe, GitHub, etc.)

UpSec receives the webhook

Verifies HMAC signature (SHA-256 / SHA-512)

Logs the event with full payload

Forwards to your destination(s)

If it fails → automatic retry with exponential backoff
(30s → 2min → 10min → 1hr)
Key Features
Instant Endpoints — Create a webhook URL in seconds. No server setup required.
HMAC Signature Verification — Timing-safe verification for SHA-256, SHA-512, and provider-specific formats (Stripe, GitHub, Shopify).
Multi-Destination Forwarding — Route a single webhook to multiple internal services.
Automatic Retries — Exponential backoff with 4 retry attempts. No more lost events.
Real-Time Event Logs — See every webhook as it arrives, with payload, headers, and delivery status.
Payload Transformation — Transform webhook payloads before forwarding using JSONPath rules.
The Tech Stack
I built UpSec with a focus on speed and reliability:

Frontend: React + TypeScript + Tailwind CSS
Backend: Serverless edge functions
Database: PostgreSQL with JSONB for flexible payload storage
Verification: Timing-safe HMAC comparison to prevent side-channel attacks
SDKs: Node.js, Python, and Go
SDK Integration
UpSec provides SDKs so you can verify webhooks in your own codebase too:

Node.js
npm install @upsec/webhook
import { UpSec } from '@upsec/webhook';

const upsec = new UpSec({ secret: process.env.WEBHOOK_SECRET });

app.post('/webhooks', (req, res) => {
const isValid = upsec.verify(req.body, req.headers['x-webhook-signature']);

if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}

// Process the verified webhook
handleEvent(req.body);
res.status(200).json({ received: true });
});
Python
pip install upsec-webhook
from upsec import UpSec

upsec = UpSec(secret=os.environ["WEBHOOK_SECRET"])

@app.route("/webhooks", methods=["POST"])
def handle_webhook():
if not upsec.verify(request.data, request.headers.get("x-webhook-signature")):
abort(401)

process_event(request.json)
return jsonify(received=True)
Enter fullscreen mode Exit fullscreen mode

Go
import "github.com/upsec/webhook-go"

func webhookHandler(w http.ResponseWriter, r *http.Request) {
client := upsec.New(os.Getenv("WEBHOOK_SECRET"))

body, _ := io.ReadAll(r.Body)
sig := r.Header.Get("X-Webhook-Signature")

if !client.Verify(body, sig) {
    http.Error(w, "Invalid signature", http.StatusUnauthorized)
    return
}

// Process verified webhook
Enter fullscreen mode Exit fullscreen mode

}
Why Not Just Build It Yourself?
You absolutely can. I did — multiple times. That's exactly why I built UpSec.

Here's what "building it yourself" actually means:

Feature DIY Effort UpSec
Signature verification Research each provider's format, implement timing-safe comparison ✅ Built-in
Retry logic Build a job queue, implement backoff, handle dead letters ✅ Automatic
Logging Set up structured logging, build a viewer UI ✅ Real-time dashboard
Multi-destination Build a routing layer, handle partial failures ✅ Configure in UI
Monitoring Build alerting for failed deliveries ✅ Notification channels
For a side project, that's weeks of work. For a production system, it's months of maintenance.

Security First
Webhook security isn't optional. UpSec uses:

Timing-safe HMAC comparison — Prevents timing attacks that could leak signature information
Rate limiting — 100 events/minute per endpoint to prevent abuse
TLS everywhere — All webhook traffic is encrypted in transit
Payload isolation — Each workspace has isolated data access
What's Next
I'm actively building UpSec and would love feedback from the community:

🔗 Website: upsec.co
📖 Docs: upsec.co/docs
🚀 Product Hunt: producthunt.com/posts/upsec
If you've dealt with webhook reliability issues, I'd love to hear your story. What providers give you the most trouble? What features would you want in a webhook gateway?

If this was helpful, consider giving UpSec an upvote on Product Hunt — it really helps! 🙏

Top comments (0)