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
- 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.
- 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.
- HMAC mit dem Webhook-secret und den exakt spezifizierten Daten berechnen. In konstanter Zeit vergleichen und das secret nie protokollieren.
- 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.
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
