Requex.me LogoRequex.me

Documentation

Browse by section

Keep all guides, tool docs, automation recipes, and comparison pages in one navigable place.

Docs Home
Docs

Foundation docs for getting started fast, understanding key terms, and tracking what has changed.

Guides

Start with fundamentals, then move into provider-specific webhook testing and production hardening.

Tool Docs

These pages explain what each tool does, when to use it, and how it fits into a webhook debugging workflow.

Automation Docs

Use these setup guides when you want forwarding rules, custom responses, security checks, or multi-destination fanout.

Compare

Use these pages to compare developer workflows, pricing tradeoffs, and feature differences between webhook tools.

Webhook Authentication — Complete Developer Guide

How to protect your webhook endpoints with Bearer tokens, API keys, Basic Auth, and HMAC signatures — plus how to test each method without deploying server code.

Last updated: March 202613 min read

Why Webhook Endpoints Need Authentication

A webhook endpoint is a publicly accessible URL — by definition reachable from the internet. Without authentication, anyone who discovers your URL can send arbitrary POST requests to it, potentially triggering business logic, polluting your event queue, or causing unintended side effects.

Webhook authentication solves two distinct problems. The first is authorization: only trusted callers (your partners, your own services, or specific platforms) should be able to deliver events. The second is integrity: the payload hasn't been tampered with in transit. Different authentication methods address these problems in different ways, and choosing the right one depends on whether you control both sides of the integration.

This guide covers the four most common webhook authentication patterns, when to use each, and how to test them using Requex.me's built-in auth testing feature — without writing or running a backend server.

1. Bearer Token Authentication

Bearer token authentication is the most widely-used method for machine-to-machine webhook delivery. The caller includes a secret token in the Authorization header:

POST https://api.requex.me/hook/your-id HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{"event": "order.created", "data": {...}}

The token value is typically either a random opaque string (a pre-shared secret) or a signed JWT (JSON Web Token). For webhook-to-server integrations, opaque secrets are simpler and almost always sufficient — the server just does a constant-time string comparison.

Node.js verification example

const crypto = require('crypto');
const EXPECTED_TOKEN = process.env.WEBHOOK_SECRET;

function verifyBearerToken(req, res, next) {
  const header = req.headers['authorization'] || '';
  const token = header.startsWith('Bearer ') ? header.slice(7) : '';

  // Use timingSafeEqual to prevent timing attacks
  const expected = Buffer.from(EXPECTED_TOKEN);
  const actual   = Buffer.from(token);

  if (actual.length !== expected.length ||
      !crypto.timingSafeEqual(actual, expected)) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  next();
}

💡 Best for: Internal service-to-service webhooks, custom integrations where you control the sender, and any scenario where the webhook source is a system you own.

2. API Key Authentication

API key authentication is similar to Bearer tokens, but the key is passed in a custom header (such as X-API-Key) or as a query parameter rather than the Authorization header. This is common when the webhook sender is a SaaS platform that has its own API key concept.

POST https://api.requex.me/hook/your-id HTTP/1.1
X-API-Key: sk_live_abc123xyz
Content-Type: application/json

{"event": "payment.success", "amount": 9900}

You configure the header name and expected value in your webhook receiver. Some platforms also support embedding the key in the webhook URL itself as a query parameter (e.g., /hook/your-id?api_key=abc123), though header-based transmission is preferred since query parameters can leak into server logs.

⚠️ Note: API keys don't verify payload integrity — a valid key confirms who sent the request, but not that the body hasn't been modified. Combine with HMAC signatures for high-security scenarios.

💡 Best for: Receiving webhooks from external platforms (billing tools, CRMs, automation platforms) that let you configure a custom API key or secret header value.

3. Basic Authentication

HTTP Basic Authentication encodes a username and password pair in the Authorization header as a Base64-encoded string. While older than the other methods, many legacy systems and some well-known platforms (like certain Shopify flows) still use it for webhook delivery.

# The header value is: Basic base64("username:password")
POST https://api.requex.me/hook/your-id HTTP/1.1
Authorization: Basic d2ViaG9vazpteXNlY3JldA==
Content-Type: application/json

Verifying Basic Auth in Express

function verifyBasicAuth(req, res, next) {
  const header = req.headers['authorization'] || '';
  if (!header.startsWith('Basic ')) {
    res.setHeader('WWW-Authenticate', 'Basic realm="Webhooks"');
    return res.status(401).json({ error: 'Unauthorized' });
  }

  const decoded = Buffer.from(header.slice(6), 'base64').toString();
  const colonIdx = decoded.indexOf(':');
  const username = decoded.slice(0, colonIdx);
  const password = decoded.slice(colonIdx + 1);

  if (username !== process.env.WH_USER ||
      password !== process.env.WH_PASS) {
    return res.status(401).json({ error: 'Unauthorized' });
  }
  next();
}

💡 Best for: Legacy integrations, platforms that only support Basic Auth, or internal tools where you want the simplest possible auth that every HTTP client supports.

4. HMAC Signature Verification

HMAC (Hash-based Message Authentication Code) is the gold standard for webhook authentication because it solves both problems simultaneously: it proves the sender knows the shared secret, and it guarantees the payload hasn't been modified in transit. Stripe, GitHub, Shopify, and most serious platforms use HMAC-SHA256.

The sender computes a signature by applying HMAC-SHA256 to the raw request body using a shared secret, then includes the signature in a header. Your receiver performs the same computation and compares the two:

