dnswatchdog.iodocs
Settings

SIEM integration (OCSF / CEF)

Stream findings and DNS changes to Splunk, Microsoft Sentinel, Google SecOps, QRadar, ArcSight or any collector as Open Cybersecurity Schema Framework (OCSF) events or Common Event Format (CEF) lines, batched and retried.

Open Notification Settings

DNS Watchdog can feed your SIEM directly. A SIEM (OCSF / CEF) notification channel emits every finding and every DNS change as an Open Cybersecurity Schema Framework event — the vendor-neutral schema that Splunk, Microsoft Sentinel, Google SecOps (Chronicle), Amazon Security Lake and most modern pipelines ingest natively — or, for collectors that expect it, as an ArcSight Common Event Format (CEF) line. Either way, findings land in the tools your security operation already runs, without a custom parser.

Compared with a custom webhook, a SIEM channel:

  • sends every change, not a top-20 summary;
  • uses industry schema (OCSF Detection Finding, Entity Management and Scan Activity classes) rather than a product-specific payload;
  • is batched (up to 100 events per request) and retried durably — a collector outage delays delivery, it does not lose a finding;
  • supports the wire formats collectors expect: a JSON array, NDJSON, Splunk HTTP Event Collector envelopes, or CEF lines;
  • carries an optional credential header, stored encrypted.

Setting up a channel

  1. In your SIEM, create an HTTPS ingestion endpoint and (usually) a token — see Per-SIEM notes.
  2. In DNS Watchdog, go to Settings → Notifications, click Add notification and choose SIEM (OCSF / CEF).
  3. Fill in the form:
FieldWhat to enter
LabelA name for the channel, e.g. Splunk (SOC)
Collector URLThe HTTPS endpoint your SIEM ingests on. Stored encrypted and never shown again
FormatJSON array (default), NDJSON, Splunk HEC or CEF — see Wire formats
Events to sendFindings, DNS changes and scan summaries (default) or Findings only
Auth header nameThe header the credential is sent in. Defaults to Authorization; some collectors want their own, e.g. X-goog-api-key
CredentialOptional. The token to send in that header, stored encrypted. Leave empty if the collector authenticates by URL or network
  1. Click Add SIEM Integration, then click Test. The test posts a single, clearly labelled OCSF event (class_uid 6007, activity_name Connectivity Test, metadata.labels: ["test"]; as a CEF line it carries the signature siem.test and cs6=test) through the same URL, format and credential a real batch uses, so a green test means real batches will arrive.

Creating, updating and deleting channels requires the Admin or Member role. Deleting the channel removes the URL and credential from encrypted storage.

Wire formats

FormatRequest bodyContent-TypeUse with
JSON array[ {event}, {event}, … ]application/jsonMicrosoft Sentinel Logs Ingestion, Google SecOps webhook feeds, Cribl Stream, Vector, Fluent Bit, Amazon Security Lake custom sources, your own collector
NDJSONOne event per lineapplication/x-ndjsonCollectors that read newline-delimited JSON
Splunk HECConcatenated HEC envelopes: {"time": …, "source": "dnswatchdog", "event": {event}}application/jsonSplunk HTTP Event Collector (/services/collector/event)
CEFOne Common Event Format line per event, newline-terminatedtext/plain; charset=utf-8Splunk HEC raw endpoint (/services/collector/raw), IBM QRadar HTTP Receiver, ArcSight, Microsoft Sentinel behind a CEF forwarder, Cribl Stream, Logstash

Every request also carries User-Agent: DNS-Watchdog-SIEM/1.0.

For Splunk HEC the credential is your HEC token; DNS Watchdog adds the Splunk scheme to the Authorization header if you paste the bare token. No sourcetype is set in the envelope, so the token's default sourcetype applies — set it on the token to route and parse events as you prefer.

CEF

Choose CEF for a collector that ingests ArcSight Common Event Format rather than JSON. Every event becomes one line, newline-terminated:

