Dashboard Guide
Webhooks

Webhooks

Webhooks allow Tenuo Cloud to notify your systems when important events occur, such as key creation, revocations, or SRL regeneration.

Supported Events

EventDescription
key.createdA new key was created
key.rotatedA key was rotated
key.revokedA key was revoked
key.suspendedA key was suspended
key.enabledA suspended key was re-enabled
revocation.createdA warrant was revoked
revocation.deletedA revocation was removed
srl.regeneratedThe SRL was regenerated
api_key.createdAn API key was created
api_key.revokedAn API key was revoked

Creating a Webhook

Navigate to Webhooks

Click Webhooks in the sidebar

Create Webhook

Click Create Webhook

Configure

  • URL: The HTTPS endpoint to receive events
  • Events: Select which events to receive
  • Secret: A shared secret for signature verification

Create

Click Create to enable the webhook

Webhook Payload

Webhook requests are sent as HTTP POST with JSON body:

{
  "id": "evt_abc123",
  "type": "key.created",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "key_id": "tnu_key_xyz",
    "key_type": "issuer",
    "name": "Production Issuer"
  }
}

Signature Verification

All webhook requests include a signature header for verification:

X-Tenuo-Signature: sha256=abc123...

Verify the signature in your handler:

import hmac
import hashlib
 
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)
⚠️

Always verify webhook signatures before processing events. This prevents attackers from sending fake events to your endpoint.

Managing Webhooks

Test a Webhook

Send a test event to verify your endpoint:

  1. Click on the webhook
  2. Click Send Test Event
  3. Check that your endpoint received the event

View Delivery History

See recent delivery attempts:

  • Timestamp
  • Event type
  • Response status
  • Response time

Disable a Webhook

Temporarily stop sending events:

  1. Click on the webhook
  2. Toggle Enabled to off

Retry Policy

Failed webhook deliveries are retried with exponential backoff:

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours

After 5 failed attempts, the webhook is marked as failing and no further retries are attempted for that event.

Best Practices

Use HTTPS endpoints

Always use HTTPS for webhook endpoints to protect event data in transit.

Respond quickly

Return a 2xx response within 30 seconds. Process events asynchronously if needed.

Handle duplicates

Use the event id to deduplicate. Events may be delivered more than once.

Rotate secrets periodically

Update your webhook secret every 90 days for security.

Monitor delivery failures

Set up alerts for webhook delivery failures to catch integration issues.

Example Handler

from flask import Flask, request, abort
import hmac
import hashlib
 
app = Flask(__name__)
WEBHOOK_SECRET = "your-webhook-secret"
 
@app.route("/webhooks/tenuo", methods=["POST"])
def handle_webhook():
    # Verify signature
    signature = request.headers.get("X-Tenuo-Signature")
    if not verify_signature(request.data, signature, WEBHOOK_SECRET):
        abort(401)
    
    # Process event
    event = request.json
    if event["type"] == "srl.regenerated":
        # Trigger authorizer refresh
        refresh_authorizers()
    
    return "", 200