POST https://api.requex.me/hook/your-id HTTP/1.1
X-Webhook-Signature: sha256=c8b4d2e1f3a65d7b9c20e4f...
Content-Type: application/json

{"event": "push", "repository": "my-repo", "commits": [...]}

Verification (Node.js)

const crypto = require('crypto');

function verifyHmacSignature(rawBody, signatureHeader, secret) {
  // Compute expected signature
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody)  // must be the raw bytes, not parsed JSON
    .digest('hex');

  // Constant-time comparison prevents timing attacks
  const sigBuffer = Buffer.from(signatureHeader);
  const expBuffer = Buffer.from(expected);

  if (sigBuffer.length !== expBuffer.length) return false;
  return crypto.timingSafeEqual(sigBuffer, expBuffer);
}

// In your Express handler:
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['x-webhook-signature'];
  if (!verifyHmacSignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  const payload = JSON.parse(req.body);
  // Process payload...
  res.sendStatus(200);
});

⚠️ Critical: You must compute the HMAC over the raw request body bytes, not over a re-serialized JavaScript object. Any JSON serialization differences (key ordering, whitespace) will cause verification failures. Always buffer the raw body before parsing.

💡 Best for: Any production webhook endpoint where security matters. HMAC is the recommended method when you control the sender, and the only correct method when receiving from platforms like Stripe or GitHub that mandate it.

Comparison: When to Use Each Method

MethodProves IdentityProves IntegrityBest Use Case
Bearer Token✅ Yes❌ NoInternal services, trusted senders
API Key✅ Yes❌ NoSaaS platform integrations with custom headers
Basic Auth✅ Yes❌ NoLegacy systems, maximum compatibility
HMAC Signature✅ Yes✅ YesProduction APIs, Stripe/GitHub/Shopify, any high-security scenario

Testing Webhook Authentication with Requex.me

Requex.me lets you configure authentication requirements on your test webhook endpoint and then send test requests to verify your implementation — no server code required. This is useful for:

  • Verifying that your sender correctly attaches the expected auth header before going to production.
  • Testing rejection behavior — confirming that requests with wrong or missing credentials receive a 401 Unauthorized response.
  • Simulating the WWW-Authenticate challenge flow for Basic Auth.
  • Validating HMAC signature computation logic by sending a real signed request and checking whether it passes.

Step 1: Open Response Settings

Visit Requex.me to get your unique webhook URL. Click the Response Settings button in the left panel to open the configuration modal.

Step 2: Configure the Auth Tab

Navigate to the Auth tab in the settings modal. Toggle Require Authentication on, then select your method:

Bearer Token

Enter the expected token value. Requex.me will reject any request whose Authorization: Bearer <token> header doesn't match.

API Key

Specify the header name (e.g. X-API-Key) and the expected key value. All other requests are rejected with 401.

Basic Auth

Set the expected username and password. Enable Simulate Challenge to return a WWW-Authenticate header on 401 responses, just like a real server.

HMAC Signature

Enter your shared secret. Requex.me will compute HMAC-SHA256 over the raw request body and compare it to the signature in the header, exactly as a production server would.

Step 3: Save and Test

Click Save to persist your auth configuration. Your endpoint now actively enforces authentication. Send a request with the correct credentials and you'll see it appear in the request log. Send one without — or with a wrong token — and you'll get a 401 with no entry in the log.

# Test with correct Bearer token — should appear in dashboard
curl -X POST https://api.requex.me/hook/your-id \
  -H "Authorization: Bearer my-secret-token" \
  -H "Content-Type: application/json" \
  -d '{"event":"test"}'

# Test with wrong token — should return 401 and not appear in dashboard
curl -X POST https://api.requex.me/hook/your-id \
  -H "Authorization: Bearer wrong-token" \
  -H "Content-Type: application/json" \
  -d '{"event":"test"}'

Common Webhook Auth Problems and Fixes

Always getting 401 even with correct credentials

Cause: Token has trailing whitespace or newline characters

Fix: Trim the token value before comparison: token.trim()

HMAC signature never matches

Cause: Computing HMAC over parsed JSON instead of raw body

Fix: Buffer the raw request body before any JSON parsing. In Express, use express.raw() before express.json().

Basic Auth header missing

Cause: Client sends credentials in URL (https://user:pass@host)

Fix: Configure your HTTP client to send the Authorization header, not URL credentials.

Auth passes but request looks tampered

Cause: Using API key / Bearer token (identity only, not integrity)

Fix: Switch to HMAC to verify both sender identity and payload integrity.

Timing attack vulnerability

Cause: Using === for token comparison

Fix: Always use crypto.timingSafeEqual() for constant-time comparison.

Webhook Authentication Checklist

  • Endpoint served over HTTPS only (never plain HTTP)
  • Authentication method chosen based on security requirements
  • Secrets stored in environment variables, never hardcoded
  • Constant-time comparison used for token/signature matching
  • HMAC computed over raw request body, not parsed JSON
  • Timestamp validation implemented (for HMAC with replay protection)
  • Idempotency checks in place using event IDs
  • Auth tested with valid AND invalid credentials before deploying

Test Your Webhook Auth Now

Configure Bearer, API Key, Basic Auth, or HMAC on your free Requex.me endpoint and validate your integration in seconds.

Open Webhook Tester →

Related Guides & Resources