Real-time security events
The audit log is your record of what happened. Webhooks are how you find out the moment it happens — an agent gets denied, revoked, force-reauthed, or starts calling tools at an abnormal rate. Every payload is HMAC-SHA256 signed so you can verify it actually came from ModGate.
1. Event types
| Event | Fires when |
|---|---|
| agent.denied | An agent calls a tool outside its scope policy |
| agent.revoked | An agent identity is revoked, from the dashboard or API |
| token.rejected | A token fails validation — bad signature, wrong audience, unknown client |
| delegation.chain_broken | A delegated request fails because an ancestor in its xAA chain was revoked or expired |
| anomaly.rate_exceeded | An agent exceeds its per-minute call-velocity threshold |
| session.reauth_required | A request is rejected by continuous authorization — live revocation, a reverify-window timeout, or an admin force-reauth |
| quota.threshold | A tenant crosses 80% or 100% of its monthly authentication quota |
2. Register a webhook
Point ModGate at any HTTPS endpoint and choose which events you want. Omit events to subscribe to everything.
POST https://api.modgate.io/webhooks/{tenantId}
X-ModGate-API-Key: YOUR_API_KEY
Content-Type: application/json
{
"url": "https://yourapp.com/hooks/modgate",
"events": ["agent.revoked", "session.reauth_required", "anomaly.rate_exceeded"]
}
# Response:
{
"id": "wh_a1b2c3...",
"tenantId": "org_...",
"url": "https://yourapp.com/hooks/modgate",
"secret": "whsec_...",
"events": ["agent.revoked", "session.reauth_required", "anomaly.rate_exceeded"],
"active": true,
"createdAt": "2026-07-16T00:00:00Z",
"secret_hint": "Save this secret — it will not be shown again: whsec_..."
}GET /webhooks/{tenantId} redacts it on every subsequent read. Store it somewhere safe the moment you create the webhook.3. Payload and headers
Every delivery is a POST with a JSON body wrapping the event-specific data:
POST https://yourapp.com/hooks/modgate
Content-Type: application/json
X-ModGate-Signature: sha256=3f2e1a...
X-ModGate-Timestamp: 1752624000
X-ModGate-Event: agent.revoked
X-ModGate-Delivery: evt_9f8e7d...
{
"id": "evt_9f8e7d...",
"type": "agent.revoked",
"tenantId": "org_...",
"timestamp": 1752624000,
"api_version": "2026-07",
"data": {
"agentId": "agent_xyz789",
"agentName": "billing-bot",
"wasOrchestrator": false,
"revokedAt": "2026-07-16T00:00:00Z"
}
}X-ModGate-Delivery is unique per attempt — use it to de-duplicate if your endpoint might receive the same event more than once (see retries, below).
4. Verify the signature
The signature is HMAC-SHA256 over {timestamp}.{raw body}, keyed with your webhook's secret. Always verify against the raw request body — not a re-serialized copy.
import crypto from 'crypto'
function verify(secret, timestamp, rawBody, signatureHeader) {
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex')
const provided = signatureHeader.replace('sha256=', '')
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(provided)
)
}crypto.timingSafeEqual), never ===, when comparing signatures.5. Delivery and retries
ModGate retries a failed delivery (non-2xx response, timeout, or network error) up to 3 times with exponential backoff — 500ms, 1s, then 2s. A 10-second timeout applies to each attempt. Webhook delivery never blocks or delays the underlying request that triggered it.
GET https://api.modgate.io/webhooks/{tenantId}/{webhookId}/deliveries
X-ModGate-API-Key: YOUR_API_KEY
# Response:
{
"deliveries": [
{
"id": "del_...",
"eventType": "agent.revoked",
"status": "success",
"statusCode": 200,
"attempts": 1,
"deliveredAt": "2026-07-16T00:00:01Z"
}
],
"total": 1
}Delivery logs are retained for 30 days.
6. Best practices
- HTTPS only — ModGate rejects non-HTTPS endpoints at registration.
- Always verify the signature before trusting the payload — anyone can POST to a public URL.
- Respond 2xx as soon as you've durably queued the event; do the actual processing asynchronously.
- De-duplicate on X-ModGate-Delivery — retries mean the same event can arrive more than once.
- Subscribe only to the events you act on — fewer moving parts, easier to reason about.
Questions? We answer personally.
[email protected] →