CEF:0|dnswatchdog.io|DNS Watchdog|20260901.1|issue_detected|Port 3389 Open (RDP) detected on rdp.example.com|8|rt=1777342530000 externalId=c2f1… cat=Detection Finding act=Create outcome=New dhost=rdp.example.com dst=203.0.113.5 dpt=3389 cs1Label=tenantId cs1=org_abc123 cs2Label=zone cs2=example.com cs3Label=issueType cs3=port_open_rdp cs4Label=scanId cs4=… cs5Label=changelogUrl cs5=https://app.dnswatchdog.io/audit/changes?scan_id\=… cs6Label=labels cs6=scan_type:daily_scan cn1Label=ocsfClassUid cn1=2004 cn2Label=ocsfTypeUid cn2=200401 flexString1Label=scanType flexString1=daily_scan

The header is CEF:0|Device Vendor|Device Product|Device Version|Signature ID|Name|Severity|:

Header fieldValue
Device Vendor / Product / Versiondnswatchdog.io, DNS Watchdog, the DNS Watchdog release
Signature IDThe DNS Watchdog change type: issue_detected, issue_resolved, issue_ignored, issue_note_added, record_detected, record_changed, record_deleted, record_removed_externally, zone_detected, zone_removed, provider_removed or scan.completed; the test event carries siem.test
NameThe event's one-line summary (the OCSF message)
SeverityThe OCSF severity on CEF's 0–10 scale: Unknown 0, Informational 1, Low 3, Medium 5, High 8, Critical 10

The extension uses standard CEF dictionary keys, so ArcSight, QRadar and Sentinel's CEF parser map them without a custom parser:

Extension keyValue
rtWhen the change was detected, epoch milliseconds
externalIdThe stable event id (OCSF metadata.uid) — de-duplicate on this
cat / actThe OCSF class (Detection Finding, Entity Management, Scan Activity) and activity (Create, Update, Close, Delete, Completed)
outcomeFinding status: New, In Progress, Suppressed or Resolved
msgThe ignore reason, note preview or external-removal note, when there is one
dhost / dst / dptThe affected hostname, IP address and port
suser / suidWho made a DNS change, where DNS Watchdog knows
start / end / cntScan start, end and total changes, on the Scan Activity event
cs1 tenantId, cs2 zone, cs3 issueType or entityType, cs4 scanId, cs5 changelogUrl, cs6 labelsLabelled custom strings
cn1 ocsfClassUid, cn2 ocsfTypeUidThe OCSF class and type ids
flexString1 scanTypedaily_scan, manual_resync, zone_scan, record_rescan or initial_scan

CEF is a flat, single-line format, so each line is a summary of the event: record snapshots, field-level diffs and the typed observable list are only carried by the JSON formats. Header fields escape \ and |; extension values escape \, = and line breaks, per the CEF specification. Names are clipped at 512 characters and extension values at 1,023.

The Splunk scheme is added to the credential automatically only for the Splunk HEC format. To send CEF to Splunk's raw endpoint, enter Splunk <token> as the credential.

Delivery and retries

Delivery is asynchronous and at-least-once:

  1. When a scan finishes with changes, DNS Watchdog maps the changes to OCSF events, splits them into batches of at most 100 events (about 200 KB), and queues one job per batch.
  2. A delivery worker posts each batch. A transient collector fault — an HTTP 429, 5xx, 408, a timeout or a dropped connection — is retried in-process three times with exponential back-off, honouring Retry-After.
  3. If those attempts are exhausted the batch returns to the queue and is retried roughly every nine minutes, five times in all, before being dead-lettered for operator recovery. A collector outage of well under an hour therefore loses nothing.
  4. A permanent fault — 401/403 (bad credential), 400/404/413 (wrong URL or format) — is not retried: no later attempt could succeed.

Because a batch can be redelivered, every event carries a stable metadata.uid (the DNS Watchdog changelog event id). De-duplicate on it if your pipeline is not already idempotent.

Channel status

The channel's status follows the same rules as every other channel — three consecutive failures mark it Error and pause delivery until a successful Test resets it — but for a SIEM channel a "failure" is a batch that was definitively rejected or gave up after all of its retries, not a single failed request. A collector blip never flags the channel.

The events

All events conform to OCSF 1.4.0 and share the standard envelope (the CEF format renders these same events as lines):

