Skip to content

Commit 4430797

Browse files
authored
Merge pull request #101 from l3montree-dev/how-to-guides/integration/webhook-events
Created How-To-Guid for Webhook integration
2 parents 1d73b00 + 60e1b5a commit 4430797

1 file changed

Lines changed: 194 additions & 2 deletions

File tree

Lines changed: 194 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,200 @@
11
import Image from 'next/image';
22
import { Callout } from 'nextra/components';
33
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
4-
import PageContentComingSoon from '@/components/PageContentComingSoon'
54

65
# Webhook Events
76

8-
<PageContentComingSoon />
7+
DevGuard can send HTTP POST requests to a URL of your choice whenever specific security events occur. Use webhooks to integrate DevGuard with external systems such as notification services, SIEMs, ticketing tools, or custom automation pipelines.
8+
9+
## Supported Event Types
10+
11+
| Type | Description | Triggered when |
12+
| --- | --- | --- |
13+
| `sbom` | Software Bill of Materials | A new SBOM is generated for an asset version |
14+
| `dependencyVulnerabilities` | Dependency vulnerabilities | New dependency vulnerabilities are detected (SCA) |
15+
| `firstPartyVulnerabilities` | First-party vulnerabilities | New first-party vulnerabilities are detected (SAST) |
16+
| `test` | Test event | A test webhook is sent manually from the UI or API |
17+
18+
## Webhook Scope
19+
20+
Webhooks can be registered at two levels:
21+
22+
- **Organization level** — receives events for **all projects** within the organization.
23+
- **Project level** — receives events only for assets within that specific project.
24+
25+
When an event fires, DevGuard delivers it to all matching webhooks: project-scoped webhooks for that project **and** organization-scoped webhooks.
26+
27+
## Creating a Webhook
28+
29+
### Via the API
30+
31+
```bash
32+
POST /api/v1/organizations/{org}/integrations/webhook/test-and-save/
33+
```
34+
35+
For a project-scoped webhook:
36+
37+
```bash
38+
POST /api/v1/organizations/{org}/projects/{project}/integrations/webhook/test-and-save/
39+
```
40+
41+
**Request Body:**
42+
43+
```json
44+
{
45+
"name": "My SIEM Integration",
46+
"description": "Forward vulnerability events to our SIEM",
47+
"url": "https://example.com/devguard-webhook",
48+
"secret": "my-shared-secret",
49+
"sbomEnabled": true,
50+
"vulnEnabled": true
51+
}
52+
```
53+
54+
| Field | Type | Required | Description |
55+
| --- | --- | --- | --- |
56+
| `name` | string | no | Display name for the webhook |
57+
| `description` | string | no | Description of the webhook's purpose |
58+
| `url` | string | **yes** | The endpoint URL that will receive the POST requests |
59+
| `secret` | string | no | Shared secret sent as the `X-Webhook-Secret` header for verification |
60+
| `sbomEnabled` | boolean | no | Enable delivery of SBOM events |
61+
| `vulnEnabled` | boolean | no | Enable delivery of vulnerability events (dependency & first-party) |
62+
63+
**Example Response:**
64+
65+
```json
66+
{
67+
"id": "a1b2c3d4-...",
68+
"name": "My SIEM Integration",
69+
"description": "Forward vulnerability events to our SIEM",
70+
"url": "https://example.com/devguard-webhook",
71+
"sbomEnabled": true,
72+
"vulnEnabled": true
73+
}
74+
```
75+
76+
<Callout type="info">
77+
DevGuard sends a test request to your URL during creation. If your endpoint does not return a `2xx` status, the webhook will not be saved.
78+
</Callout>
79+
80+
### Updating a Webhook
81+
82+
```bash
83+
PUT /api/v1/organizations/{org}/integrations/webhook/{id}/
84+
```
85+
86+
The request body is the same as creation, but must also include the `id` field.
87+
88+
### Deleting a Webhook
89+
90+
```bash
91+
DELETE /api/v1/organizations/{org}/integrations/webhook/{id}/
92+
```
93+
94+
## Payload Format
95+
96+
Every webhook delivery is an HTTP `POST` with `Content-Type: application/json`. The payload follows this structure:
97+
98+
```json
99+
{
100+
"type": "sbom | dependencyVulnerabilities | firstPartyVulnerabilities | test",
101+
"organization": {
102+
"id": "uuid",
103+
"name": "My Org",
104+
"slug": "my-org"
105+
},
106+
"project": {
107+
"id": "uuid",
108+
"name": "My Project",
109+
"slug": "my-project"
110+
},
111+
"asset": {
112+
"id": "uuid",
113+
"name": "My Asset",
114+
"slug": "my-asset",
115+
"description": "..."
116+
},
117+
"assetVersion": {
118+
"name": "main",
119+
"slug": "main",
120+
"defaultBranch": true,
121+
"type": "branch"
122+
},
123+
"artifact": {
124+
"artifactName": "my-image:latest"
125+
},
126+
"payload": "..."
127+
}
128+
```
129+
130+
The `payload` field contains the event-specific data and varies by event type:
131+
132+
- **`sbom`** — A full [CycloneDX](https://cyclonedx.org/) BOM object.
133+
- **`dependencyVulnerabilities`** — An array of dependency vulnerability objects including CVE details, component purl, CVSS score, risk assessment, and fix version.
134+
- **`firstPartyVulnerabilities`** — An array of first-party vulnerability objects including rule ID, file URI, code snippet, scanner ID, and severity.
135+
- **`test`** — A simple object with a `message` and `timestamp`.
136+
137+
## Verifying Webhook Deliveries
138+
139+
If you configured a `secret` when creating the webhook, DevGuard includes it in every request to your endpoint as:
140+
141+
```
142+
X-Webhook-Secret: <your-secret>
143+
```
144+
145+
Your endpoint should validate this header to ensure the request originates from DevGuard.
146+
147+
The following example shows how this could look like in your backend server.
148+
149+
**Example usage of webhook secret (Node.js / Express):**
150+
151+
```js
152+
app.post("/devguard-webhook", (req, res) => {
153+
const secret = req.headers["x-webhook-secret"];
154+
if (secret !== process.env.DEVGUARD_WEBHOOK_SECRET) {
155+
return res.status(401).send("Unauthorized");
156+
}
157+
158+
const event = req.body;
159+
console.log(`Received ${event.type} event for ${event.asset.name}`);
160+
161+
// Process the event...
162+
res.status(200).send("OK");
163+
});
164+
```
165+
166+
## Retry Behavior
167+
168+
If your endpoint does not return a `2xx` status code, DevGuard retries the delivery up to **3 times** with increasing delays: **1 second**, **5 seconds**, and **10 seconds**.
169+
170+
Requests time out after **120 seconds**.
171+
172+
## Testing a Webhook
173+
174+
You can send a test payload to any URL without saving it:
175+
176+
```bash
177+
POST /api/v1/organizations/{org}/integrations/webhook/test/
178+
```
179+
180+
181+
**Request Body:**
182+
183+
```json
184+
{
185+
"url": "https://example.com/devguard-webhook",
186+
"secret": "my-shared-secret",
187+
"payloadType": "sampleDependencyVulns"
188+
}
189+
```
190+
191+
DevGuard will take the URL you provided and send a test-payload to it to verify the webhook integration.
192+
193+
Supported `payloadType` values:
194+
195+
| Value | Description |
196+
| --- | --- |
197+
| `empty` | Simple test message with a timestamp |
198+
| `sampleSbom` | A sample CycloneDX SBOM |
199+
| `sampleDependencyVulns` | A sample dependency vulnerability (CVE-2021-44228) |
200+
| `sampleFirstPartyVulns` | A sample first-party vulnerability (SQL injection) |

0 commit comments

Comments
 (0)