Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions asm/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,106 @@ paths:
'401':
$ref: '#/components/responses/Unauthorized'

# ── Webhooks ──────────────────────────────────────────────────────────────────
#
# HailBytes POSTs to your configured endpoint whenever a scan changes status.
# Configure webhook URLs in the dashboard under Settings → Webhooks.
webhooks:
scanStatusChanged:
post:
summary: Scan status change
description: |
Delivered whenever a scan transitions to `completed`, `failed`, or
`cancelled`. Configure delivery endpoints in the HailBytes dashboard
under **Settings → Webhooks**.

## Signature Verification

Every request includes an `X-HailBytes-Signature-256` header — an
HMAC-SHA256 signature of the raw request body keyed with your webhook
secret. Always verify the signature before processing the payload:

```python
import hmac, hashlib

def is_valid(secret: str, body: bytes, header: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, header)
```

Return any **2xx** status to acknowledge receipt. HailBytes retries
up to **5 times** with exponential back-off on non-2xx responses or
network timeouts. Returning **410 Gone** permanently removes the
endpoint from future deliveries.
tags: [Scans]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [event, timestamp, data]
properties:
event:
type: string
enum: [scan.completed, scan.failed, scan.cancelled]
description: Event type that triggered this delivery
example: scan.completed
timestamp:
type: string
format: date-time
description: ISO 8601 timestamp of when the event was emitted
example: '2025-06-20T14:23:00Z'
data:
$ref: '#/components/schemas/ScanDetail'
examples:
completed:
summary: Scan completed successfully
value:
event: scan.completed
timestamp: '2025-06-20T14:23:00Z'
data:
id: scn_a1b2c3d4e5f60001
label: 'Q2 perimeter sweep'
status: completed
scan_type: full
targets: ['acmecorp.com', '203.0.113.0/24']
created_at: '2025-06-20T14:00:00Z'
started_at: '2025-06-20T14:01:12Z'
completed_at: '2025-06-20T14:23:00Z'
summary:
assets_discovered: 42
assets_updated: 7
vulnerabilities_found: 3
vulnerabilities_by_severity:
critical: 1
high: 2
medium: 0
low: 0
informational: 0
failed:
summary: Scan failed
value:
event: scan.failed
timestamp: '2025-06-20T14:10:00Z'
data:
id: scn_a1b2c3d4e5f60002
label: null
status: failed
scan_type: discovery_only
targets: ['203.0.113.0/24']
created_at: '2025-06-20T14:05:00Z'
started_at: '2025-06-20T14:06:00Z'
completed_at: null
error_message: 'Network unreachable for target range'
responses:
'200':
description: Delivery acknowledged. Any 2xx is accepted.
'410':
description: Endpoint removed — HailBytes will stop delivering to this URL.

components:
securitySchemes:
bearerAuth:
Expand Down
Loading