FieldValue
category_uid / category_nameThe OCSF category of the class below
class_uid / class_name2004 Detection Finding, 3004 Entity Management, or 6007 Scan Activity
activity_id / activity_nameWhat happened — see each class
type_uid / type_nameclass_uid * 100 + activity_id and its name
severity_id / severityOCSF severity (0 Unknown … 5 Critical)
timeWhen the change was detected, epoch milliseconds
messageA one-line human summary
metadata.version1.4.0
metadata.product{"name": "DNS Watchdog", "vendor_name": "dnswatchdog.io", "version": …}
metadata.uidStable per-event id (the changelog event id) — de-duplicate on this
metadata.event_codeThe DNS Watchdog change type, e.g. issue_detected, record_changed
metadata.tenant_uidYour organisation id
metadata.log_namednswatchdog.scan
metadata.labels["scan_type:daily_scan"] etc.; the test event carries ["test"]
observablesHostnames, IP addresses and ports extracted from the event, typed per OCSF
unmappedDNS Watchdog fields OCSF has no home for: scan_id, scan_type, zone_name, record_name, provider_id, changelog_url and the full issue/record snapshot

Detection Finding (2004) — issues

One event per issue event. Severity is the issue's DNS Watchdog severity.

DNS Watchdog changeactivity_idstatus_id
Issue detected1 Create1 New
Issue updated (re-graded severity or review-status change)2 Updatefrom the issue's review status
Issue ignored2 Update3 Suppressed (the reason is in comment)
Note added to an issue2 Updatefrom the issue's review status (the note preview is in comment)
Issue resolved3 Close4 Resolved

finding_info carries the issue's uid, title, desc, types (the DNS Watchdog issue type, e.g. port_open_rdp), the analytic that raised it, and src_url pointing at your changelog. resources[0] names the affected DNS record (or zone) with its record type, value, IP address and port where relevant.

{
  "category_uid": 2, "category_name": "Findings",
  "class_uid": 2004, "class_name": "Detection Finding",
  "activity_id": 1, "activity_name": "Create",
  "type_uid": 200401, "type_name": "Detection Finding: Create",
  "severity_id": 4, "severity": "High",
  "status_id": 1, "status": "New",
  "time": 1777342530000,
  "message": "Port 3389 Open (RDP) detected on rdp.example.com",
  "metadata": {
    "version": "1.4.0",
    "product": { "name": "DNS Watchdog", "vendor_name": "dnswatchdog.io", "version": "20260901.1" },
    "uid": "c2f1…", "event_code": "issue_detected", "tenant_uid": "org_abc123",
    "log_name": "dnswatchdog.scan", "logged_time": 1777342531000,
    "labels": ["scan_type:daily_scan"]
  },
  "finding_info": {
    "uid": "issue-…", "title": "Port 3389 Open (RDP)",
    "desc": "Remote Desktop Protocol port 3389 is publicly accessible. …",
    "types": ["port_open_rdp"],
    "analytic": { "type_id": 1, "type": "Rule", "name": "port_open_rdp", "uid": "port_open_rdp" },
    "created_time": 1777342200000, "modified_time": 1777342530000,
    "src_url": "https://app.dnswatchdog.io/audit/changes?scan_id=…"
  },
  "resources": [
    { "type": "DNS Record", "name": "rdp.example.com", "uid": "rec-…",
      "data": { "record_type": "A", "record_value": "203.0.113.5", "zone_name": "example.com", "ip_address": "203.0.113.5", "port": 3389 } }
  ],
  "observables": [
    { "name": "resources[0].name", "type_id": 1, "type": "Hostname", "value": "rdp.example.com" },
    { "name": "unmapped.issue_data.ip_address", "type_id": 2, "type": "IP Address", "value": "203.0.113.5" },
    { "name": "unmapped.issue_data.port", "type_id": 11, "type": "Port", "value": "3389" }
  ],
  "unmapped": { "scan_id": "…", "scan_type": "daily_scan", "issue_type": "port_open_rdp", "issue_severity": "high", "zone_name": "example.com", "record_name": "rdp.example.com", "changelog_url": "…" }
}

Entity Management (3004) — DNS zone, record and provider changes

