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

ChannelSent immediatelyWeekly digest
Email, Slack, Microsoft Teams, webhooksCritical changesYes, skipped when nothing changed
PagerDutyCritical and high changesNever
JiraCritical and high changes, one issue request per changeNo

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:

  1. In the Teams channel, open Workflows and choose the template Post to a channel when a webhook request is received.
  2. Finish the wizard and copy the HTTP POST URL it gives you (on *.logic.azure.com, *.powerplatform.com or *.webhook.office.com).
  3. 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

  1. In PagerDuty, open the service that should own external exposure, then Integrations, Add integration, Events API V2.
  2. Copy the 32-character Integration Key (the routing key).
  3. 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.

  1. 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.
  2. Add the action Create issue. Set Summary to {{webhookData.summary}} and Description to {{webhookData.description}}.
  3. Under Additional fields, map priority and labels:
    {
      "fields": {
        "priority": { "name": "{{webhookData.priority}}" },
        "labels": {{webhookData.labels.asJsonStringArray}}
      }
    }
  4. Add a Jira channel in Attack Surface Scan with the URL and the secret (sent in the X-Automation-Webhook-Token header).

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

  1. PagerDuty on the service that owns internet exposure, with high changes at low urgency.
  2. Jira for critical and high changes, deduplicated, landing in the team's normal backlog.
  3. Teams or Slack for the security channel: critical changes as they happen and the weekly digest for context.
  4. OCSF webhook or API pull into the SIEM, for correlation and retention.
  5. 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