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:
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¶
- Check the webhook URL is correct and accessible
- Verify your endpoint accepts POST requests
- Check firewall rules allow outbound HTTPS from CertifyClouds
- Review CertifyClouds logs for error messages
Wrong Format¶
- Verify you selected the correct webhook type (Slack/Teams/Generic)
- Check your endpoint expects
Content-Type: application/json
Duplicate Notifications¶
- Ensure you don't have multiple rules for the same alert type
- Check for overlapping threshold values