Webhooks

Receiving real-time vault event notifications via signed HTTP payloads.

Webhooks deliver vault events to your own HTTP endpoints as signed JSON payloads. When a subscribed action fires, SikkerKey POSTs the event to your URL with an HMAC-SHA256 signature so you can verify authenticity.

Webhooks require a paid plan. The number of webhooks you can create and the daily delivery limit depend on your plan. Check the pricing page for details.

Creating a Webhook

From the dashboard, go to the Alerts page. The Webhooks card is at the top. Click the + button to open the create modal.

  1. Enter your endpoint URL. It must use HTTPS.
  2. Select which events to subscribe to. Events are grouped by category (Secrets, Machines, Projects, Authentication, Teams, Sessions). Use the search bar, severity filter, and category filter to find specific actions. Click a category checkbox to select all actions in that group.
  3. Click Create Webhook.

After creation, the signing secret is displayed once. Copy it immediately -- it will not be shown again. You need this secret to verify webhook signatures on your server.

Payload Format

Every webhook delivery is an HTTP POST with Content-Type: application/json and these headers:

HeaderValue
X-SikkerKey-Delivery-IdUnique UUID for this delivery, use for deduplication
X-SikkerKey-SignatureHMAC-SHA256 hex digest of the request body
X-SikkerKey-EventThe action name (e.g. secret_create)
User-AgentSikkerKey-Webhook/1.0

The JSON body:

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "event": "secret_delete",
  "severity": "high",
  "timestamp": 1712678400000,
  "data": {
    "userId": "...",
    "machineId": "...",
    "secretId": "sk_abc123",
    "sourceIp": "203.0.113.42",
    "detail": "Secret deleted: production-api-key"
  }
}

Fields in data are included only when relevant to the event. For example, machineId is null for events that don't involve a machine.

Verifying Signatures

Compute the HMAC-SHA256 of the raw request body using the signing secret you received at creation. Compare it to the X-SikkerKey-Signature header value.

import hmac, hashlib

def verify(body: bytes, secret: str, signature: str) -> bool:
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)
const crypto = require('crypto');

function verify(body, secret, signature) {
  const expected = crypto.createHmac('sha256', secret).update(body).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
func verify(body []byte, secret, signature string) bool {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write(body)
    expected := hex.EncodeToString(mac.Sum(nil))
    return hmac.Equal([]byte(expected), []byte(signature))
}

Always use constant-time comparison to prevent timing attacks.

Deduplication

Every delivery includes a unique id (UUID) in the payload body and as the X-SikkerKey-Delivery-Id header. This ID stays the same across retries of the same delivery.

If your endpoint returns a success but the response doesn't reach SikkerKey (network issue, timeout), the same payload will be retried with the same id. Store processed delivery IDs on your end and skip duplicates.

Delivery Behavior

  • Timeout: Each delivery attempt has a 15-second timeout.
  • Retries: Failed deliveries are retried up to 3 times with exponential backoff (5 seconds, 30 seconds, 5 minutes).
  • Success: Any HTTP 2xx response is treated as successful.
  • Health tracking: Consecutive failures are tracked per webhook. After 10 consecutive failures, the webhook is automatically disabled.
  • Burst limiting: Outbound deliveries are globally rate-limited to 60 per second with burst capacity. This prevents high-activity events from overwhelming your endpoints.

Managing Webhooks

From the Webhooks card on the Alerts page:

  • Test: Sends a test payload (webhook_test event with info severity) to verify your endpoint is reachable.
  • Disable / Enable: Toggles the webhook without deleting it. Re-enabling resets the health status and failure counter.
  • Delete: Permanently removes the webhook.

Each webhook row shows:

  • The endpoint URL
  • Health status: healthy, unhealthy, or disabled
  • Number of subscribed events
  • Last successful delivery time
  • Consecutive failure count (if any)
  • Last error message (if any)

Plan Limits

Your plan determines two webhook limits:

  • Webhook endpoints: the maximum number of webhooks you can create.
  • Daily deliveries: the maximum number of webhook payloads delivered per day, resetting at midnight UTC.

When the daily delivery limit is reached, remaining deliveries for the day are silently dropped. The webhook remains healthy -- deliveries resume the next day.