DNS feed schemas

Catalog

Logical feedCustomer topicRecords
dns.logs.opscnx.customer.<customer_id>.dns.logs.opsApproval, validation, deployment, ownership, and alias events
dns.logs.platformcnx.customer.<customer_id>.dns.logs.platformSelected Knot signing and zone-distribution events
dns.queries.detailcnx.customer.<customer_id>.dns.queries.detailSampled classified DNS responses
dns.queries.summarycnx.customer.<customer_id>.dns.queries.summaryUnsampled classified response counts

Subscriptions select feeds individually. The exact granted topics are in connection.yml. See Delivery and compatibility for retention, transport losses, replay, and schema evolution.

Common fields

FieldTypeMeaning
timestampstringUTC RFC 3339 time with nine fractional digits: source journal time for logs, dnstap response time for detail, or counting-window start for summaries
serverstringHost producing the source event
customer_idstringCanonical customer identifier
zonestringAbsolute zone name with a trailing dot; may be absent from repository-level operations

The JSON timestamp is the event time. Nine fractional digits express resolution; clock accuracy and cross-host alignment are described in Time provenance.

For SIEM field mapping and correlation, see Ingesting DNS telemetry.

Delivery and compatibility

FeedBehavior
dns.logs.opsConfirmed-delivery cursor with deterministic event_id; replay may duplicate records. Deduplicate by event_id.
dns.logs.platformBest-effort delivery of selected platform events; transport backpressure can drop records.
dns.queries.detailBest-effort delivery with producer sampling and a default customer delivery sample of up to 100 records per second across the fleet. Full producer-selected fleet delivery is available on request, up to 10,000 records per second.
dns.queries.summaryUnsampled classified counts in 60-second windows; best-effort transport can still lose summary records.

DNS serving continues independently of Kafka and customer consumption. CNX's central logging platform is the durable authority for DNS operations and platform logs. Absence from the SIEM feed does not prove that a source event did not occur. An unsampled summary describes the events counted by its producer, not a guarantee that every summary reaches the SIEM.

DNS records have no inline schema-version field. The topic identifies the feed, and action identifies the log event type where present. Optional fields may be added within the contract. Renaming or removing a documented field, changing its type, or changing an action's meaning requires a versioned contract and a customer migration plan.

Operations log: dns.logs.ops

Every record contains the common fields except that zone is conditional, plus:

FieldTypeMeaning
event_idstringDeterministic 32-character hexadecimal replay-deduplication identifier
actorstringdns-ops or dns-aliases
actor_typestringsystem
actionstringEvent type from the catalog below
log_levelstringSource severity, normally info, warning, or error
messagestringSource event text for analyst display

Conditional correlation fields:

FieldTypeMeaning
production_shastringApproved main revision being processed; its presence alone does not prove successful validation or deployment
previous_production_shastringPreviously accepted revision; omitted when there is none
approved_byarray of stringsNormalized committer email identities from accepted first-parent merge history
observed_shastringRepository head rejected by the authorization gate
serialintegerConfirmed zone serial after a successful update

actor identifies the executing or observing system component. Human approval is represented separately in approved_by. Individual commit authors and merge-request submitters remain in the customer's Git history.

Action catalog

ActionLevelConditional fieldsMeaning
repo-config-enforcement-failederrornoneRequired repository protection or merge settings could not be enforced; processing stops for the cycle
violationerrorobserved_shaRepository history failed the production-authorization gate
change-approvedinfozone, production_sha, previous_production_sha, approved_byAn authorized revision changed the zone and processing began
change-validatedinfozone, production_shaZone syntax and policy validation passed
change-rejectederrorzone, production_shaValidation failed; prior accepted state remains authoritative
ownership-ksk-missingwarningzone, production_shaRequired customer KSK was missing; ownership processing was skipped
ownership-verify-nsinfozone, production_shaOwnership verified through NS delegation
ownership-verify-txtinfozone, production_shaOwnership verified through the CNX TXT challenge
ownership-token-generateinfozone, production_shaNew verification token generated; the token is not emitted
zone-provisioninfozone, production_shaZone added to Knot configuration
zone-record-add-scheduledinfozone, production_shaRecord shown in message scheduled for addition
zone-record-remove-scheduledinfozone, production_shaRecord shown in message scheduled for removal
zone-change-appliedinfozone, production_sha, serialKnot committed the change and the resulting serial was confirmed
zone-change-failederrorzone, production_shaDeployment attempt failed
alias-registerinfozone, production_shaConfigured alias entered processing
alias-publishinfozone, production_sha, serialAlias answers changed and the new serial was confirmed
alias-deregisterinfozone, production_shaAlias removed from the registry after removal from accepted state
alias-retractwarningzone, production_shaAnswers retracted after the configured period without a DNSSEC-validated target answer

Optional fields depend on the source event. Use action and structured fields for correlation and alert rules; message is display text.

Deployment example

{
  "timestamp": "2026-10-02T09:15:04.123456000Z",
  "server": "dns-master.example.com",
  "event_id": "7b52883921ee5bce81ffad6b1de3208a",
  "actor": "dns-ops",
  "actor_type": "system",
  "action": "zone-change-applied",
  "log_level": "info",
  "customer_id": "123",
  "zone": "example.com.",
  "production_sha": "a1b2c3d4e5f60123456789abcdef0123456789abc",
  "serial": 2026100201,
  "message": "change committed successfully; zone serial 2026100201"
}

