Handleidingen
Webhooks
Een webhook-endpoint ontvangt wat de alertregels van een werkruimte ernaartoe sturen: een geblokkeerde release, een resultaat dat op een persoon wacht, een beheerde run die eindigde, het alarm van een productiemonitor. Elke levering is een JSON-body ondertekend met het geheim van het endpoint, zodat je server kan controleren dat ze van je werkruimte komt voordat hij erop handelt.
Een endpoint toevoegen
Op de Integrations-pagina van de werkruimte voegt een Owner of Admin een ondertekende webhook toe met een naam en een openbare https-URL op poort 443 of 8443. De pagina toont dan het ondertekeningsgeheim van het endpoint, dat begint met whsec_. Kopieer het op dat moment: het wordt versleuteld opgeslagen en niet opnieuw getoond. Om het te vervangen, verwijder je het endpoint en voeg je het opnieuw toe.
Kies daarna op de Alerts-pagina het endpoint als kanaal van een of meer regels. "Send a test" verstuurt een oloproof.test-levering en toont de status waarmee je server antwoordde.
Wat er wordt verstuurd
{
"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
}Een item bevat ids, de beslissingsstatussen van de engine, de releaseactie, de status en uitkomst van een job, het niveau, de drempel en het interval van een monitor zoals de engine ze schreef, en links. Het bevat nooit de invoer, uitvoer, het verwachte antwoord of de labels van een case. Een levering bevat hoogstens 50 items; more telt de gebeurtenissen daarna.
Een levering verifiëren
Elke levering draagt drie headers, in de vorm van Standard Webhooks:
- webhook-id: de id van de levering, bij elke nieuwe poging dezelfde.
- webhook-timestamp: wanneer deze poging werd verstuurd, in seconden sinds 1970.
- webhook-signature: v1, en de base64 HMAC-SHA256 van id.timestamp.body, met als sleutel de bytes van het geheim (het deel na whsec_, base64-gedecodeerd).
Bereken de handtekening over de ruwe body zoals ontvangen, vergelijk haar in constante tijd, en weiger een timestamp die meer dan vijf minuten van je klok afwijkt.
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));
});
}De bibliotheken van Standard Webhooks verifiëren dezelfde headers.
Levering
Antwoord binnen tien seconden met een willekeurige 2xx-status. Al het andere, een omleiding inbegrepen, is een mislukte poging, die opnieuw wordt geprobeerd na 1, 5, 30, 120 en 360 minuten en daarna wordt opgegeven. Omdat een antwoord verloren kan gaan nadat je server er al op handelde, kan dezelfde levering twee keer aankomen: gebruik webhook-id om een herhaling te negeren. Een regel gaat hoogstens één keer af per gebeurtenis, dus een nieuwe id is een nieuwe levering.
Vóór elke poging wordt de naam van het endpoint opnieuw opgezocht, en het verzoek gaat alleen naar een adres dat openbaar is: loopback-, privé-, link-local-, gedeelde, gereserveerde en cloud-metadata-adressen worden geweigerd, net als IPv6-vormen die er een van bevatten. De verbinding wordt gemaakt met het adres dat werd gecontroleerd, en het certificaat wordt gecontroleerd tegen de naam.
Slack
Een Slack-endpoint is een incoming-webhook-URL. Het ontvangt een kort Engelstalig bericht, één regel per gebeurtenis, met een link naar elk resultaat. Slack controleert de handtekeningheaders niet, die toch worden meegestuurd.