Skip to content

Webhook Reference

CertifyClouds sends webhook notifications for alert events. This document describes the payload formats for each webhook type.


Overview

CertifyClouds supports three webhook formats:

Type Use Case Compatible With
slack Slack Incoming Webhooks Slack, Discord (with /slack URL)
teams Microsoft Teams Connectors Microsoft Teams
generic Custom integrations Any HTTP endpoint

Alert Types

Discovery Alerts

Alert Type Trigger Fields Included
scan_completed After a scan finishes Total vaults, secrets count, duration
secret_expiring Secrets expiring within threshold Secret names, expiry dates, vault names
secret_expired Secrets already expired Secret names, expired dates, vault names
vault_error Key Vault access errors Vault names, error messages

Rotation Alerts (PRO)

Alert Type Trigger Fields Included
rotation_success Successful credential rotation App name, secret name, new expiry
rotation_failed Failed rotation attempt App name, secret name, error message
discovery_completed App Registration discovery done Apps found, matches count

Sync Alerts (PRO)

Alert Type Trigger Fields Included
sync_success Successful sync to AWS/GCP Secret name, target ARN
sync_failed Failed sync attempt Secret name, error message
sync_conflict Version conflict detected Secret name, conflict details

Slack Format

Compatible with Slack Incoming Webhooks and Discord (use /slack suffix on webhook URL).

{
  "attachments": [
    {
      "color": "#EF4444",
      "title": "Secret Expiring Alert",
      "text": "Found 3 secrets expiring within 30 days",
      "footer": "CertifyClouds",
      "ts": 1702569600,
      "fields": [
        {
          "title": "Vault",
          "value": "kv-production",
          "short": true
        },
        {
          "title": "Secrets",
          "value": "api-key, db-password, cert-primary",
          "short": true
        }
      ]
    }
  ]
}

Fields

Field Type Description
color string Hex color code for sidebar
title string Alert title
text string Alert message body
footer string Always "CertifyClouds"
ts integer Unix timestamp
fields array Optional key-value pairs

Color Codes

Color Hex Usage
Red #EF4444 Errors, failures, expired
Orange #F97316 Warnings, expiring soon
Green #22C55E Success, completed
Blue #3B82F6 Informational

Microsoft Teams Format

Compatible with Microsoft Teams Incoming Webhooks (Connectors).

{
  "@type": "MessageCard",
  "@context": "https://schema.org/extensions",
  "summary": "Secret Expiring Alert",
  "themeColor": "EF4444",
  "title": "Secret Expiring Alert",
  "text": "Found 3 secrets expiring within 30 days",
  "sections": [
    {
      "facts": [
        {
          "name": "Vault",
          "value": "kv-production"
        },
        {
          "name": "Secrets",
          "value": "api-key, db-password, cert-primary"
        }
      ]
    }
  ]
}

Fields

Field Type Description
@type string Always "MessageCard"
@context string Schema URL
summary string Card summary (same as title)
themeColor string Hex color without #
title string Card title
text string Card body text
sections array Optional sections with facts

Generic Format

JSON payload for custom integrations, scripts, or third-party tools.

{
  "title": "Secret Expiring Alert",
  "message": "Found 3 secrets expiring within 30 days",
  "color": "#EF4444",
  "timestamp": "2024-12-14T12:00:00.000000",
  "source": "CertifyClouds",
  "fields": [
    {
      "title": "Vault",
      "value": "kv-production"
    },
    {
      "title": "Secrets",
      "value": "api-key, db-password, cert-primary"
    }
  ]
}

Fields

Field Type Description
title string Alert title
message string Alert message body
color string Hex color code
timestamp string ISO 8601 timestamp
source string Always "CertifyClouds"
fields array Optional key-value pairs

Delivery & Retry Logic

Retry Configuration

CertifyClouds implements exponential backoff for failed webhook deliveries:

Attempt Delay Before Retry
1 Immediate
2 2 seconds
3 5 seconds
4 10 seconds (final)

Response Handling

Status Code Action
200, 204 Success - no retry
4xx Client error - no retry
5xx Server error - retry with backoff
Timeout Retry with backoff

Timeout

Each webhook request has a 10 second timeout. If your endpoint is slow, consider using a message queue.


Example Payloads

Scan Completed (Slack)

{
  "attachments": [
    {
      "color": "#22C55E",
      "title": "Scan Completed",
      "text": "Discovery scan completed successfully",
      "footer": "CertifyClouds",
      "ts": 1702569600,
      "fields": [
        {"title": "Vaults Scanned", "value": "12", "short": true},
        {"title": "Total Secrets", "value": "847", "short": true},
        {"title": "Duration", "value": "2m 34s", "short": true}
      ]
    }
  ]
}

Secret Expiring (Generic)

{
  "title": "Secrets Expiring Soon",
  "message": "Found 5 secrets expiring within 30 days",
  "color": "#F97316",
  "timestamp": "2024-12-14T12:00:00.000000",
  "source": "CertifyClouds",
  "fields": [
    {"title": "kv-production", "value": "api-key (expires 2024-12-20), db-conn (expires 2024-12-25)"},
    {"title": "kv-staging", "value": "service-account (expires 2025-01-02)"}
  ]
}

Rotation Failed (Teams)

{
  "@type": "MessageCard",
  "@context": "https://schema.org/extensions",
  "summary": "Rotation Failed",
  "themeColor": "EF4444",
  "title": "Rotation Failed",
  "text": "Failed to rotate secret for MyApp/client-secret",
  "sections": [
    {
      "facts": [
        {"name": "Application", "value": "MyApp"},
        {"name": "Secret", "value": "client-secret"},
        {"name": "Error", "value": "Insufficient permissions"}
      ]
    }
  ]
}

Integration Examples

Discord

Discord supports Slack webhooks with a URL suffix:

https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_TOKEN/slack

Set webhook type to slack in CertifyClouds.

PagerDuty

Use the generic webhook format with PagerDuty Events API v2. You'll need middleware to transform the payload.

Custom Script

from flask import Flask, request

app = Flask(__name__)

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

    title = data['title']
    message = data['message']
    fields = data.get('fields', [])

    # Your custom logic here
    print(f"Alert: {title}")
    print(f"Message: {message}")

    for field in fields:
        print(f"  {field['title']}: {field['value']}")

    return '', 200

Troubleshooting

Webhook Not Received

  1. Check the webhook URL is correct and accessible
  2. Verify your endpoint accepts POST requests
  3. Check firewall rules allow outbound HTTPS from CertifyClouds
  4. Review CertifyClouds logs for error messages

Wrong Format

  1. Verify you selected the correct webhook type (Slack/Teams/Generic)
  2. Check your endpoint expects Content-Type: application/json

Duplicate Notifications

  1. Ensure you don't have multiple rules for the same alert type
  2. Check for overlapping threshold values