Skip to content
Cisco AI Defense logo
CiscoAI Security

Notification webhooks — DefenseClaw

Overview

Webhooks are for human notification — chat and incident paging. They are intentionally separate from observability sinks so that a noisy SIEM ingestion does not create duplicate alerting traffic. The defenseclaw setup webhook command group adds, lists, enables, disables, tests, and removes webhook endpoints. The sidecar's notification queue fans out one event per configured webhook and applies the configured severity floor.

Supported types

TypeTransportAuthSeverity floor default
slackSlack incoming webhook URLURL secretmedium
pagerdutyPD Events API v2routing key env varhigh
webexWebex REST API (bot token)bot token env var + --room-idmedium
genericOperator-specified URL with HMAC-SHA256 signatureshared secret env varlow

Commands

SubcommandPurpose
add <type>Register a webhook, probe it, and persist to config
listPrint all webhooks with type, URL (redacted), severity floor, enabled state
show <name>Print one webhook's effective config
enable <name> / disable <name>Flip state without removing
remove <name>Delete (needs --yes)
test <name>Dispatch a synthetic event through the normal code path

Non-interactive examples

Slack

defenseclaw setup webhook add slack \
  --name soc-slack \
  --url https://hooks.slack.com/services/T.../B.../XXX \
  --min-severity medium \
  --events verdict,scan,admission \
  --non-interactive

PagerDuty

export DEFENSECLAW_PD_ROUTING_KEY=<routing-key>
defenseclaw setup webhook add pagerduty \
  --name soc-page \
  --secret-env DEFENSECLAW_PD_ROUTING_KEY \
  --min-severity high \
  --events verdict,admission \
  --non-interactive

Webex

export DEFENSECLAW_WEBEX_TOKEN=<bot-token>
defenseclaw setup webhook add webex \
  --name sec-channel \
  --secret-env DEFENSECLAW_WEBEX_TOKEN \
  --room-id Y2lzY29zcGFyazovL3VybjpURUFN... \
  --min-severity medium \
  --non-interactive

Generic HMAC

export DEFENSECLAW_WEBHOOK_SECRET=<shared-secret>
defenseclaw setup webhook add generic \
  --name internal-bus \
  --url https://bus.corp.example.com/hooks/defenseclaw \
  --secret-env DEFENSECLAW_WEBHOOK_SECRET \
  --min-severity low \
  --events verdict,scan,admission,activity \
  --non-interactive

Each outbound POST carries X-DefenseClaw-Signature: sha256=<hex> over the raw body so your receiver can verify integrity. Replay is mitigated by X-DefenseClaw-Timestamp (the receiver should reject events older than 5 minutes).

Event filtering

EventTriggered by
verdictEvery guardrail decision (observe: warn/block; action: block)
scanScanner run with findings at/above severity floor
admissionPolicy admission decisions (skill / MCP / plugin gate)
activityWatcher events (quarantine, policy reload, circuit-breaker flips)
lifecycleSidecar start/stop, sink failures, circuit-breaker transitions

Use --events to subscribe only to what the destination team cares about. Unsubscribed events are filtered before the HTTP round-trip so unused endpoints are effectively free.

Config shape

# config.yaml excerpt
webhooks:
  - name: soc-slack
    type: slack
    url: https://hooks.slack.com/services/...
    min_severity: medium
    events: [verdict, scan, admission]
    enabled: true
    # secret_env omitted for slack (URL is the secret)
  - name: soc-page
    type: pagerduty
    secret_env: DEFENSECLAW_PD_ROUTING_KEY
    min_severity: high
    events: [verdict, admission]
    enabled: true

Rewrites are atomic (tmp+rename), token values never enter config.yaml, and re-running add with an existing --name updates in place.

Test behavior

setup webhook add validates the URL and writes config. setup webhook test <name> dispatches a synthetic event matching the target API's contract:

TypeProbe
SlackPOST {url} with {"text":"DefenseClaw connectivity probe"}, expect 200 ok
PagerDutyPOST /v2/enqueue with event_action=trigger and dedup_key=defenseclaw-probe, expect 202
WebexWebex messages API with roomId/markdown, expect 200
GenericPOST {url} with {"probe":true,...} and HMAC signature; expect 2xx

Failures from test leave the saved webhook entry in place so operators can fix endpoint-side configuration and test again.

Verify it worked

defenseclaw setup webhook list
defenseclaw setup webhook test soc-slack
# trigger a real verdict
defenseclaw skill scan some-skill --path ~/.claw/skills/some-skill

Troubleshooting

SymptomCauseFix
firewall rejected url: private addressRFC1918 destinationAdd host to firewall.webhook_allowlist after review
Slack webhook returns 404Revoked or rotated URLCreate a new webhook in Slack; setup webhook add slack to replace
PagerDuty receives no eventsRouting key bound to wrong serviceUpdate DEFENSECLAW_PD_ROUTING_KEY in .env and restart sidecar
HMAC verification fails on receiverWrong secret or body reading issueCompare X-DefenseClaw-Signature with hmac_sha256(secret, raw_body)

Related