Skip to main content

Guides for DevSecOps Engineers

These guides cover automation workflows: CI/CD integration, API usage, webhook notifications, and API spec imports for maximum scan coverage.


Guide 1: Integrating ThreatWeaver into CI/CD Pipelines​

Shift security left by triggering vulnerability scans automatically when code changes.

Time needed30 minutes
PrerequisitesThreatWeaver API token; access to your CI/CD configuration
What you'll learnHow to trigger scans from GitHub Actions and GitLab CI, and fail builds on critical findings

How it works​

GitHub Actions setup​

Create a workflow file in your repository:

# .github/workflows/security-scan.yml
name: Security Scan

on:
pull_request:
branches: [main, develop]

jobs:
dast-scan:
runs-on: ubuntu-latest
steps:
- name: Trigger ThreatWeaver Scan
id: scan
env:
TW_API_TOKEN: ${{ secrets.TW_API_TOKEN }}
TW_TARGET_ID: ${{ secrets.TW_TARGET_ID }}
run: |
RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $TW_API_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"targetId\": \"$TW_TARGET_ID\"}" \
https://api.threatweaver.ai/api/appsec/assessments/trigger)

ASSESSMENT_ID=$(echo $RESPONSE | jq -r '.assessmentId')
echo "assessment_id=$ASSESSMENT_ID" >> $GITHUB_OUTPUT

- name: Poll for Completion
env:
TW_API_TOKEN: ${{ secrets.TW_API_TOKEN }}
run: |
ASSESSMENT_ID="${{ steps.scan.outputs.assessment_id }}"
for i in $(seq 1 60); do
STATUS=$(curl -s \
-H "Authorization: Bearer $TW_API_TOKEN" \
"https://api.threatweaver.ai/api/appsec/assessments/$ASSESSMENT_ID" \
| jq -r '.status')

if [ "$STATUS" = "completed" ]; then
echo "Scan completed!"
break
fi
echo "Scan in progress (attempt $i/60)..."
sleep 30
done

- name: Check for Critical Findings
env:
TW_API_TOKEN: ${{ secrets.TW_API_TOKEN }}
run: |
ASSESSMENT_ID="${{ steps.scan.outputs.assessment_id }}"
CRITICAL_COUNT=$(curl -s \
-H "Authorization: Bearer $TW_API_TOKEN" \
"https://api.threatweaver.ai/api/appsec/assessments/$ASSESSMENT_ID/findings?severity=critical" \
| jq '.totalCount')

if [ "$CRITICAL_COUNT" -gt 0 ]; then
echo "FAIL: Found $CRITICAL_COUNT critical vulnerabilities!"
exit 1
fi
echo "PASS: No critical vulnerabilities found."
Store secrets securely

Add TW_API_TOKEN and TW_TARGET_ID as encrypted secrets in your repository settings. Never hardcode credentials in workflow files.

GitLab CI setup​

# .gitlab-ci.yml
security-scan:
stage: test
script:
- |
RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $TW_API_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"targetId\": \"$TW_TARGET_ID\"}" \
https://api.threatweaver.ai/api/appsec/assessments/trigger)

ASSESSMENT_ID=$(echo $RESPONSE | jq -r '.assessmentId')
echo "Assessment started: $ASSESSMENT_ID"

# Poll and check results (same logic as GitHub Actions)
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

Failing builds on critical findings​

You can configure your pipeline to:

PolicyAction
Critical findingsFail the build immediately -- block the merge.
High findingsWarn but allow merge (with reviewer approval).
Medium and belowLog for tracking, do not block.
Start permissive, tighten over time

When first integrating, set the policy to warn-only. Once your team has addressed the initial backlog, switch to blocking on Critical and High findings.


Guide 2: Using the ThreatWeaver API​

Automate any ThreatWeaver workflow programmatically using the REST API.

Time needed20 minutes to get started
PrerequisitesThreatWeaver account with API access
What you'll learnHow to authenticate, make API calls, and automate common workflows

Getting your API token​

  1. Log in to ThreatWeaver.
  2. Navigate to Settings > Security.
  3. Under API Tokens, click Generate Token.
  4. Copy the token immediately -- it will not be shown again.
Token scope

API tokens inherit the permissions of the user who created them. Create a dedicated service account with the minimum required role for automated workflows.

Making your first API call​

List all assets:

curl -s \
-H "Authorization: Bearer YOUR_API_TOKEN" \
https://api.threatweaver.ai/api/assets \
| jq '.data[:3]'

Common workflows​

Create a target and start a scan​

