Agent skill
Signal Sciences Webhooks Skill
Receive and verify Signal Sciences (Fastly Next-Gen WAF) generic webhooks. Use when setting up Signal Sciences or Fastly Next-Gen WAF webhook alert handlers, debugging X-SigSci-Signature verification, or handling events like flag, agentAlert, loggingModeChanged, and ruleCreated.
Install this skill
npx skills add hookdeck/webhook-skills --skill signal-sciences-webhooks
Signal Sciences is now the Fastly Next-Gen WAF. Its generic webhook integration (alert) posts JSON notifications for selected workspace (site) activity, such as a flagged IP address or an agent alert.
When to Use This Skill
- How do I receive Signal Sciences or Fastly Next-Gen WAF webhooks?
- How do I verify the
X-SigSci-Signatureheader? - Why is my Signal Sciences webhook signature verification failing?
- How do I handle
flagoragentAlertevents? - Where do I find or rotate the signing key for a generic webhook?
Verification (core)
Fastly sends X-SigSci-Signature: the hex HMAC-SHA256 digest of the raw JSON body, keyed with the signing key generated for the integration (used as a plain string). There is no timestamp and no prefix. Compare timing-safe.
Node:
const crypto = require('crypto');
function verify(rawBody, signatureHeader, signingKey) {
if (!signatureHeader) return false;
const expected = crypto.createHmac('sha256', signingKey).update(rawBody).digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(signatureHeader.trim().toLowerCase()), Buffer.from(expected));
} catch {
return false;
}
}
Python:
import hmac, hashlib
def verify(raw_body: bytes, signature_header: str, signing_key: str) -> bool:
if not signature_header:
return False
expected = hmac.new(signing_key.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature_header.strip().lower(), expected)
For complete handlers with route wiring, event dispatch, and tests, see:
Fastly publishes no SDK for verification, so all examples use the manual HMAC check above.
Payload Shape
The event name is the type field in the JSON body (there is no event-type header):
{
"created": "2024-02-09T21:08:21.31644377Z",
"type": "flag",
"payload": { "ID": "...", "SiteID": "...", "Slug": "site.example" },
"link": "dashboard link to event",
"workspaceId": "www.mysite.com"
}
Common Event Types
type | Description |
|---|---|
flag | An IP address was flagged |
expireFlag | An IP address flag was manually expired |
agentAlert | An agent alert was triggered |
loggingModeChanged | Agent mode (Blocking, Not Blocking, Off) changed |
ruleCreated / ruleUpdated / ruleDeleted | A request rule changed |
listCreated / listUpdated / listDeleted | A list changed |
customAlertCreated / customAlertUpdated / customAlertDeleted | A custom alert changed |
See references/overview.md for the full list of activity types.
Important Headers
| Header | Description |
|---|---|
X-SigSci-Signature | Hex HMAC-SHA256 of the raw body |
Content-Type | application/json |
Environment Variables
SIGNAL_SCIENCES_SIGNING_KEY=your_signing_key # Reveal/Rotate on the integration in the console
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 signal-sciences --path /webhooks/signal-sciences
Reference Materials
- references/overview.md - Webhook concepts and activity types
- references/setup.md - Configuration guide
- references/verification.md - Signature verification details