<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Spubhi</title>
    <description>The latest articles on DEV Community by Spubhi (@spubhi).</description>
    <link>https://dev.to/spubhi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3519174%2F331c984f-917d-48d8-9681-4686316c20e1.jpg</url>
      <title>DEV Community: Spubhi</title>
      <link>https://dev.to/spubhi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/spubhi"/>
    <language>en</language>
    <item>
      <title>Why HMAC Is the Right Choice for Webhook Security (and Why Spubhi Makes It Simple)</title>
      <dc:creator>Spubhi</dc:creator>
      <pubDate>Mon, 05 Jan 2026 16:19:57 +0000</pubDate>
      <link>https://dev.to/spubhi/why-hmac-is-the-right-choice-for-webhook-security-and-why-spubhi-makes-it-simple-29p2</link>
      <guid>https://dev.to/spubhi/why-hmac-is-the-right-choice-for-webhook-security-and-why-spubhi-makes-it-simple-29p2</guid>
      <description>&lt;p&gt;Webhooks are one of the most common integration patterns today. They’re also one of the easiest places to make security mistakes.&lt;/p&gt;

&lt;p&gt;In this post, &lt;strong&gt;I’ll focus on why HMAC is a better approach for securing webhooks&lt;/strong&gt; and how Spubhi keeps the implementation simple and predictable.&lt;/p&gt;

&lt;p&gt;This is not a comparison-heavy or theory-heavy article — it’s about practical implementation and reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Problem with Webhook Security
&lt;/h2&gt;

&lt;p&gt;A webhook endpoint is publicly accessible by design.&lt;br&gt;
That means anyone can send a request to it unless you validate the sender.&lt;/p&gt;

&lt;p&gt;The real challenge is not adding authentication, but ensuring that:&lt;/p&gt;

&lt;p&gt;The request was not modified&lt;/p&gt;

&lt;p&gt;The sender actually knows a shared secret&lt;/p&gt;

&lt;p&gt;The validation works reliably across different clients and platforms&lt;/p&gt;

&lt;p&gt;This is where many webhook implementations break down.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why HMAC Works Well for Webhooks
&lt;/h2&gt;

&lt;p&gt;HMAC (Hash-based Message Authentication Code) solves a very specific problem:&lt;br&gt;
verifying both authenticity and integrity of a request.&lt;/p&gt;

&lt;p&gt;When using HMAC:&lt;/p&gt;

&lt;p&gt;The sender signs the raw request body using a shared secret&lt;/p&gt;

&lt;p&gt;The receiver independently generates the same signature&lt;/p&gt;

&lt;p&gt;If the signatures match, the request is trusted&lt;/p&gt;

&lt;p&gt;No secrets are sent over the wire.&lt;br&gt;
Only a signature is transmitted.&lt;/p&gt;

&lt;p&gt;This has a few important implications:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. No secret exposure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unlike tokens or passwords, the shared secret is never transmitted in the request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Payload integrity is guaranteed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If even one character in the request body changes, the signature validation fails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Stateless validation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The server does not need to store sessions or tokens per request.&lt;br&gt;
It only needs the shared secret and the incoming payload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Language-agnostic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HMAC works the same way in Java, Node.js, Python, Go, or any other language.&lt;/p&gt;

&lt;p&gt;This makes it ideal for webhook-based systems.&lt;/p&gt;
&lt;h2&gt;
  
  
  Common HMAC Implementation Pitfalls
&lt;/h2&gt;

&lt;p&gt;Most HMAC failures don’t come from cryptography — they come from inconsistencies.&lt;/p&gt;

&lt;p&gt;Some common issues:&lt;/p&gt;

&lt;p&gt;Signing parsed JSON instead of the raw body&lt;/p&gt;

&lt;p&gt;Different JSON serialization on sender and receiver&lt;/p&gt;

&lt;p&gt;Header mismatches or late header injection&lt;/p&gt;

&lt;p&gt;Async signing issues in tools like Postman&lt;/p&gt;

&lt;p&gt;A reliable HMAC implementation must:&lt;/p&gt;