One event per change to a managed DNS entity. entity describes it (type is DNS Record, DNS Zone or DNS Provider) and carries its state; an update also carries the new state in entity_result, and unmapped.field_changes lists the exact fields that changed. Scanner metadata is excluded from these snapshots, as it is from every notification. Where DNS Watchdog knows who made the change, actor.user names them.

DNS Watchdog changeactivity_idseverity_id
Record discovered, zone discovered1 Create1 Informational
Record changed3 Update1 Informational
Record deleted, record removed externally, zone removed, provider removed4 Delete2 Low

A record removed at the provider outside DNS Watchdog carries comment: "Record removed at the provider, outside DNS Watchdog".

Scan Activity (6007) — one per scan

A single activity_id: 2 (Completed) event closes every scan's batch, with scan.uid, scan.type_id (2 Scheduled for the daily scan, 1 Manual otherwise), start_time, end_time, duration, num_detections, and per-change-type counts under unmapped.counts_by_change_type. It doubles as a heartbeat: a detection rule that expects it daily will tell you if DNS Watchdog has gone quiet. It is only sent when Events to send is Findings, DNS changes and scan summaries.

Per-SIEM notes

Splunk

  1. In Splunk, enable the HTTP Event Collector and create a token (Settings → Data inputs → HTTP Event Collector → New Token). Set its default index and, optionally, a sourcetype.
  2. Collector URL: https://<splunk-host>:8088/services/collector/event (Splunk Cloud: https://http-inputs-<stack>.splunkcloud.com/services/collector/event).
  3. Format: Splunk HEC. Credential: the HEC token.

For CEF instead, use the raw endpoint — https://<splunk-host>:8088/services/collector/raw — with format CEF, enter Splunk <token> as the credential, and give the token a CEF sourcetype (the Splunk Add-on for CEF, or cef) so the extension keys are extracted.

Search with class_uid=2004 for findings, or metadata.event_code="issue_detected". The Splunk OCSF add-ons map these classes to CIM data models.

Microsoft Sentinel

Sentinel's Logs Ingestion API accepts a JSON array but authenticates with Entra ID tokens, which a static header cannot supply. Point the channel at a Logic App or Azure Function HTTP trigger that forwards to your Data Collection Rule, or ingest through Cribl Stream or Azure Event Hubs. Format: JSON array. If the trigger uses a shared-access URL, leave the credential empty; if it expects a key header, set the header name and credential.

If your workspace is fed by the Common Event Format (CEF) via AMA connector instead, choose format CEF and point the channel at a forwarder that accepts HTTPS and relays to the log forwarder's syslog port (Cribl Stream, Logstash, Fluent Bit) — that connector reads syslog, not HTTP. The lines arrive parsed into CommonSecurityLog with the extension keys mapped.

Google SecOps (Chronicle)

Create a Webhook feed (SIEM Settings → Feeds → Add new → Webhook, log type OCSF or a custom log type). Collector URL: the feed's endpoint URL. Format: JSON array (Chronicle splits JSON arrays into records). Auth header name: X-goog-api-key with the feed's API key as the credential; if the feed also requires a secret, put it in the URL as Chronicle instructs.

IBM QRadar and ArcSight

Both ingest CEF natively. In QRadar, add a log source with the HTTP Receiver protocol (HTTPS, POST, one event per line); use its listen URL as the collector URL, format CEF, and, if you enabled an authentication token on the receiver, set the header name and credential it expects. For ArcSight, point the channel at a SmartConnector or Logger receiver that accepts CEF over HTTPS, or at a forwarder that relays to your CEF syslog receiver.

Other collectors

Cribl Stream, Vector, Fluent Bit, Logstash, Elastic, Datadog and Sumo Logic all offer HTTP sources that accept a JSON array or NDJSON body with a token header, and most can parse CEF lines too. Choose the matching format, set the header name the source expects (Authorization: Bearer … is the default), and de-duplicate on metadata.uid (externalId in CEF).

Sending to more than one SIEM

You can add several SIEM channels, each with its own URL, format and scope — a findings-only feed for the SOC and a full feed into a data lake, say. Each is delivered, retried and tested independently.

On this page