Webhooks
Sirr can send HTTP POST requests to your endpoints whenever secret events occur. Use webhooks to trigger workflows, update dashboards, or feed audit systems in real time.
Overview
Register a webhook URL and subscribe to one or more event types. When an event occurs, Sirr sends a JSON payload to your URL with an HMAC signature for verification. Failed deliveries are retried with exponential backoff.
Webhooks are fire-and-forget from Sirr's perspective — they do not block the original API request. A slow or failing webhook endpoint will not impact secret operations.
Create a webhook
Register a new webhook endpoint.
Required attributes
- Name
url- Type
- string
- Description
The HTTPS endpoint that will receive webhook payloads.
- Name
events- Type
- string[]
- Description
Array of event types to subscribe to. Use
["*"]for all events.
Optional attributes
- Name
description- Type
- string
- Description
Human-readable label for this webhook.
Request
curl -X POST http://localhost:39999/webhooks \
-H "Authorization: Bearer $SIRR_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/sirr",
"events": ["secret.created", "secret.read", "secret.burned"],
"description": "Slack notifier"
}'
Response (201)
{
"id": "wh_a1b2c3d4",
"url": "https://example.com/hooks/sirr",
"events": ["secret.created", "secret.read", "secret.burned"],
"description": "Slack notifier",
"created_at": 1700000000
}
List webhooks
List all registered webhook endpoints.
Request
curl http://localhost:39999/webhooks \
-H "Authorization: Bearer $SIRR_MASTER_KEY"
Response
{
"webhooks": [
{
"id": "wh_a1b2c3d4",
"url": "https://example.com/hooks/sirr",
"events": ["secret.created", "secret.read", "secret.burned"],
"description": "Slack notifier",
"created_at": 1700000000
}
]
}
Delete a webhook
Remove a webhook endpoint. No further events will be delivered to this URL.
Path parameters
- Name
id- Type
- string
- Description
The webhook ID returned when it was created.
Request
curl -X DELETE http://localhost:39999/webhooks/wh_a1b2c3d4 \
-H "Authorization: Bearer $SIRR_MASTER_KEY"
Response
{
"deleted": true
}
Event payloads
When an event occurs, Sirr sends a POST request to each subscribed webhook URL with a JSON body.
Example payload
{
"id": "evt_x1y2z3",
"type": "secret.read",
"timestamp": 1700003600,
"data": {
"key": "db/password",
"read_count": 1,
"max_reads": 3,
"expires_at": 1700007200
}
}
Event types
| Event | Triggered when |
|---|---|
secret.created | A new secret is pushed |
secret.read | A secret is retrieved |
secret.deleted | A secret is explicitly deleted |
secret.burned | A secret reaches its read limit and is destroyed |
secret.expired | A secret's TTL elapses and it is destroyed |
HMAC verification
Every webhook request includes an X-Sirr-Signature header containing an HMAC-SHA256 signature of the request body. Verify this signature to ensure the payload was sent by your Sirr instance and has not been tampered with.
The HMAC secret is set via the SIRR_WEBHOOK_SECRET environment variable.
Verification steps
- Read the raw request body (do not parse JSON first)
- Compute
HMAC-SHA256(body, SIRR_WEBHOOK_SECRET) - Compare the hex-encoded result with the
X-Sirr-Signatureheader - Use constant-time comparison to prevent timing attacks
Node.js verification
import { createHmac, timingSafeEqual } from 'crypto'
function verifyWebhook(body, signature, secret) {
const expected = createHmac('sha256', secret)
.update(body)
.digest('hex')
return timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
)
}
Python verification
import hmac
import hashlib
def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(signature, expected)
If SIRR_WEBHOOK_SECRET is not set, webhooks are delivered without signatures. Always set this variable in production to prevent spoofed webhook payloads.