The normal change trace is change-approved, change-validated, scheduled record operations, and zone-change-applied. Rejected validation and failed deployment have separate actions. Scheduled record operations describe intention; the applied event confirms the transaction result. Platform events correlate by zone and serial because Knot has no Git-revision context.

Platform log: dns.logs.platform

Every record contains timestamp, server, actor, actor_type, action, log_level, zone, customer_id, and message. actor is dns-master or dns-slave; actor_type is system. The message preserves Knot log text.

ActionOptional structured fields
dnssec-signing-zonenone
dnssec-signing-startednone
dnssec-signing-completeserial, rrsigs_added
dnssec-incremental-signing-completeserial, rrsigs_added
dnssec-next-signingnext_signing_at
dnssec-key-activekey_tag, algorithm, key_role, key_state
zone-file-updatedprevious_serial, serial
zone-notify-outgoingremote, serial
zone-notify-incomingremote, serial
zone-transfer-incremental-outgoingremote; started events may include previous_serial, serial; finished events may include duration_seconds, message_count, bytes
zone-transfer-incremental-incomingremote; started events may include previous_serial, serial; finished events may include remote_serial
zone-transfer-full-outgoingremote
zone-transfer-full-incomingremote
zone-refreshremote, remote_serial, expires_in_seconds

Only recognized Knot message shapes are published. If an optional value cannot be extracted, the event is retained with that field omitted.

{
  "timestamp": "2026-10-02T09:15:04.123450000Z",
  "server": "dns-master.example.com",
  "actor": "dns-master",
  "actor_type": "system",
  "action": "dnssec-signing-complete",
  "log_level": "info",
  "zone": "example.com.",
  "customer_id": "123",
  "serial": 2026100201,
  "rrsigs_added": 7,
  "message": "DNSSEC, successfully signed, serial 2026100201, new RRSIGs 7"
}

Query detail: dns.queries.detail

Classified dnstap response events use the following fields:

FieldTypeMeaning
timestampstringDNS response time
serverstringAuthoritative server that answered
query_transportstringv4 or v6, after recovery of the original client address
zonestringBest matching served zone
customer_idstringCustomer identifier for that zone
qnamestring or nullAbsolute queried name
qtypestring or nullQuery type
rcodestringResponse code
src_v4, src_v6string or nullRecovered client address; normally exactly one is populated
ecs_v4, ecs_v6string or nullEDNS Client Subnet value when supplied
answerarray of stringsText representation of each answer-section RDATA item
answer_v4, answer_v6array of stringsA and AAAA answer values for indexing

Query detail has two sampling stages:

StageScopeSelection
ProducerEach sinkAt most 1,000 detail events per one-second window; uniform reservoir sampling above that threshold
Customer deliveryYour subscription, across all fleet sinksBy default, a further sample of up to 100 records per second

Before publishing to your customer topic, CNX selects records from the fleet's query-detail stream according to your subscription's sampling level. The default limit applies across the fleet, rather than separately to each sink.

Request full fleet delivery from CNX if your consumer and SIEM can sustain up to 10,000 records per second. This removes the additional customer delivery sampling and provides the full producer-selected stream for your customer account. Per-sink producer sampling still applies, so full fleet delivery is not a complete record of every DNS query. Delivery remains best effort; use query summaries for counts.

The additional customer sampling applies only to dns.queries.detail. Operations logs, platform logs, and query summaries have no customer sampling filter. Their event selection and transport behavior remain as documented for each feed.

{
  "timestamp": "2026-10-02T09:16:00.123456789Z",
  "server": "dns-edge.example.com",
  "query_transport": "v4",
  "zone": "example.com.",
  "customer_id": "123",
  "qname": "www.example.com.",
  "qtype": "A",
  "rcode": "NOERROR",
  "src_v4": "192.0.2.10",
  "src_v6": null,
  "ecs_v4": null,
  "ecs_v6": null,
  "answer": ["192.0.2.80"],
  "answer_v4": ["192.0.2.80"],
  "answer_v6": []
}

Query summary: dns.queries.summary

FieldTypeMeaning
timestampstringCounting-window start
serverstringAuthoritative server counted
zonestringServed zone
customer_idstringCustomer identifier
rcodestringResponse code
window_secondsintegerCounting-window length, currently 60
countintegerClassified responses for this server, zone, and response code

Counts include all classified responses observed by the producer, independent of detail sampling. Sum across servers for a customer-wide zone total over the same window. Summary transport remains best effort.

{
  "timestamp": "2026-10-02T09:16:00.000000000Z",
  "server": "dns-edge.example.com",
  "zone": "example.com.",
  "customer_id": "123",
  "rcode": "NOERROR",
  "window_seconds": 60,
  "count": 84000
}

Live-zone correlation

CNX publishes these synthetic TXT records in the deployed zone:

_cnx-customer-id.example.com.    TXT "123"
_cnx-meta.example.com.           TXT "sha=<zone-directory-hash>"
_cnx-production-sha.example.com. TXT "<production_sha>"

_cnx-production-sha identifies the accepted Git revision represented by the live zone. _cnx-meta identifies the source-directory hash used for drift detection. The serial in zone-change-applied identifies the first committed zone version containing the corresponding synthetic records.