Zum Inhalt springen

Anleitungen

Webhooks

Ein Webhook-Endpunkt erhält, was die Alarmregeln eines Workspace an ihn leiten: ein blockiertes Release, ein Ergebnis, das auf eine Person wartet, einen beendeten verwalteten Lauf, den Alarm einer Produktionsüberwachung. Jede Zustellung ist ein JSON-Body, signiert mit dem Geheimnis des Endpunkts, sodass Ihr Server prüfen kann, dass sie von Ihrem Workspace kommt, bevor er handelt.

Einen Endpunkt hinzufügen

Auf der Seite Integrationen des Workspace fügt ein Owner oder Admin einen signierten Webhook mit einem Namen und einer öffentlichen https-URL auf Port 443 oder 8443 hinzu. Die Seite zeigt dann das Signiergeheimnis des Endpunkts, das mit whsec_ beginnt. Kopieren Sie es sofort: Es wird verschlüsselt gespeichert und nicht erneut angezeigt. Um es zu ersetzen, löschen Sie den Endpunkt und fügen ihn erneut hinzu.

Wählen Sie dann auf der Seite Alarme den Endpunkt als Kanal einer oder mehrerer Regeln. „Test senden“ schickt eine oloproof.test-Zustellung und zeigt den Status, mit dem Ihr Server geantwortet hat.

Was gesendet wird

{
  "type": "oloproof.gate_blocked",
  "id": "dlv_8c1f0a2b3c4d5e6f7a8b9c0d",
  "created_at": "2026-10-26T14:03:00.000Z",
  "workspace": "acme",
  "rule": { "id": "rul_1a2b3c4d5e6f7a8b9c0d1e2f", "name": "Do not ship" },
  "event": "gate_blocked",
  "items": [
    {
      "project": "support",
      "kind": "run",
      "id": "run_20261026T140100_4f2a",
      "release_action": "BLOCK",
      "rules": [["faithfulness", "FAIL"]],
      "href": "https://oloproof.com/app/workspaces/acme/projects/support/runs/run_20261026T140100_4f2a"
    }
  ],
  "more": 0
}

Ein Eintrag enthält Ids, die Entscheidungszustände der Engine, die Release-Aktion, Zustand und Ausgang eines Jobs, Niveau, Schwelle und Intervall einer Überwachung, so wie die Engine sie geschrieben hat, und Links. Er enthält nie Eingabe, Ausgabe, erwartete Antwort oder Labels eines Falls. Eine Zustellung enthält höchstens 50 Einträge; more zählt die Ereignisse darüber hinaus.

Eine Zustellung prüfen

Jede Zustellung trägt drei Header in der Form von Standard Webhooks:

  • webhook-id: die Id der Zustellung, bei jedem neuen Versuch dieselbe.
  • webhook-timestamp: wann dieser Versuch gesendet wurde, in Sekunden seit 1970.
  • webhook-signature: v1, und das Base64-HMAC-SHA256 von id.timestamp.body, mit den Bytes des Geheimnisses als Schlüssel (der Teil nach whsec_, Base64-dekodiert).

Berechnen Sie die Signatur über den rohen Body, wie er empfangen wurde, vergleichen Sie in konstanter Zeit, und lehnen Sie einen Zeitstempel ab, der mehr als fünf Minuten von Ihrer Uhr abweicht.

import base64, hashlib, hmac, time

def verify(secret: str, headers: dict, body: bytes) -> bool:
    key = base64.b64decode(secret.removeprefix("whsec_"))
    msg = f"{headers['webhook-id']}.{headers['webhook-timestamp']}.".encode() + body
    expected = base64.b64encode(hmac.new(key, msg, hashlib.sha256).digest()).decode()
    fresh = abs(time.time() - int(headers["webhook-timestamp"])) <= 300
    given = [part.split(",", 1)[-1] for part in headers["webhook-signature"].split()]
    return fresh and any(hmac.compare_digest(expected, sig) for sig in given)
import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(secret, headers, body) {
  const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
  const id = headers["webhook-id"], ts = headers["webhook-timestamp"];
  const expected = createHmac("sha256", key).update(`${id}.${ts}.${body}`).digest("base64");
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) <= 300;
  return fresh && headers["webhook-signature"].split(" ").some((part) => {
    const sig = Buffer.from(part.split(",").pop());
    return sig.length === expected.length && timingSafeEqual(sig, Buffer.from(expected));
  });
}

Die Bibliotheken von Standard Webhooks prüfen dieselben Header.

Zustellung

Antworten Sie innerhalb von zehn Sekunden mit einem beliebigen 2xx-Status. Alles andere, einschließlich einer Weiterleitung, ist ein fehlgeschlagener Versuch, der nach 1, 5, 30, 120 und 360 Minuten wiederholt und dann aufgegeben wird. Da eine Antwort verloren gehen kann, nachdem Ihr Server bereits gehandelt hat, kann dieselbe Zustellung zweimal ankommen: Verwenden Sie webhook-id, um eine Wiederholung zu verwerfen. Eine Regel löst höchstens einmal je Ereignis aus, eine neue Id ist also eine neue Zustellung.

Vor jedem Versuch wird der Name des Endpunkts neu aufgelöst, und die Anfrage geht nur an eine öffentliche Adresse: Loopback-, private, Link-Local-, geteilte, reservierte und Cloud-Metadaten-Adressen werden abgelehnt, ebenso IPv6-Formen, die eine davon enthalten. Die Verbindung wird zur geprüften Adresse aufgebaut, und das Zertifikat wird gegen den Namen geprüft.

Slack

Ein Slack-Endpunkt ist eine Incoming-Webhook-URL. Er erhält eine kurze englische Nachricht, eine Zeile pro Ereignis, mit einem Link zu jedem Ergebnis. Slack prüft die Signatur-Header nicht, die trotzdem gesendet werden.