&lt;p&gt;Use the &lt;strong&gt;exact raw request body&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Normalize the payload consistently&lt;/p&gt;

&lt;p&gt;Use a predictable header for the signature&lt;/p&gt;

&lt;p&gt;Validate before any business logic executes&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Spubhi Keeps HMAC Simple
&lt;/h2&gt;

&lt;p&gt;Spubhi was designed with webhook security as a first-class concern.&lt;/p&gt;

&lt;p&gt;Here’s what Spubhi does differently:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Raw body handling is explicit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spubhi validates HMAC against the actual incoming payload, not a re-serialized version.&lt;/p&gt;

&lt;p&gt;This avoids subtle mismatches that break signature verification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Header-based authentication only&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spubhi expects the HMAC signature in a single, clear header:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;X-SPUBHI-SECRET&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;No ambiguity. No hidden behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. No encoding or decoding of secrets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Secrets are treated as-is.&lt;br&gt;
There’s no unnecessary base64 wrapping or transformation.&lt;/p&gt;

&lt;p&gt;What you sign on the client is exactly what Spubhi verifies on the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Authentication happens before flow execution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If authentication fails, the request is rejected immediately.&lt;br&gt;
No partial execution, no side effects.&lt;/p&gt;

&lt;p&gt;This makes webhook behavior predictable and safe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minimal Client-Side HMAC Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Normalize JSON exactly like your current logic
const body = JSON.stringify(JSON.parse(pm.request.body.raw));

// HMAC secret
const secret = "hmac_Qv33h2Yp7SpLwl7mQ8geU7R8SrfRZ27BpX5j0tHM";

// Encode inputs
const encoder = new TextEncoder();
const keyData = encoder.encode(secret);
const bodyData = encoder.encode(body);

