Agent Operations Platform
Webhooks
Governance nobody sees is governance nobody acts on. Webhooks push selected events out as signed HTTP POSTs: a denial reaches an on-call channel, a suspended agent reaches your SOAR runbook, and nobody polls for either. The delivery record proves they arrived.
Workflow
Select the events.Prove they landed.
A subscription matches events by type and filter. A destination receives them, signed. Every attempt is recorded, and failures replay once the receiver is healthy.
- 01
Subscribe
Match events by type, then narrow by filter. One call creates the subscription and its destination together.
- 02
Deliver
Signed HTTP POSTs to a custom endpoint or a catalog provider. Verify with any Standard Webhooks library.
- 03
Inspect
Every attempt is recorded with its outcome, and the body is retained so you can see exactly what was sent.
- 04
Replay
Re-send one delivery or a window of failures. The event id is preserved, so correct consumers dedupe.
Consistent operations
A published contract rather than the internal schema
Eventing projects selected facts from the audit trail onto a versioned public contract. Your integrations build against a declared shape, and the internal schema stays free to change. Event types share their names with the audit operations behind them, so subscribing and querying use one vocabulary.
Signed to a public spec
Deliveries follow the Standard Webhooks specification, so verification is an existing library rather than bespoke code. Each destination holds its own secret.
Secrets rotate without a gap
A rotation signs each delivery with both the new and the previous key for 24 hours. A consumer keeps verifying while you move it across.
Filters that compose
Repeat a key for OR, use distinct keys for AND, glob a value when a prefix is what matters. Envelope filters — outcome, stage, denial reason, error presence — apply to every type, and they are how a high-volume per-request subscription becomes specific enough to be useful.
Delivery you can audit
Attempt history per delivery, with the retained body. "Did the SOC get told?" becomes a query you can answer.
Replay, gated separately
A replay is a new delivery carrying the original event id, so a consumer that dedupes processes it once. Re-sending can re-trigger automation, so the permission is separate: fixing a destination is not the same right as re-firing a day of alerts.
Providers, not just endpoints
A catalog of off-the-shelf destinations lets a subscription target an existing incoming-webhook URL. Useful before anyone has written a receiver.
In practice
From subscription to replay
Subscriptions, deliveries and replay are reachable from the CLI, the API, and the MCP surface. On the receiving end, verification is a library call: acknowledge inside ten seconds and process asynchronously, because a slow handler burns retry budget.
# Denied tool calls to an ops endpoint
dome webhooks subscriptions create alerts \
--url https://ops.example.com/hooks/dome \
--event-type tool.call \
--filter 'result=denied'
# Lifecycle changes to Slack, no receiver needed
dome webhooks subscriptions create slack-alerts \
--provider slack \
--event-type agent.suspend \
--event-type agent.revoke
# Glob a value; repeat a key to mean OR
dome webhooks subscriptions create demo-tools \
--url https://... --event-type tool.call \
--filter 'tool_name~=demo-mcp/*'# Prove the destination works before you rely on it
dome webhooks subscriptions test alerts
# What failed, and what was actually sent?
dome webhooks deliveries list --status failed
dome webhooks deliveries get <delivery-id> --body
# Re-send a window once the receiver is healthy
dome webhooks deliveries replay-failed --since 24h
# Move to a new signing secret, 24h dual-signed
dome webhooks subscriptions rotate-secret alertsimport { Webhook } from "standardwebhooks";
const wh = new Webhook(process.env.DOME_WEBHOOK_SECRET); // whsec_...
app.post("/webhooks/dome", express.raw({ type: "application/json" }), (req, res) => {
try {
const event = wh.verify(req.body, req.headers);
// Dedupe on req.headers["dome-event-id"], then process async.
res.status(202).send();
} catch {
res.status(400).send("invalid signature");
}
});Questions
Common questions about agent event delivery
How is eventing different from audit?
Audit is the record and eventing is the reflex. Audit is complete, immutable, and retained for evidence. Eventing projects selected facts onto a versioned public contract for delivery elsewhere, keeping the internal schema out of the API.
How are webhook deliveries signed?
Each destination has its own signing secret and deliveries are signed to the Standard Webhooks specification, so any Standard Webhooks library verifies them. The secret is revealed once at creation and is rotatable but never readable again.
What happens when my endpoint is down?
Dome retries, records every attempt, and retains the body so you can inspect and replay. A replay carries the original event id, so a consumer that dedupes on it ignores the overlap.
Can an agent subscribe to events?
No. The webhooks API is called by people and scoped platform API keys, not by agent credentials. Delivery configuration is an operator concern, so a compromised agent cannot redirect the event stream.
Do I need a webhook receiver to start?
No. A provider catalog covers off-the-shelf destinations, so a subscription can point at an existing incoming-webhook URL without you writing a receiver. Custom HTTPS endpoints use the same subscription model.