# Step 1: Create a target
TARGET=$(curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Staging API", "url": "https://staging.api.myapp.com"}' \
https://api.threatweaver.ai/api/appsec/targets)

TARGET_ID=$(echo $TARGET | jq -r '.id')

# Step 2: Start a scan
ASSESSMENT=$(curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"targetId\": \"$TARGET_ID\", \"scanType\": \"gray_box\"}" \
https://api.threatweaver.ai/api/appsec/assessments/trigger)

ASSESSMENT_ID=$(echo $ASSESSMENT | jq -r '.assessmentId')
echo "Scan started: $ASSESSMENT_ID"

# Step 3: Poll for results
while true; do
STATUS=$(curl -s \
-H "Authorization: Bearer $TOKEN" \
"https://api.threatweaver.ai/api/appsec/assessments/$ASSESSMENT_ID" \
| jq -r '.status')

[ "$STATUS" = "completed" ] && break
sleep 30
done

# Step 4: Get findings
curl -s \
-H "Authorization: Bearer $TOKEN" \
"https://api.threatweaver.ai/api/appsec/assessments/$ASSESSMENT_ID/findings" \
| jq '.data[] | {type: .vulnerabilityType, severity: .severity, endpoint: .endpoint}'

Get all critical findings for a target​

curl -s \
-H "Authorization: Bearer $TOKEN" \
"https://api.threatweaver.ai/api/appsec/findings?targetId=$TARGET_ID&severity=critical" \
| jq '.data'

Export findings as SARIF​

SARIF (Static Analysis Results Interchange Format) is supported by GitHub, VS Code, and other developer tools.

curl -s \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/sarif+json" \
"https://api.threatweaver.ai/api/appsec/assessments/$ASSESSMENT_ID/export?format=sarif" \
-o results.sarif

Rate limits​

Endpoint CategoryLimit
Read operations (GET)100 requests/minute
Write operations (POST/PUT/DELETE)30 requests/minute
Scan triggers10 requests/minute
Best practices
  • Cache responses where possible to reduce API calls.
  • Use webhook notifications instead of polling for scan completion.
  • Implement exponential backoff when you hit rate limits.

Guide 3: Setting Up Webhooks and Notifications​

Get notified automatically when scans complete, new findings are discovered, or findings are resolved.

Time needed15 minutes
PrerequisitesAdmin role; a webhook endpoint (e.g., Slack incoming webhook URL)
What you'll learnHow to configure webhooks and integrate with Slack and PagerDuty

Available webhook events​

EventWhen it fires
scan_completedA scan finishes (success or failure).
finding_createdA new vulnerability is discovered.
finding_resolvedA previously open vulnerability is confirmed fixed.
finding_reopenedA previously fixed vulnerability has reappeared.
exception_expiringAn exception is about to expire (7 days before).

Configuring a webhook​

  1. Navigate to Admin > Integrations.
  2. Click "+ Add Webhook".
  3. Enter the webhook URL -- the HTTPS endpoint that will receive events.
  4. Select events -- choose which events trigger the webhook.
  5. Save and test. Click Send Test to verify your endpoint receives the payload.

Webhook payload format​

{
"event": "finding_created",
"timestamp": "2026-04-04T10:30:00Z",
"data": {
"findingId": "f-abc123",
"vulnerabilityType": "sql_injection",
"severity": "critical",
"endpoint": "POST /api/users/search",
"assessmentId": "a-def456",
"targetName": "Staging API"
}
}

Integrating with Slack​

  1. In Slack, create an Incoming Webhook for your security channel (Slack workspace settings > Apps > Incoming Webhooks).
  2. Copy the webhook URL (starts with https://hooks.slack.com/services/...).
  3. In ThreatWeaver, add this URL as a webhook and select the events you care about.
  4. Slack will receive formatted messages for each event.

Integrating with PagerDuty​

For critical findings that need immediate attention:

  1. In PagerDuty, create an Events API v2 integration on your security service.
  2. Copy the integration key.
  3. In ThreatWeaver, add a PagerDuty integration under Admin > Integrations.
  4. Configure it to trigger only on finding_created events with critical severity.
  5. Your on-call engineer will be paged immediately when a critical vulnerability is found.
Webhook security

ThreatWeaver signs webhook payloads with an HMAC signature in the X-TW-Signature header. Verify this signature on your endpoint to ensure the webhook came from ThreatWeaver and was not tampered with.


Guide 4: Importing API Specs for Better Scanning​

Providing an API specification tells the scanner exactly which endpoints exist, what parameters they accept, and what data types are expected. This dramatically improves scan coverage.

Time needed10 minutes
PrerequisitesAn API specification file (OpenAPI, Swagger, Postman, or GraphQL schema)
What you'll learnHow to upload API specs and troubleshoot missing endpoint coverage

Why API specs improve scanning​

Without a spec, the scanner discovers endpoints by crawling and guessing. With a spec, it knows every endpoint from the start.

Supported formats​

FormatFile ExtensionNotes
OpenAPI 3.0+.json, .yamlPreferred. Full parameter and schema support.
Swagger 2.0.json, .yamlAutomatically converted to OpenAPI 3.0.
Postman Collection.jsonv2.1 collections supported.
GraphQL Schema.graphql, .gqlIntrospection query results also accepted.

Steps: Upload via UI​

  1. Navigate to AppSec > Targets.
  2. Select your target and click Edit.
  3. In the API Specification section, click Upload Spec.
  4. Select your file and click Upload. ThreatWeaver will parse the spec and show a summary (number of endpoints, parameters, and schemas detected).
  5. Save the target. The next scan will use the spec for full endpoint coverage.

Steps: Upload via API​

curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-F "spec=@openapi.yaml" \
"https://api.threatweaver.ai/api/appsec/targets/$TARGET_ID/spec"

Troubleshooting: "My scan missed endpoints"​

SymptomCauseFix
Endpoints in spec not scannedSpec not attached to targetRe-upload the spec and verify it is listed on the target page.
Some endpoints return 404Base URL mismatchCheck that the target URL matches the servers section in your OpenAPI spec.
POST endpoints not testedMissing request body schemasAdd requestBody definitions to your spec so the scanner knows what payloads to send.
GraphQL mutations missedIntrospection disabledProvide the schema file directly instead of relying on introspection.
Keep your spec up to date

Re-upload your API spec whenever you add new endpoints. Outdated specs mean the scanner misses new attack surface.


Next steps​