Skip to content

Webhooks

CyberCage provides webhooks to notify your systems of important security events in real-time.

Overview

Webhooks allow you to receive HTTP POST notifications when specific events occur in your CyberCage deployment:

  • New threats detected
  • MCP servers approved/blocked
  • Policy violations
  • Agent status changes
  • Security alerts

Webhook Configuration

Setting Up Webhooks

Configure webhooks in the Dashboard under Organization Settings > Integrations > Webhooks.

json
{
  "url": "https://your-server.com/webhook",
  "events": ["threat.detected", "server.blocked"],
  "secret": "your-webhook-secret",
  "enabled": true
}

Event Types

EventDescriptionPayload
threat.detectedMalicious activity detectedThreat details, agent info
threat.blockedThreat successfully blockedBlock action, timestamp
server.approvedMCP server approvedServer details, approver
server.blockedMCP server blockedServer details, reason
server.pendingNew server awaiting approvalServer config, requester
agent.onlineAgent came onlineAgent ID, device info
agent.offlineAgent went offlineAgent ID, last seen
policy.violationPolicy rule violatedPolicy details, violation

Webhook Security

Signature Verification

All webhook requests include a signature header for verification:

javascript
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(JSON.stringify(payload));
  const expectedSignature = `sha256=${hmac.digest('hex')}`;

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

Headers

HeaderDescription
X-CyberCage-SignatureHMAC-SHA256 signature
X-CyberCage-EventEvent type
X-CyberCage-Delivery-IDUnique delivery identifier
X-CyberCage-TimestampISO 8601 timestamp

Payload Examples

Threat Detection Event

json
{
  "event": "threat.detected",
  "timestamp": "2025-01-15T10:30:00Z",
  "organization_id": "org_abc123",
  "data": {
    "threat_id": "thr_xyz789",
    "severity": "high",
    "type": "data_exfiltration",
    "description": "Attempted to access sensitive API keys",
    "agent": {
      "id": "agt_def456",
      "hostname": "john-laptop",
      "user": "user@example.com"
    },
    "mcp_server": {
      "name": "custom-server",
      "command": "node server.js"
    },
    "details": {
      "tool": "filesystem_read",
      "path": "/home/user/.env",
      "blocked": true
    }
  }
}

Server Approval Event

json
{
  "event": "server.approved",
  "timestamp": "2025-01-15T11:00:00Z",
  "organization_id": "org_abc123",
  "data": {
    "server_id": "srv_ghi789",
    "name": "github",
    "identity_hash": "7f8e9d6c5a4b3e2f1a0b9c8d7e6f5a4b3c2d1e0f",
    "approved_by": "admin@example.com",
    "application": "Claude Desktop"
  }
}

Webhook Retries

CyberCage automatically retries failed webhook deliveries:

  • Retry Schedule: 1min, 5min, 15min, 1hr, 6hr
  • Max Retries: 5 attempts
  • Timeout: 30 seconds per request
  • Success Codes: 200-299

Delivery Status

Check webhook delivery status in the Dashboard:

  1. Navigate to Organization Settings > Integrations > Webhooks
  2. Click on a webhook to see delivery history
  3. View success/failure rates and retry attempts

Testing Webhooks

Test Event

Send a test event from the Dashboard:

bash
curl -X POST https://api.cybercage.io/ui/api/webhooks/test \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_id": "whk_123",
    "event": "test.ping"
  }'

Local Testing with ngrok

For local development:

bash
# Start local server
node webhook-server.js

# Expose via ngrok
ngrok http 3000

# Configure webhook with ngrok URL
https://abc123.ngrok.io/webhook

Webhook Endpoints

List Webhooks

bash
GET /ui/api/webhooks

Create Webhook

bash
POST /ui/api/webhooks
{
  "url": "https://example.com/webhook",
  "events": ["threat.detected"],
  "secret": "webhook_secret"
}

Update Webhook

bash
PUT /ui/api/webhooks/{webhook_id}
{
  "enabled": false
}

Delete Webhook

bash
DELETE /ui/api/webhooks/{webhook_id}

Get Delivery History

bash
GET /ui/api/webhooks/{webhook_id}/deliveries

Integration Examples

Slack Integration

javascript
// Express webhook handler for Slack
app.post('/webhook', async (req, res) => {
  const { event, data } = req.body;

  if (event === 'threat.detected') {
    await sendSlackAlert({
      text: `🚨 Threat Detected`,
      blocks: [
        {
          type: 'section',
          text: {
            type: 'mrkdwn',
            text: `*Severity:* ${data.severity}\n*Type:* ${data.type}\n*User:* ${data.agent.user}`
          }
        }
      ]
    });
  }

  res.status(200).send('OK');
});

PagerDuty Integration

python
# Python webhook handler for PagerDuty
import requests
from flask import Flask, request

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    data = request.json

    if data['event'] == 'threat.detected' and data['data']['severity'] == 'critical':
        # Trigger PagerDuty incident
        requests.post('https://events.pagerduty.com/v2/enqueue', json={
            'routing_key': PAGERDUTY_KEY,
            'event_action': 'trigger',
            'payload': {
                'summary': f"Critical threat: {data['data']['description']}",
                'severity': 'critical',
                'source': 'cybercage',
                'custom_details': data['data']
            }
        })

    return 'OK', 200

Rate Limits

  • Webhook Deliveries: 10,000 per hour per organization
  • Burst Limit: 100 requests per second
  • Payload Size: Max 1MB per webhook

Best Practices

  1. Always verify signatures to ensure webhook authenticity
  2. Implement idempotency - handle duplicate deliveries gracefully
  3. Respond quickly - process webhooks asynchronously if needed
  4. Monitor delivery rates - check Dashboard for failures
  5. Use specific event filters - only subscribe to needed events
  6. Secure your endpoint - use HTTPS and authentication
  7. Handle retries - return 2xx quickly to avoid unnecessary retries

Troubleshooting

Webhook Not Receiving Events

  • Verify webhook is enabled in Dashboard
  • Check event filters match expected events
  • Confirm endpoint is publicly accessible
  • Review delivery history for errors

Signature Validation Failing

  • Ensure using correct webhook secret
  • Verify signature algorithm (HMAC-SHA256)
  • Check for request body modifications by proxies
  • Compare raw body bytes, not parsed JSON

High Failure Rate

  • Check endpoint availability and response times
  • Verify SSL certificate if using HTTPS
  • Monitor for timeout issues (30s limit)
  • Review server logs for 5xx errors

Next Steps

Built in Berlin, DE 🇩🇪