feat: add outbound webhook event framework
This commit is contained in:
+1
-1
@@ -236,7 +236,7 @@ Goal: let DMARQ integrate cleanly into existing security and operations workflow
|
||||
|
||||
Planned:
|
||||
- A stable, documented read-only API surface for posture and reporting queries. Delivered with scoped `reports:read`, `posture:read`, and `tls-reports:read` API tokens, public read-only endpoints, and per-token usage audit fields.
|
||||
- Webhook event delivery for key events (new sender source, compliance drop, missing reports, alert lifecycle).
|
||||
- Webhook event delivery for key events (new sender source, compliance drop, missing reports, alert lifecycle). Delivered with encrypted webhook endpoints, signed delivery headers, idempotency keys, retry/backoff state, test sends, and delivery inspection.
|
||||
- Integration templates for SIEM and ticketing workflows (export formats, payload schemas, examples).
|
||||
- Token/scoping model for API access that matches governance needs (service accounts, least privilege).
|
||||
|
||||
|
||||
+34
-12
@@ -510,17 +510,39 @@ The API uses versioning in the URL path (/api/v1/) to ensure backward compatibil
|
||||
|
||||
## Webhooks
|
||||
|
||||
DMARQ can notify your systems about events via webhooks:
|
||||
DMARQ can notify downstream systems about operational events from
|
||||
**Settings > Webhooks** or the admin API.
|
||||
|
||||
1. Navigate to **Settings** > **API Access** > **Webhooks**
|
||||
2. Click **Add Webhook**
|
||||
3. Configure:
|
||||
- Destination URL
|
||||
- Secret token (for verification)
|
||||
- Events to subscribe to
|
||||
| Endpoint | Purpose |
|
||||
| --- | --- |
|
||||
| `GET /api/v1/webhooks` | List endpoints and supported event types |
|
||||
| `POST /api/v1/webhooks` | Create an endpoint |
|
||||
| `PUT /api/v1/webhooks/{id}` | Update an endpoint |
|
||||
| `DELETE /api/v1/webhooks/{id}` | Disable an endpoint while keeping delivery history |
|
||||
| `POST /api/v1/webhooks/{id}/test` | Queue and attempt a test delivery |
|
||||
| `GET /api/v1/webhooks/deliveries` | Inspect recent delivery attempts |
|
||||
| `POST /api/v1/webhooks/deliveries/process` | Attempt due retries |
|
||||
|
||||
Supported events:
|
||||
- `report.processed` - When a new report is processed
|
||||
- `compliance.threshold` - When compliance falls below threshold
|
||||
- `domain.added` - When a domain is added
|
||||
- `domain.removed` - When a domain is removed
|
||||
Supported event types:
|
||||
- `dmarq.report.imported`
|
||||
- `dmarq.sender.new`
|
||||
- `dmarq.compliance.drop`
|
||||
- `dmarq.reports.missing`
|
||||
- `dmarq.alert.created`
|
||||
- `dmarq.alert.resolved`
|
||||
- `dmarq.webhook.test`
|
||||
|
||||
Deliveries are signed with HMAC-SHA256 using the endpoint signing secret.
|
||||
Receivers should verify these headers:
|
||||
|
||||
| Header | Description |
|
||||
| --- | --- |
|
||||
| `X-DMARQ-Event` | Event type |
|
||||
| `X-DMARQ-Delivery` | Delivery id |
|
||||
| `X-DMARQ-Idempotency-Key` | Stable deduplication key |
|
||||
| `X-DMARQ-Timestamp` | Unix timestamp used in the signature |
|
||||
| `X-DMARQ-Signature` | `v1=<hex hmac>` over `timestamp.delivery_id.body` |
|
||||
|
||||
Non-2xx responses are retried with exponential backoff until the endpoint's
|
||||
maximum attempt count is reached. Operators can inspect the delivery status,
|
||||
last response code, error text, and response excerpt without reading logs.
|
||||
|
||||
@@ -135,6 +135,46 @@ and are never stored.
|
||||
| last_used_ip | VARCHAR(64) | Source IP from the last successful API use |
|
||||
| usage_count | INTEGER | Successful API use count |
|
||||
|
||||
### Webhook_Endpoints
|
||||
|
||||
The `webhook_endpoints` table stores outbound webhook destinations. Target
|
||||
URLs and signing secrets are encrypted at rest.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| id | INTEGER | Primary key |
|
||||
| name | VARCHAR(120) | Operator-facing endpoint name |
|
||||
| url | TEXT | Encrypted destination URL |
|
||||
| secret | TEXT | Encrypted signing secret |
|
||||
| event_types | TEXT | Comma-separated event subscriptions, or `*` |
|
||||
| enabled | BOOLEAN | Whether deliveries can be sent |
|
||||
| max_attempts | INTEGER | Maximum attempts before a delivery fails |
|
||||
| timeout_seconds | INTEGER | Per-request timeout |
|
||||
| last_success_at | TIMESTAMP | Last successful delivery |
|
||||
| last_failure_at | TIMESTAMP | Last failed delivery attempt |
|
||||
| failure_count | INTEGER | Consecutive endpoint-level failures |
|
||||
|
||||
### Webhook_Deliveries
|
||||
|
||||
The `webhook_deliveries` table records delivery attempts and retry state.
|
||||
|
||||
| Column | Type | Description |
|
||||
|--------|------|-------------|
|
||||
| id | INTEGER | Primary key |
|
||||
| endpoint_id | INTEGER | Foreign key to webhook_endpoints.id |
|
||||
| event_type | VARCHAR(80) | Delivered event type |
|
||||
| payload | TEXT | Event envelope JSON |
|
||||
| idempotency_key | VARCHAR(160) | Stable deduplication key per endpoint |
|
||||
| status | VARCHAR(24) | pending, delivered, failed, or abandoned |
|
||||
| attempt_count | INTEGER | Attempts already made |
|
||||
| max_attempts | INTEGER | Maximum attempts for this delivery |
|
||||
| next_attempt_at | TIMESTAMP | Next retry time |
|
||||
| last_attempt_at | TIMESTAMP | Last attempt time |
|
||||
| delivered_at | TIMESTAMP | Successful delivery time |
|
||||
| last_status_code | INTEGER | Last HTTP status code |
|
||||
| last_error | TEXT | Last sanitized error |
|
||||
| response_excerpt | TEXT | Truncated downstream response |
|
||||
|
||||
## DNS and Configuration Tables
|
||||
|
||||
### DNS_Records
|
||||
@@ -243,6 +283,9 @@ The schema includes several indexes to optimize query performance:
|
||||
- `ix_api_tokens_key_hash`: On api_tokens.key_hash
|
||||
- `ix_api_tokens_key_prefix`: On api_tokens.key_prefix
|
||||
- `ix_api_tokens_active_scope`: On api_tokens.active and api_tokens.scopes
|
||||
- `ix_webhook_endpoints_enabled_events`: On webhook_endpoints.enabled and webhook_endpoints.event_types
|
||||
- `ix_webhook_delivery_endpoint_idempotency`: Unique on webhook_deliveries.endpoint_id and idempotency_key
|
||||
- `ix_webhook_delivery_due`: On webhook_deliveries.status and webhook_deliveries.next_attempt_at
|
||||
- `idx_activity_logs_timestamp`: On activity_logs.timestamp
|
||||
- `idx_activity_logs_user_id`: On activity_logs.user_id
|
||||
- `idx_system_logs_timestamp`: On system_logs.timestamp
|
||||
|
||||
@@ -86,6 +86,21 @@ Apprise supports email, Slack, Teams, Discord, generic webhooks, and many other
|
||||
targets through the same notification field. Add each destination on a separate
|
||||
line.
|
||||
|
||||
## Webhooks
|
||||
|
||||
Use **Settings** > **Webhooks** when another system needs structured DMARQ
|
||||
events instead of human-readable notifications.
|
||||
|
||||
1. Add a name and HTTPS endpoint URL.
|
||||
2. Choose all events or one event type.
|
||||
3. Save the endpoint.
|
||||
4. Use **Test** to send a signed test event.
|
||||
5. Inspect **Recent Deliveries** to see status, attempts, response codes, and errors.
|
||||
|
||||
DMARQ signs each delivery with `X-DMARQ-Signature` and includes
|
||||
`X-DMARQ-Idempotency-Key` so receivers can reject replays and deduplicate
|
||||
retries. Endpoint URLs and signing secrets are encrypted at rest.
|
||||
|
||||
## API Access
|
||||
|
||||
DMARQ provides an API for integration with other systems:
|
||||
|
||||
Reference in New Issue
Block a user