Decide what deserves a page before wiring anything
An external attack surface monitor produces two kinds of output: findings (the state of things: a missing header, an old TLS version) and changes (something moved since the last scan). Findings belong in a backlog. Changes are what alerting is for, and only some of them are urgent.
A useful test for paging: would I want to know about this at 2 a.m. if it turned out to be an attack? Changes that pass it:
- A sensitive port starts answering: a database, remote desktop or an orchestration API is reachable from the internet on a host where it was closed yesterday.
- A certificate issued by a CA you have not authorized appears in certificate transparency: the signature of mis-issuance or staged phishing infrastructure.
- A new vulnerability match on the CISA KEV catalog: software you expose is on the list of what attackers are actively exploiting.
- A registrar transfer lock is removed: planned maintenance, or the first step of a domain hijack.
Attack Surface Scan marks all four critical. High-importance changes (another registrar lock removed, for instance) usually need an owner within days rather than a person out of bed. Everything else, from a new subdomain to a score change, is context: it belongs in a digest someone reads on Monday.
How delivery is split by channel
| Channel | Sent immediately | Weekly digest |
|---|---|---|
| Email, Slack, Microsoft Teams, webhooks | Critical changes | Yes, skipped when nothing changed |
| PagerDuty | Critical and high changes | Never |
| Jira | Critical and high changes, one issue request per change | No |
Every channel type is available on every paid plan, each confirmed channel has a Send test button that delivers a sample change, and a failing channel is flagged in the app without blocking the others. The setup below follows the Integrations docs.
Microsoft Teams: use a Workflows webhook
If your Teams alerts used an Office 365 connector "incoming webhook", they have stopped. Microsoft's final retirement schedule disabled Office 365 connectors in Teams between May 18 and May 22, 2026, and connector-based webhooks had to move to Workflows (Power Automate). New setups should start there:
- In the Teams channel, open Workflows and choose the template Post to a channel when a webhook request is received.
- Finish the wizard and copy the HTTP POST URL it gives you (on
*.logic.azure.com,*.powerplatform.comor*.webhook.office.com). - Add a Microsoft Teams channel in Attack Surface Scan, paste the URL, and press Send test.
Messages arrive as Adaptive Cards (version 1.4) listing up to 20 changes, with a button that opens the app.
PagerDuty: Events API v2 and deduplication
- In PagerDuty, open the service that should own external exposure, then Integrations, Add integration, Events API V2.
- Copy the 32-character Integration Key (the routing key).
- Add a PagerDuty channel in Attack Surface Scan and paste it.
Critical changes trigger with PagerDuty severity critical and high changes with
error, two of the four values the
Events API v2 accepts. The part that matters for on-call sanity is the
dedup_key: it is afs- plus 32 hex characters derived from the target, the
change kind and its new value. The same port reopening on the same host updates the open incident
instead of paging again, while a different port is a new incident.
Two practical choices. First, use PagerDuty's event orchestration or urgency settings if you want high changes to create low-urgency incidents that wait for business hours, so only critical changes wake someone. Second, resolve incidents in PagerDuty once the next scan confirms the fix; resolve events are not sent automatically, because "the port closed" is something a human should confirm was intentional.
Jira: an Automation rule, not stored credentials
Instead of storing a Jira API token, Attack Surface Scan sends each critical or high change to a Jira Automation incoming webhook, and the rule creates the issue on your side with your project, issue type and fields.
- In Jira, Project settings, Automation, Create rule. Choose the trigger Incoming webhook with No issues from the webhook. Copy the webhook URL, and the secret if one is shown.
- Add the action Create issue. Set Summary to
{{webhookData.summary}}and Description to{{webhookData.description}}. - Under Additional fields, map priority and labels:
{ "fields": { "priority": { "name": "{{webhookData.priority}}" }, "labels": {{webhookData.labels.asJsonStringArray}} } } - Add a Jira channel in Attack Surface Scan with the URL and the secret (sent in the
X-Automation-Webhook-Tokenheader).
To avoid duplicate tickets for a change that repeats while the first ticket is still open, add a Lookup issues action before Create issue with
labels = attack-surface-scan AND text ~ "{{webhookData.dedupKey}}" AND statusCategory != Done
and a condition that {{lookupIssues.size}} equals 0. The payload also carries the
target host, the change kind and a link back to the app, so the ticket is actionable without
opening another tool. Atlassian changes the Automation UI from time to time; their
trigger documentation is the reference if a step looks different.
Once the ticket exists, the fix is often a small config change in a repository; handing findings to a coding agent covers that last step.
SIEM: OCSF webhooks or API pulls
For a SIEM or data lake, push is usually simplest. Set a generic webhook's format to
OCSF (SIEM) and each delivery arrives as a JSON array of
OCSF 1.3.0 Detection Finding events (class 2004), which Amazon Security Lake,
Splunk, Microsoft Sentinel and other SIEMs ingest without a custom parser. Severity maps to
severity_id (critical 5, high 4, medium 3, low 2), the change kind is in
metadata.event_code, the affected host is in resources, and
finding_info.uid is the same dedup key PagerDuty and Jira receive, so you can correlate
across tools.
Webhook endpoints must be HTTPS on a public hostname; literal IP addresses, localhost and internal names are rejected, and redirects are not followed. If your collector is private, pull instead. The read-only REST API (Growth and above) exposes the same change feed:
curl -s -H "Authorization: Bearer $AFS_API_KEY" \
"$AFS_API_BASE/changes?days=7&importance=critical"
A scheduled pull of /v1/changes and /v1/findings into a warehouse also
gives you history for dashboards and audit questions without anyone exporting CSVs by hand.
A routing plan that holds up
- PagerDuty on the service that owns internet exposure, with high changes at low urgency.
- Jira for critical and high changes, deduplicated, landing in the team's normal backlog.
- Teams or Slack for the security channel: critical changes as they happen and the weekly digest for context.
- OCSF webhook or API pull into the SIEM, for correlation and retention.
- Email for the person accountable, so the digest reaches someone who does not live in chat.
MSPs can scope any channel to one client workspace, so each client's alerts land in that client's tools (see attack surface management for MSPs). Then press Send test on every channel and confirm a human saw each one. An alert path nobody has tested is not a control.
Frequently asked questions
Do Microsoft Teams incoming webhooks still work?
Office 365 connector webhooks in Teams were retired, with the final rollout completing between May 18 and May 22, 2026. Use a Workflows webhook instead: the "Post to a channel when a webhook request is received" template gives you a URL that accepts Adaptive Cards.
Which attack surface changes should page someone?
Changes that look like the start of an attack: a sensitive port opening, a certificate from an unauthorized CA, a new vulnerability match on CISA KEV, or a registrar transfer lock being removed. Most other changes are better as tickets or a weekly digest.
How do I stop PagerDuty paging repeatedly for the same issue?
Send a stable dedup_key. Attack Surface Scan derives it from the target, the change kind and the new value, so a repeat of the same change updates the open incident instead of triggering a new one.
How do I get attack surface alerts into a SIEM?
Either set a webhook's format to OCSF, which delivers Detection Finding (class 2004) events most SIEMs ingest without a custom parser, or pull the change feed on a schedule from the REST API. Pulling suits collectors that are not reachable from the internet.
Sources
- Microsoft 365 Developer Blog: Retirement of Office 365 connectors within Microsoft Teams
- Microsoft Learn: Create incoming webhooks and Workflows in Teams
- PagerDuty: Events API v2 overview
- PagerDuty: Send an alert event (deduplication)
- Atlassian: Jira Automation triggers (incoming webhook)
- OCSF 1.3.0: Detection Finding class
- Slack: Sending messages using incoming webhooks