warden.yaml
Nothing waits on delivery. Notifications are a subscriber to the same event stream the operator view uses, not a step in the pipeline. An endpoint that is slow, down, or hostile delays no approval and blocks no agent — a reviewer who never got the message can still open the operator view, which remains the authority.
What is delivered
resolved event carries the same operation plus how it ended:
- The statement keeps its parameters unbound (
$1), exactly as the operator view shows it. You see the shape of the operation, not the customer data it touches. - The preview is already masked and column-restricted, by the gate, before it ever reaches the pending queue. A notification cannot leak a value the agent itself was not allowed to read.
Verifying a delivery
Every request carriesX-Warden-Event, X-Warden-Delivery, and:
v1 is HMAC-SHA256(secret, "<t>.<raw body>"), hex-encoded. Verify it before acting on anything, and reject deliveries whose timestamp is outside a few minutes — that is what stops an old, valid message being replayed at you.
Delivery behaviour
Retries are deliberately few. A notification is a convenience, so a queue that grows while an endpoint is down would cost more than the messages are worth.
Watch
warden_webhook_deliveries_total by result:
Requirements
string
Where reviewers reach this gateway. Used to build the links in a payload; omitted entirely if unset, rather than guessing an address that may not resolve from wherever the message is read.
string
required
Must be
https. A plaintext http endpoint is refused unless allow_insecure: true is set, and warns at startup every time: the payload carries the statement and the preview, and a signature proves origin without hiding content.string
required
At least 16 characters. Required, because an unsigned webhook is one anyone who learns the URL can forge — and these carry approval requests.
array
proposed, resolved, or both. Empty sends both.Slack is next, and builds on this. Approve and reject buttons in a Slack message, verified with Slack’s signing secret, with each Slack user mapped to a named operator so the audit chain records who decided. Until then, a small relay that receives these webhooks and posts to Slack gets you most of the way — the payload already carries the diff.