Alle Artikel
Linear-Webhooks sicher auf localhost testen
Linearwebhookslocalhostdeveloper integrations

Linear-Webhooks sicher auf localhost testen

Ein externer Dienst kann localhost nicht direkt erreichen. Der Tunnel stellt eine öffentliche HTTPS-URL bereit und leitet echte headers sowie den unveränderten body an den lokalen Server weiter. Den raw body vor jedem JSON parser sichern. Erst Signatur und Eingaben prüfen, die Zustellung dauerhaft speichern und danach die Geschäftslogik starten.

Wie Linear-Webhooks eine lokale Anwendung erreichen

Ein externer Dienst kann localhost nicht direkt erreichen. Der Tunnel stellt eine öffentliche HTTPS-URL bereit und leitet echte headers sowie den unveränderten body an den lokalen Server weiter. >offizielle Dokumentation

1. Endpoint mit unverändertem raw body erstellen

Den raw body vor jedem JSON parser sichern. Erst Signatur und Eingaben prüfen, die Zustellung dauerhaft speichern und danach die Geschäftslogik starten.

import express from "express";
import crypto from "node:crypto";

const app = express();
const secret = process.env.LINEAR_WEBHOOK_SECRET;

app.post(
  "/webhooks/linear",
  express.raw({ type: "application/json", limit: "1mb" }),
  async (req, res) => {
    const rawBody = req.body;
    const signature = req.get("linear-signature");

    if (!verifyLinearSignature(signature, rawBody, secret)) {
      return res.sendStatus(401);
    }

    let payload;
    try {
      payload = JSON.parse(rawBody.toString("utf8"));
    } catch {
      return res.sendStatus(400);
    }

    if (!Number.isFinite(payload.webhookTimestamp) ||
        Math.abs(Date.now() - payload.webhookTimestamp) > 60_000) {
      return res.sendStatus(401);
    }

    const deliveryId = req.get("linear-delivery") || payload.webhookId;
    if (!deliveryId) return res.sendStatus(400);

    try {
      await recordAndEnqueueOnce(deliveryId, payload);
      return res.sendStatus(200);
    } catch (error) {
      console.error("Linear webhook persistence failed", error);
      return res.sendStatus(500);
    }
  }
);

app.use(express.json());
app.listen(3000);

Den raw body vor jedem JSON parser sichern. Erst Signatur und Eingaben prüfen, die Zustellung dauerhaft speichern und danach die Geschäftslogik starten. >offizielle Dokumentation

2. Lokalen Port über HTTPS bereitstellen

Server starten und den Tunnel in einem zweiten Terminal offen halten. Ein 401 für einen unsignierten Request bestätigt funktionierendes Routing und korrekte Ablehnung.

npx portpreview 3000
https://example.portpreview.dev/webhooks/linear

Server starten und den Tunnel in einem zweiten Terminal offen halten. Ein 401 für einen unsignierten Request bestätigt funktionierendes Routing und korrekte Ablehnung.

3. Webhook in Linear konfigurieren

Die vollständige HTTPS-URL eintragen, nur benötigte Events abonnieren und einen echten Fall im Testsystem auslösen. Das secret gehört nicht ins Repository.

Die vollständige HTTPS-URL eintragen, nur benötigte Events abonnieren und einen echten Fall im Testsystem auslösen. Das secret gehört nicht ins Repository.

Signatur über die exakten Bytes prüfen

HMAC mit dem Webhook-secret und den exakt spezifizierten Daten berechnen. In konstanter Zeit vergleichen und das secret nie protokollieren.

function verifyLinearSignature(signature, rawBody, secret) {
  if (!secret || typeof signature !== "string" ||
      !/^[0-9a-f]{64}$/i.test(signature)) {
    return false;
  }

  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest();
  const actual = Buffer.from(signature, "hex");

  return actual.length === expected.length &&
    crypto.timingSafeEqual(actual, expected);
}

HMAC mit dem Webhook-secret und den exakt spezifizierten Daten berechnen. In konstanter Zeit vergleichen und das secret nie protokollieren. >Praxisleitfaden

Replay-Angriffe per timestamp verhindern