// Generate HMAC-SHA-256
crypto.subtle.importKey(
  "raw",
  keyData,
  { name: "HMAC", hash: "SHA-512" },
  false,
  ["sign"]
).then(key =&amp;gt; {
  return crypto.subtle.sign("HMAC", key, bodyData);
}).then(signature =&amp;gt; {
  const hmac = Array.from(new Uint8Array(signature))
    .map(b =&amp;gt; b.toString(16).padStart(2, "0"))
    .join("");

  // SAME header name you already use
  pm.request.headers.upsert({
    key: "X-SPUBHI-SECRET",
    value: hmac
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;No SDKs.&lt;br&gt;
No custom formats.&lt;br&gt;
No hidden transformations.&lt;br&gt;
**&lt;br&gt;
Minimal Server-Side Validation Logic**&lt;/p&gt;

&lt;p&gt;On the server:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the raw request body&lt;/li&gt;
&lt;li&gt;Generate HMAC using the same secret&lt;/li&gt;
&lt;li&gt;Compare it with the incoming header&lt;/li&gt;
&lt;li&gt;Reject if it doesn’t match&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Simple logic — easy to audit, easy to debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Webhook security doesn’t need to be complex — &lt;strong&gt;it needs to be correct and consistent.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HMAC works well because it:&lt;/p&gt;

&lt;p&gt;Protects payload integrity&lt;/p&gt;

&lt;p&gt;Avoids secret exposure&lt;/p&gt;

&lt;p&gt;Scales without state&lt;/p&gt;

&lt;p&gt;Works across platforms&lt;/p&gt;

&lt;p&gt;Spubhi keeps this model simple by:&lt;/p&gt;

&lt;p&gt;Avoiding magic&lt;/p&gt;

&lt;p&gt;Enforcing clear boundaries&lt;/p&gt;

&lt;p&gt;Treating authentication as a first step, not an afterthought&lt;/p&gt;

&lt;p&gt;If you’re building webhook-driven integrations, HMAC done right is enough — and simplicity is what makes it reliable.&lt;/p&gt;

&lt;h1&gt;
  
  
  webhooks
&lt;/h1&gt;

&lt;h1&gt;
  
  
  apissecurity
&lt;/h1&gt;

&lt;h1&gt;
  
  
  hmac
&lt;/h1&gt;

&lt;h1&gt;
  
  
  backend
&lt;/h1&gt;

&lt;h1&gt;
  
  
  integration
&lt;/h1&gt;

</description>
      <category>api</category>
      <category>backend</category>
      <category>security</category>
    </item>
    <item>
      <title>How Easy It Is to Convert Complex JSON to JSON in Spubhi</title>
      <dc:creator>Spubhi</dc:creator>
      <pubDate>Sat, 03 Jan 2026 13:02:02 +0000</pubDate>
      <link>https://dev.to/spubhi/how-easy-it-is-to-convert-complex-json-to-json-in-spubhi-3gll</link>
      <guid>https://dev.to/spubhi/how-easy-it-is-to-convert-complex-json-to-json-in-spubhi-3gll</guid>
      <description>&lt;p&gt;Most integration work isn’t about calling APIs.&lt;br&gt;
It’s about &lt;strong&gt;reshaping data&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Different systems send JSON in different formats, and almost every integration needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Renaming fields&lt;/li&gt;
&lt;li&gt;Aggregating values&lt;/li&gt;
&lt;li&gt;Handling missing data&lt;/li&gt;
&lt;li&gt;Producing a clean, predictable output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, I’ll show how &lt;strong&gt;complex JSON → JSON transformation&lt;/strong&gt; can be done cleanly in Spubhi, without loops, glue code, or custom scripts.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Problem: Real JSON Is Never Flat
&lt;/h2&gt;

&lt;p&gt;Let’s start with a realistic payload received via a webhook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "invoiceId": "INV-101",
  "customer": {
    "name": {
      "first": "Ravi",
      "last": "Sharma"
    }
  },
  "items": [
    { "name": "Laptop", "price": 50000.258 },
    { "name": "Mouse", "price": 800.756 }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What downstream systems usually want is something simpler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
{
  "invoiceId": "INV-101",
  "customerName": "Ravi Sharma",
  "itemCount": 2,
  "totalAmount": 50801.014
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigating nested fields&lt;/li&gt;
&lt;li&gt;Combining values&lt;/li&gt;
&lt;li&gt;Aggregating arrays&lt;/li&gt;
&lt;li&gt;Preserving decimal precision&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Traditional Way (and Why It’s Painful)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In most platforms, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing loops&lt;/li&gt;
&lt;li&gt;Manually summing values&lt;/li&gt;
&lt;li&gt;Handling nulls defensively&lt;/li&gt;
&lt;li&gt;Worrying about floating-point precision&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The transformation logic ends up scattered and hard to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Spubhi Way: JSON-First Transformation
&lt;/h2&gt;

&lt;p&gt;Spubhi treats everything as JSON internally, even if the input was XML or another format.&lt;/p&gt;

&lt;p&gt;The transformation logic looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "invoiceId": payload.invoiceId,
  "customerName": payload.customer.name.first + " " + payload.customer.name.last,
  "itemCount": sizeOf(payload.items),
  "totalAmount": sumBy(payload.items, "price")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;No loops.&lt;br&gt;
No glue code.&lt;br&gt;
No precision loss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Works Well
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. JSON-First by Design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You always work with JSON, regardless of how the data came in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Built-in Aggregation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Functions like sizeOf and sumBy are first-class, not hacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Decimal-Safe Calculations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sums preserve natural decimal values instead of forcing rounding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. One Concept per Line&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each output field clearly shows:&lt;/p&gt;

&lt;p&gt;Where data comes from&lt;/p&gt;

&lt;p&gt;How it’s derived&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Integration code tends to live for years.&lt;br&gt;
The simpler the transformation logic, the easier it is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debug&lt;/li&gt;
&lt;li&gt;Extend&lt;/li&gt;
&lt;li&gt;Hand off to another developer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By keeping transformations declarative and JSON-focused, Spubhi reduces the mental overhead that usually comes with integration work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Most integration platforms can transform JSON.&lt;br&gt;
The difference is &lt;strong&gt;how much work you have to do&lt;/strong&gt; to get there.&lt;/p&gt;

&lt;p&gt;If your integrations involve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Webhooks&lt;/li&gt;
&lt;li&gt;Event-driven payloads&lt;/li&gt;
&lt;li&gt;Aggregations&lt;/li&gt;
&lt;li&gt;Complex JSON reshaping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A JSON-first approach makes a noticeable difference.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why I Built My Own Self-Hosted Integration Runtime</title>
      <dc:creator>Spubhi</dc:creator>
      <pubDate>Mon, 15 Dec 2025 12:55:03 +0000</pubDate>
      <link>https://dev.to/spubhi/why-i-built-my-own-self-hosted-integration-runtime-2fgg</link>
      <guid>https://dev.to/spubhi/why-i-built-my-own-self-hosted-integration-runtime-2fgg</guid>
      <description>&lt;p&gt;Most integration tools I’ve used over the years were impressive on the surface—rich UIs, hundreds of connectors, and quick demos.&lt;/p&gt;

&lt;p&gt;But once things moved closer to production, the problems started showing up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem I kept running into&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tools like workflow automators and enterprise integration platforms usually break down in the same ways:&lt;/p&gt;

&lt;p&gt;Execution-based pricing that grows unpredictably&lt;/p&gt;

&lt;p&gt;Queues, retries, and error handling hidden behind abstractions&lt;/p&gt;

&lt;p&gt;Self-hosting treated as a secondary option&lt;/p&gt;

&lt;p&gt;Too much emphasis on UI, not enough on runtime behavior&lt;/p&gt;

&lt;p&gt;These tools work well for demos.&lt;br&gt;
They become painful when reliability and control actually matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I actually needed&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of more UI, I wanted:&lt;/p&gt;

&lt;p&gt;A runtime-first integration engine&lt;/p&gt;

&lt;p&gt;Explicit control over queues, retries, and parallelism&lt;/p&gt;

&lt;p&gt;Predictable costs by running on my own hardware&lt;/p&gt;

&lt;p&gt;A simple way to define flows without locking myself into a SaaS&lt;/p&gt;

&lt;p&gt;That’s what led me to build Spubhi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Spubhi is (and isn’t)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spubhi is a self-hosted integration runtime, built with a few clear constraints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Executes JSON-defined flows&lt;/p&gt;

&lt;p&gt;Supports API-triggered and queue-triggered executions&lt;/p&gt;

&lt;p&gt;Uses a payload-based transformation DSL&lt;/p&gt;

&lt;p&gt;Runs on Docker / VM / server&lt;/p&gt;

&lt;p&gt;Focuses on reliability over visual design&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it doesn’t try to be:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not a Zapier replacement&lt;/p&gt;

&lt;p&gt;Not a no-code tool&lt;/p&gt;

&lt;p&gt;Not a marketplace of connectors&lt;/p&gt;

&lt;p&gt;It’s built for developers who want control, ownership, and transparency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lessons learned while building it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A few things surprised me while working on this:&lt;/p&gt;

&lt;p&gt;Queues are harder than UI — but also more valuable&lt;/p&gt;

&lt;p&gt;Retry logic becomes complex very quickly in real systems&lt;/p&gt;

&lt;p&gt;“Easy” integrations hide painful failure modes&lt;/p&gt;

&lt;p&gt;Simplicity at runtime matters more than feature count&lt;/p&gt;

&lt;p&gt;Most of the real work wasn’t writing code—it was deciding what not to abstract away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I’m writing this&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’m not launching anything here.&lt;br&gt;
I’m sharing this because I want feedback from people who’ve dealt with integration systems in production.&lt;/p&gt;

&lt;p&gt;If you’ve used tools like MuleSoft, n8n, WSO2, or homegrown scripts:&lt;/p&gt;

&lt;p&gt;What part frustrated you the most?&lt;/p&gt;

&lt;p&gt;Where did things break in real usage?&lt;/p&gt;

&lt;p&gt;What would instantly make you reject a new integration tool?&lt;/p&gt;

&lt;p&gt;I’m building this in the open and learning as I go.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>automation</category>
      <category>nocode</category>
    </item>
  </channel>
</rss>
