CiscoCiscoDefenseClaw
Setup

Setup webhooks

Configure Slack, PagerDuty, Webex, and generic HMAC webhooks so the gateway can ping a chat or incident channel when high-severity events fire.

defenseclaw setup webhook manages the notifier webhooks the gateway dispatches when a guardrail or asset-policy event clears your minimum-severity threshold. Four destinations are supported out of the box; every one of them is configurable interactively or via a fully-flagged non-interactive form.

Notifiers vs audit sinks — important

There are two webhook surfaces, and they are intentionally separated:

  • Notifiers (defenseclaw setup webhook) — chat/incident pings shaped to the destination's API (Slack blocks, PagerDuty Events v2, Webex messages, or generic JSON). Severity-gated, deduped, exactly the events you'd page someone for. This page.
  • Audit sinks (defenseclaw setup observability add webhook) — every event the gateway emits, posted as JSONL. No severity gate; intended for SIEMs and data lakes.

Pick the surface that matches the consumer. Most installs run one notifier (Slack) and zero or one audit sinks.

The four webhook types

Prop

Type

Three worked examples

Slack incoming webhooks carry the secret in the URL itself, so you do not need a --secret-env:

defenseclaw setup webhook add slack \
  --url https://hooks.slack.com/services/T000/B000/XXXXXX \
  --min-severity HIGH \
  --non-interactive

Test it without paging the channel by using --dry-run, then live-fire when you're happy:

defenseclaw setup webhook test slack-hooks-slack-com --dry-run
defenseclaw setup webhook test slack-hooks-slack-com

PagerDuty Events v2 needs a routing key. Store the secret in an env var, point the webhook at its name:

export DEFENSECLAW_PD_ROUTING_KEY="R0…XYZ"
defenseclaw setup webhook add pagerduty \
  --name pd-prod \
  --url https://events.pagerduty.com/v2/enqueue \
  --secret-env DEFENSECLAW_PD_ROUTING_KEY \
  --min-severity HIGH \
  --non-interactive

The dispatcher reads the live env value at call time, so rotating the routing key is a single export away.

For SIEMs / SOAR platforms that prefer a generic POST with a verifiable signature:

export DEFENSECLAW_SIEM_SECRET="some-shared-secret"
defenseclaw setup webhook add generic \
  --name siem \
  --url https://siem.example.com/defenseclaw \
  --secret-env DEFENSECLAW_SIEM_SECRET \
  --events policy_block,judge_block,asset_policy_deny \
  --min-severity MEDIUM \
  --non-interactive

The receiver validates the HMAC by recomputing HMAC-SHA256(secret, body) and comparing it to the X-DefenseClaw-Signature header.

All seven subcommands

Prop

Type

Flag reference for add

FlagDefaultNotes
--name <id>derived from type + URL hostFriendly identifier shown in list and audit.
--url <url>(required)Validated against the SSRF guard at write time and again at delivery.
--secret-env <ENV>type-specific (see below)The name of an env var, never the literal secret. The CLI rejects values that look like real secrets.
--room-id <id>(required for webex)Webex room/space identifier.
--min-severity LOW|MEDIUM|HIGH|CRITICALHIGHEvents below the floor are dropped.
--events a,b,c(all categories)Allow-list — useful when a receiver only cares about, say, policy_block.
--timeout-seconds <n>5Per-delivery timeout.
--cooldown-seconds <n>300 (runtime default)Dedup window. 0 disables dedup; omit to use the runtime default.
--enabled / --disabled--enabledInitial state.
--dry-runoffPrint the YAML diff without writing.
--non-interactiveoffRequired for CI; missing required fields exit non-zero with a error: --foo is required message.

Per-type --secret-env defaults:

TypeDefault --secret-env
slack(none — secret is in the URL)
pagerdutyDEFENSECLAW_PD_ROUTING_KEY
webexDEFENSECLAW_WEBEX_TOKEN
genericnone; you'll be asked whether to sign with HMAC, default DEFENSECLAW_WEBHOOK_SECRET

SSRF guard

Every URL is validated against the same SSRF guard the Go gateway runs at delivery time:

  • TLD, scheme (https:// only by default), and host parse cleanly.
  • Resolves to a public IP. RFC1918, link-local, and loopback are rejected unless you explicitly opt in by exporting DEFENSECLAW_WEBHOOK_ALLOW_LOCALHOST=1.
  • No userinfo (https://user:pass@…) — credentials belong in --secret-env.

The validator runs both at add time (early failure) and at delivery time (catches hand-edits to config.yaml that would otherwise reject events at runtime).

Verifying a webhook with test

test ships a synthetic event with a unique event-ID per invocation, which means receivers cannot dedup it:

defenseclaw setup webhook test pd-prod

The output includes:

  • The formatted payload bytes count and a 160-byte preview.
  • Every header DefenseClaw sent (including any HMAC signature for generic).
  • The HTTP status returned by the receiver.
  • An audit-log entry tagged setup-webhook test name=pd-prod ok=true.

For the dry-run rehearsal:

defenseclaw setup webhook test pd-prod --dry-run

— the payload is formatted (so you can copy/paste it into your receiver's playground) without making the HTTP call.

Common gotchas

Reference