Penaxtra POSTs domain events to URLs you configure in /app/integrations. Each delivery is HMAC-SHA256 signed and retried with exponential backoff.
Configuring
Owner / admin only. In the console, open /app/integrations, fill in the "Add webhook" form:
- Name - identifier shown on the deliveries table.
- URL - must be
https://. URLs that resolve to private,
loopback, link-local, or multicast addresses are rejected at create time and re-checked at fire time.
- Events - subscribe to one or more of:
- scan.completed - finding.created - finding.severity_changed - finding.status_changed - report.generated
On save we generate a 256-bit signing secret and show it to you exactly once. The DB only holds the sealed-box-encrypted copy.
Signature scheme
Every POST carries three headers:
X-Penaxtra-Signature: t=1731504000,v1=ab12cd34...
X-Penaxtra-Event: finding.created
X-Penaxtra-Delivery: 7b9e6e0e-1234-...
Verify in your receiver:
signed_payload = f"{t}.{raw_body}".encode("utf-8")
expected_hex = hmac.new(secret, signed_payload, "sha256").hexdigest()
hmac.compare_digest(expected_hex, v1_value)
Reject the request if:
tis more than 300 seconds old (replay defence)- the HMAC comparison fails
- you have already processed this
X-Penaxtra-Deliveryvalue
(deduplication)
Retry behaviour
Non-2xx responses or network errors trigger a retry chain with backoff of 1s, 2s, 4s, 8s, 16s. After five failed attempts the delivery is marked dead. Ten consecutive dead deliveries auto-deactivates the parent webhook.
Testing
The "Test" button on /app/integrations enqueues a ping event regardless of your subscription list, so you can verify signature handling end-to-end before flipping to a real event.
Last reviewed: 2026-05-14. Reviewed by: Engineering. Content type: Developer documentation. Reach the maintainers: [email protected] .