ガイド
Webhooks
webhook エンドポイントは、ワークスペースのアラートルールがそこへ送るものを受け取ります。ブロックされたリリース、人の判断を待つ結果、終了したマネージド実行、本番モニターのアラームです。各配信はエンドポイントのシークレットで署名された JSON 本文なので、サーバーは処理する前に、それがあなたのワークスペースから来たことを確認できます。
エンドポイントを追加する
ワークスペースの Integrations ページで、Owner または Admin が名前と、ポート 443 または 8443 上の公開 https URL を指定して署名付き webhook を追加します。するとページに、whsec_ で始まるエンドポイントの署名シークレットが表示されます。そのときにコピーしてください。シークレットは暗号化して保存され、二度と表示されません。置き換えるには、エンドポイントを削除してから追加し直します。
次に Alerts ページで、1 つ以上のルールのチャネルとしてそのエンドポイントを選びます。「Send a test」は oloproof.test の配信を送り、サーバーが返したステータスを表示します。
送られる内容
{
"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
}項目には、id、エンジンの判定状態、リリースアクション、ジョブの状態と結果、エンジンが書いたとおりのモニターの水準、しきい値、区間、そしてリンクが含まれます。ケースの入力、出力、期待される回答、ラベルは決して含まれません。1 回の配信に含まれる項目は最大 50 件で、more はそれを超えたイベントの数です。
配信を検証する
すべての配信は、Standard Webhooks の形式で 3 つのヘッダーを持ちます。
- webhook-id: 配信の id。再試行でも同じです。
- webhook-timestamp: この試行が送られた時刻。1970 年からの秒数です。
- webhook-signature: v1, と、シークレットのバイト列(whsec_ の後の部分を base64 デコードしたもの)をキーとする id.timestamp.body の base64 HMAC-SHA256。
受け取ったままの生の本文に対して署名を計算し、定数時間で比較し、あなたの時計から 5 分以上ずれたタイムスタンプは拒否してください。
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));
});
}Standard Webhooks のライブラリも同じヘッダーを検証します。
配信
10 秒以内に任意の 2xx ステータスで応答してください。それ以外(リダイレクトを含む)は失敗した試行とみなされ、1、5、30、120、360 分後に再試行され、その後は断念されます。サーバーが処理した後に応答が失われることがあるため、同じ配信が 2 回届くことがあります。webhook-id を使って重複を捨ててください。ルールは 1 つのイベントにつき最大 1 回しか発火しないため、新しい id は新しい配信です。
各試行の前にエンドポイントの名前が改めて解決され、リクエストは公開アドレスにのみ送られます。ループバック、プライベート、リンクローカル、共有、予約済み、クラウドのメタデータのアドレスは拒否され、それらを含む IPv6 形式も同様です。接続は確認されたアドレスに対して行われ、証明書は名前に対して検証されます。
Slack
Slack エンドポイントは incoming webhook の URL です。イベントごとに 1 行の短い英語のメッセージを受け取り、各結果へのリンクが付きます。Slack は署名ヘッダーを確認しませんが、ヘッダーはそれでも送られます。