Webhooks Management
Configure webhooks to receive real-time event notifications from Cerberus IAM.
Endpoints
List Webhooks
Retrieve all webhooks configured for the organisation.
Endpoint
GET /v1/admin/webhooksAuthentication
- Required: Yes
- Required Permission:
webhooks:read
Response (200 OK)
json
{
"data": [
{
"id": "wh_01h2xz9k3m4n5p6q7r8s9t0v2h",
"url": "https://api.example.com/webhooks/cerberus",
"events": ["user.created", "user.updated", "user.deleted"],
"clientId": null,
"isActive": true,
"createdAt": "2025-10-20T10:00:00.000Z",
"updatedAt": "2025-10-26T08:30:00.000Z"
}
],
"total": 1
}Note: The webhook secret is never exposed in responses.
Get Webhook
Retrieve details of a specific webhook.
Endpoint
GET /v1/admin/webhooks/:idAuthentication
- Required: Yes
- Required Permission:
webhooks:read
Create Webhook
Create a new webhook endpoint.
Endpoint
POST /v1/admin/webhooksAuthentication
- Required: Yes
- Required Permission:
webhooks:create
Request Body
json
{
"url": "https://api.example.com/webhooks/cerberus",
"events": ["user.created", "user.updated", "user.deleted", "role.created"],
"clientId": "cli_01h2xz9k3m4n5p6q7r8s9t0v2d"
}| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Webhook endpoint URL (must be HTTPS) |
events | array | Yes | Array of event types to subscribe to |
clientId | string | No | Optional OAuth client ID for filtering |
Available Events
user.created,user.updated,user.deleted,user.blockedrole.created,role.updated,role.deletedteam.created,team.updated,team.deletedclient.created,client.updated,client.revokedsession.created,session.revokedlogin.success,login.failedmfa.enabled,mfa.disabled
Response (201 Created)
json
{
"id": "wh_01h2xz9k3m4n5p6q7r8s9t0v2i",
"url": "https://api.example.com/webhooks/cerberus",
"secret": "whsec_abc123def456...",
"events": ["user.created", "user.updated", "user.deleted"],
"clientId": null,
"isActive": true,
"createdAt": "2025-10-26T12:00:00.000Z",
"updatedAt": "2025-10-26T12:00:00.000Z"
}Important: The secret is only returned on creation. Use it to verify webhook signatures.
Update Webhook
Update webhook configuration.
Endpoint
PATCH /v1/admin/webhooks/:idAuthentication
- Required: Yes
- Required Permission:
webhooks:update
Request Body (all optional)
json
{
"url": "https://api.example.com/webhooks/cerberus-v2",
"events": ["user.created", "user.deleted"],
"isActive": false
}Delete Webhook
Delete a webhook endpoint.
Endpoint
DELETE /v1/admin/webhooks/:idAuthentication
- Required: Yes
- Required Permission:
webhooks:delete
Response (204 No Content)
Rotate Webhook Secret
Generate a new signing secret for the webhook.
Endpoint
POST /v1/admin/webhooks/:id/rotate-secretAuthentication
- Required: Yes
- Required Permission:
webhooks:update
Response (200 OK)
json
{
"id": "wh_01h2xz9k3m4n5p6q7r8s9t0v2i",
"url": "https://api.example.com/webhooks/cerberus",
"secret": "whsec_new987zyx654...",
"events": ["user.created", "user.updated"],
"clientId": null,
"isActive": true,
"createdAt": "2025-10-26T12:00:00.000Z",
"updatedAt": "2025-10-26T12:30:00.000Z"
}Note: The new secret is returned. Update your webhook verification code.
Test Webhook
Send a test event to verify webhook configuration.
Endpoint
POST /v1/admin/webhooks/:id/testAuthentication
- Required: Yes
- Required Permission:
webhooks:update
Response (200 OK)
json
{
"message": "Test webhook sent"
}The test event payload:
json
{
"id": "evt_test_123",
"type": "webhook.test",
"createdAt": "2025-10-26T12:00:00.000Z",
"data": {
"message": "This is a test webhook event",
"webhookId": "wh_01h2xz9k3m4n5p6q7r8s9t0v2i"
}
}Webhook Payload Format
All webhooks receive payloads in this format:
json
{
"id": "evt_01h2xz9k3m4n5p6q7r8s9t0v2j",
"type": "user.created",
"createdAt": "2025-10-26T12:00:00.000Z",
"organisationId": "org_01h2xz9k3m4n5p6q7r8s9t0v1x",
"data": {
"user": {
"id": "usr_01h2xz9k3m4n5p6q7r8s9t0v3x",
"email": "[email protected]",
"name": "New User"
}
}
}Verifying Webhook Signatures
Cerberus signs webhooks with HMAC SHA-256. Verify signatures:
javascript
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}
// Express.js example
app.post('/webhooks/cerberus', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-cerberus-signature'];
const payload = req.body.toString();
if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(payload);
// Process event...
res.status(200).send('OK');
});Headers Sent
| Header | Description |
|---|---|
X-Cerberus-Signature | HMAC SHA-256 signature of the payload |
X-Cerberus-Event | Event type (e.g., user.created) |
X-Cerberus-Delivery | Unique delivery ID |
Content-Type | application/json |
User-Agent | Cerberus-Webhooks/1.0 |
Retry Behavior
- Failed webhooks are retried with exponential backoff
- Retry schedule: 1m, 5m, 15m, 1h, 6h, 24h
- After 6 failed attempts, the webhook is marked as failed
- Monitor webhook health via delivery logs (future feature)
Best Practices
- Verify signatures: Always validate the
X-Cerberus-Signatureheader - Respond quickly: Return 200 status within 5 seconds to avoid retries
- Process asynchronously: Queue events for background processing
- Use HTTPS: Webhook URLs must use HTTPS
- Rotate secrets: Regularly rotate webhook secrets for security
- Handle duplicates: Implement idempotency using the event
id - Monitor failures: Set up alerting for webhook delivery failures
Notes
- Webhooks are delivered in near real-time (typically < 1 second)
- The
clientIdfield filters events for a specific OAuth client - Inactive webhooks (
isActive: false) do not receive events - Deleted webhooks cannot be recovered
- Use the test endpoint to validate your integration