Nach erfolgreicher Signaturprüfung die Aktualität des timestamp prüfen und die Host-Uhr synchron halten.

Nach erfolgreicher Signaturprüfung die Aktualität des timestamp prüfen und die Host-Uhr synchron halten.

Payload und Zustell-IDs verstehen

Nur bekannte type-Werte verarbeiten, zusätzliche Felder tolerieren und mit einer stabilen Zustell-ID dauerhaft deduplizieren.

Nur bekannte type-Werte verarbeiten, zusätzliche Felder tolerieren und mit einer stabilen Zustell-ID dauerhaft deduplizieren.

Schnell bestätigen und idempotent verarbeiten

Zustell-ID und job in einer atomaren Transaktion anlegen, bevor 200 zurückgegeben wird. Bei ausgefallenem Storage einen Fehler liefern.

Zustell-ID und job in einer atomaren Transaktion anlegen, bevor 200 zurückgegeben wird. Bei ausgefallenem Storage einen Fehler liefern. >Praxisleitfaden

Den vollständigen lokalen Ablauf testen

  1. Server starten und den Tunnel in einem zweiten Terminal offen halten. Ein 401 für einen unsignierten Request bestätigt funktionierendes Routing und korrekte Ablehnung.
  2. Die vollständige HTTPS-URL eintragen, nur benötigte Events abonnieren und einen echten Fall im Testsystem auslösen. Das secret gehört nicht ins Repository.
  3. HMAC mit dem Webhook-secret und den exakt spezifizierten Daten berechnen. In konstanter Zeit vergleichen und das secret nie protokollieren.
  4. Zustell-ID und job in einer atomaren Transaktion anlegen, bevor 200 zurückgegeben wird. Bei ausgefallenem Storage einen Fehler liefern.

Routing, headers, Signatur, Antwortzeit und Idempotenz prüfen. Synthetische Requests eignen sich vor allem für Ablehnungspfade.

Fehler bei Linear-Webhooks beheben

  • Server starten und den Tunnel in einem zweiten Terminal offen halten. Ein 401 für einen unsignierten Request bestätigt funktionierendes Routing und korrekte Ablehnung.
  • HMAC mit dem Webhook-secret und den exakt spezifizierten Daten berechnen. In konstanter Zeit vergleichen und das secret nie protokollieren.
  • Nach erfolgreicher Signaturprüfung die Aktualität des timestamp prüfen und die Host-Uhr synchron halten.
  • POST-path, Tunnel-port, raw body, secret, Systemzeit und Datenbanklatenz kontrollieren.

>Praxisleitfaden

Sicherheitscheckliste für Entwicklung und Produktion

  • HTTPS erzwingen, Größe und method begrenzen, secrets schützen, Logs bereinigen und veraltete Test-URLs entfernen.
  • Den raw body vor jedem JSON parser sichern. Erst Signatur und Eingaben prüfen, die Zustellung dauerhaft speichern und danach die Geschäftslogik starten.
  • Zustell-ID und job in einer atomaren Transaktion anlegen, bevor 200 zurückgegeben wird. Bei ausgefallenem Storage einen Fehler liefern.

HTTPS erzwingen, Größe und method begrenzen, secrets schützen, Logs bereinigen und veraltete Test-URLs entfernen. >Praxisleitfaden

Häufig gestellte Fragen

Wie teste ich einen Linear-Webhook auf localhost?
Server starten und den Tunnel in einem zweiten Terminal offen halten. Ein 401 für einen unsignierten Request bestätigt funktionierendes Routing und korrekte Ablehnung.
Wie prüfe ich die Signatur eines Linear-Webhooks?
HMAC mit dem Webhook-secret und den exakt spezifizierten Daten berechnen. In konstanter Zeit vergleichen und das secret nie protokollieren.
Warum stellt Linear den Webhook erneut zu?
Zustell-ID und job in einer atomaren Transaktion anlegen, bevor 200 zurückgegeben wird. Bei ausgefallenem Storage einen Fehler liefern.
Welcher Schlüssel eignet sich für Idempotenz?
Nur bekannte type-Werte verarbeiten, zusätzliche Felder tolerieren und mit einer stabilen Zustell-ID dauerhaft deduplizieren.