Webhooks And Events¶
Webhooks deliver signed SigID events to tenant-owned systems. Use them for asynchronous synchronization, security monitoring, compliance workflows, and operational automation.
When to use webhooks¶
Use webhooks when your application needs to react to SigID changes outside the interactive login request.
| Use case | Example |
|---|---|
| User lifecycle sync | Create, suspend, reactivate, or remove a local user record |
| Organization sync | Update workspace membership after organization role changes |
| Security monitoring | Alert on suspicious activity, MFA failures, or refresh token reuse |
| Agent governance | Track agent registration, key rotation, delegation, and vault access |
| Billing operations | Update account status after payment or settlement events |
| Compliance | Archive audit-relevant events in a tenant SIEM |
Do not use webhooks as the only authorization check for an API request. APIs must still validate tokens and enforce policy at request time.
Subscription model¶
A webhook subscription belongs to one tenant and includes:
| Field | Meaning |
|---|---|
| URL | HTTPS receiver endpoint |
| Event types | List of event type filters |
| Secret | HMAC signing secret for delivery verification |
| Description | Human-readable purpose or owner |
| Active flag | Whether deliveries should be sent |
Keep subscriptions scoped to the receiver's job. A security monitoring endpoint does not need every billing event, and a billing integration does not need every login event.
Delivery headers¶
Each delivery is a POST with Content-Type: application/json.
| Header | Meaning |
|---|---|
X-SigID-Signature-Suite |
Signature suite, currently sigid-webhook-v1 |
X-SigID-Signature-256 |
HMAC-SHA256 signature, formatted as sha256=<hex> |
X-SigID-Signature-Max-Age |
Sender replay window in seconds |
X-SigID-Timestamp |
Unix timestamp at signing time |
X-SigID-Event |
Event type |
X-SigID-Delivery |
Unique delivery ID |
Signature verification¶
Receivers must verify signatures before parsing or acting on the event.
The v1 canonical string is:
Verification requirements:
- Reject missing or unsupported
X-SigID-Signature-Suite. - Rebuild the canonical string using the exact raw request body.
- Compute HMAC-SHA256 with the webhook secret.
- Compare with
X-SigID-Signature-256in constant time. - Reject stale timestamps using the smaller of the sender max-age and your local policy ceiling.
- Deduplicate
X-SigID-Deliverywithin the replay window.
Use the raw body
Verify the signature against the exact bytes received. Re-serializing JSON can change whitespace, key order, or escaping and invalidate the signature.
Receiver behavior¶
Your receiver should:
- accept only
POST - require
application/json - verify the signature before processing
- store the delivery ID before side effects
- process the event idempotently
- return
2xxonly after durable acceptance - return
4xxfor permanent receiver-side validation errors - return
5xxfor transient failures that should be retried
SigID respects Retry-After when possible and retries failed deliveries
according to the platform delivery policy.
Idempotency¶
Webhook delivery is at-least-once. Your receiver may see the same event or delivery more than once.
Recommended deduplication table:
| Column | Purpose |
|---|---|
delivery_id |
Primary deduplication key from X-SigID-Delivery |
event_type |
Useful for debugging and routing |
received_at |
Replay-window and support visibility |
status |
Accepted, processed, failed, ignored |
event_id |
Event-level correlation when present in payload |
Deduplicate before performing side effects such as sending email, granting access, creating tickets, or updating billing state.
Event categories¶
SigID event types are dotted strings. Subscribe to specific event types when possible. Use broader patterns only when the receiver is intentionally a security or audit sink.
| Category | Examples |
|---|---|
| Authentication | auth.login.success, auth.login.failure, auth.logout, auth.token.issued, auth.token.revoked |
| MFA and risk | auth.mfa.challenge, auth.mfa.verify, auth.adaptive_mfa.triggered |
| Tenant users | tenant_user.invited, tenant_user.activated, tenant_user.suspended, tenant_user.removed |
| Administration | admin.user.created, admin.agent.registered, admin.delegation.revoked |
| Vault | vault.credential.created, vault.grant.revoked, vault.credential.accessed |
| Wallet | wallet.tx.signed, wallet.tx.rejected, wallet.budget.exceeded |
| Chain | chain.ownership.changed, chain.reputation.updated, chain.metadata.updated |
| SSO | sso.configured, sso.login.success, sso.login.failed, sso.user.provisioned |
| Organizations | org.created, org.member.added, org.member.role_changed, org.ownership_transferred |
| Commerce | commerce.payment.succeeded, commerce.payment.failed, commerce.settlement.released |
| Security | security.brute_force.detected, security.refresh_token.reuse, security.suspicious_activity |
Test delivery¶
After creating a subscription:
- Send a test delivery from the dashboard or API.
- Confirm your receiver logs the delivery ID and event type.
- Confirm invalid signatures are rejected.
- Confirm duplicate delivery IDs do not duplicate side effects.
- Confirm your alerting fires if the endpoint returns repeated non-
2xxresponses.
API surface¶
| Route | Purpose |
|---|---|
GET /api/v1/webhooks |
List subscriptions |
POST /api/v1/webhooks |
Create a subscription |
GET /api/v1/webhooks/{id} |
Read a subscription |
PUT /api/v1/webhooks/{id} |
Update URL, event types, description, or active flag |
DELETE /api/v1/webhooks/{id} |
Delete a subscription |
POST /api/v1/webhooks/{id}/test |
Send a test delivery |
GET /api/v1/webhooks/{id}/deliveries |
Inspect delivery history |
Use idempotency keys for subscription creation and test delivery if your client can retry after network failures.
Production checklist¶
- Receiver URL uses HTTPS.
- Receiver is dedicated to SigID events.
- Secret is stored in a secret manager.
- Signature verification uses the raw request body.
- Delivery IDs are deduplicated.
- Receiver returns
2xxonly after safe acceptance. - Retries and failures are monitored.
- Event subscriptions are limited to the receiver's purpose.
- Logs do not contain secrets, access tokens, refresh tokens, or full payloads when they include sensitive data.