Skip to content

Sending events to a SIEM

TechWatchAlert can stream your organization’s security events to your SIEM: a CVE that affects an asset, a decision tier that rises, reported exploitation, a fixed machine, a reopened case, a compliance or external attack surface finding. Your SOC correlates them with the rest of its logs, without opening the application.

Team and Enterprise plans The page is reserved for the organization’s administrators.

  1. Open Organization settings › Security › SIEM.
  2. Choose the tool: Syslog (TLS), Splunk, Microsoft Sentinel or Elastic.
  3. Fill in the address and the secret (see below for each tool).
  4. Set What is sent: event types, minimum severity, projects.
  5. Click Test and save. The test checks the address, the certificate, the credentials, then sends one test event (event_type = test). The destination is saved only if the test succeeds; Save anyway remains available if your SIEM is not ready yet.

An organization can have up to five destinations, for example a production Splunk and a staging syslog.

  • Transport: TCP encrypted with TLS 1.2 or later (RFC 5425), port 6514 by default, or your collector’s port (443, or 1024 to 65535).
  • Framing: one frame per event, prefixed by its length in octets (octet counting, RFC 6587 § 3.4.1), the only framing allowed over TLS.
  • Message: RFC 5424 header (<PRI>1 timestamp host application - type - ), no structured data, then the body in CEF (ArcSight, QRadar) or JSON (the schema below).
  • Certificate: verified, host name included. If your collector presents a certificate signed by your internal certificate authority, paste it in PEM format: only that CA is then accepted.
  • Syslog facility: authpriv (10) by default; auth, audit or local0 to local7 as you prefer. The syslog severity follows the event’s (critical → 2, high → 3, medium → 4, low → 5, information → 6).
Type (event_type) When Severity
vulnerability.detected a CVE affects a monitored component or machine (the alert is created) the CVE’s
vulnerability.priority_changed a case’s decision tier changes, for example from D+60 to D+3 from the new tier
vulnerability.status_changed a case status changes (in remediation, fixed, risk accepted…) information
vulnerability.exploited added to the KEV catalog (CISA, VulnCheck), exploitation reported by CERT-FR, public PoC or ransomware, on a CVE that affects an asset critical (high for a PoC)
vulnerability.reopened a closed case reopens (machine vulnerable again, expired exception, fix not confirmed) at least medium
vulnerability.fix_verified the inventory confirms that no machine is exposed anymore information
host.vulnerable a machine becomes exposed to a CVE, or is exposed again the CVE’s
host.remediated the inventory sees a machine that is no longer exposed information
compliance.finding a hardening rule becomes non-compliant on a machine the rule’s
attack_surface.finding a finding opens on a monitored domain (vulnerable service, sensitive port, certificate…) the finding’s
audit.action an action of the organization’s audit log (optional, unchecked by default) information

Without a choice of types, a destination receives everything except the audit log. A project filter still lets organization events (audit log) through, since they have no project.

Each event follows a stable, versioned schema (schema_version). Timestamps are in UTC (RFC 3339, milliseconds). event_id is stable: the same fact sent again keeps the same identifier, so your SIEM can deduplicate. The event is frozen at the time of the fact. Blocks that do not apply are absent.

Example: vulnerability.detected
{
"schema_version": "1.0",
"event_id": "5e04c44f-419c-5e6a-b773-12f474678160",
"event_type": "vulnerability.detected",
"category": "vulnerability",
"timestamp": "2026-10-25T09:30:15.123Z",
"severity": "critical",
"severity_score": 10,
"message": "CVE-2026-1234567 affects a monitored asset",
"organization": { "id": "11111111-2222-3333-4444-555555555555" },
"project": { "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "name": "Portal" },
"vulnerability": {
"id": "CVE-2026-1234567", "severity": "critical", "cvss_score": 9.8, "cvss_version": "3.1",
"cvss_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "epss": 0.43,
"kev": true, "exploited": true, "exploitation_sources": ["cisa_kev", "certfr"],
"poc": true, "ransomware": false,
"reference": "https://www.cve.org/CVERecord?id=CVE-2026-1234567"
},
"asset": { "name": "nginx 1.25.3" },
"url": "https://app.techwatchalert.com/fr/alerts/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/CVE-2026-1234567"
}
Field Content
schema_version, event_id, event_type, category, timestamp schema version, stable identifier (UUID), type, family (vulnerability, host, compliance, attack_surface, audit), UTC timestamp
severity, severity_score info, low, medium, high, critical; score 1, 3, 5, 8 or 10
message short sentence in English
organization.id, project.id, project.name where the fact happens
vulnerability.* CVE, severity, CVSS score and vector, EPSS, KEV, exploitation and its sources (cisa_kev, vulncheck_kev, certfr), PoC, ransomware, decision_tier (j3, j14, j60, differe)
host.id, host.name the machine concerned
asset.name, asset.software the exposed component or software
change.field, change.from, change.to, change.reason what changed (tier, case status)
exploitation.kind, exploitation.sources known_exploited, poc_published or ransomware
finding.* rule or finding type, title, section, benchmark, target, port, service, product, version, related CVEs
detection.historical, detection.reappeared alert of a component added for already published CVEs; machine exposed again
actor.id, actor.email, actor.type, source.ip, audit.action, audit.target author and action (audit log, case decisions)
url link to the application page

Never sent: case comments, notes, justifications and attachments, nor the settings details of audit actions.

Header: CEF:0|TechWatchAlert|TechWatchAlert|1.0|<event_type>|<readable name>|<severity_score>|. The header escapes \ and |; the extension escapes \, = and line breaks, as the standard requires.

CEF key Field
rt timestamp (milliseconds since the epoch)
externalId event_id
cat, act, msg category, event_type, message
dhost host.name
suser, suid, src actor.email, actor.id, source.ip
cs1 the object: CVE (cveId), rule (ruleId), finding type (findingType) or audit action (auditAction), named by cs1Label
cs2 / cs4 / cs5 project.name / project.id / organization.id
cs3 decisionTier, or a case’s newStatus
cs6 url
cfp1 / cfp2 CVSS score / EPSS
cn1 / cn2 KEV (0 or 1) / confirmed exploitation (0 or 1)
ECS field Field
@timestamp, message timestamp, message
event.id, event.action, event.severity, event.kind, event.category, event.type event_id, event_type, severity_score; alert or event; vulnerability, host, configuration, network
event.dataset, event.module, event.provider, event.reference techwatchalert; url
vulnerability.id, .severity, .score.base, .score.version, .reference, .enumeration, .classification, .scanner.vendor the vulnerability block
host.id, host.name; user.id, user.email; source.ip machine; author
rule.id, rule.name, rule.category compliance or external attack surface finding
organization.id, labels.project_id, labels.project_name organization, project
observer.vendor, observer.product TechWatchAlert
techwatchalert.* what has no ECS equivalent: EPSS, KEV, tier, change, exploitation, finding, detection

TimeGenerated, EventId, EventType, Category, Severity, SeverityScore, Message, OrganizationId, ProjectId, ProjectName, CveId, CvssScore, Epss, Kev, Exploited, DecisionTier, HostId, HostName, FindingRule, Url, SchemaVersion, and Details (dynamic), which carries the full event.

// Exploited CVEs affecting an asset, over 7 days
TechWatchAlert_CL
| where TimeGenerated > ago(7d)
| where EventType == "vulnerability.exploited"
| summarize Projects = make_set(ProjectName), Latest = max(TimeGenerated) by CveId, CvssScore, Kev
| order by Latest desc
// Machines exposed again (reappearance after a fix)
TechWatchAlert_CL
| where EventType == "host.vulnerable" and tobool(Details.detection.reappeared)
| project TimeGenerated, HostName, CveId, ProjectName, Url
// Tiers raised to D+3: to handle within three days
TechWatchAlert_CL
| where EventType == "vulnerability.priority_changed" and DecisionTier == "j3"
| project TimeGenerated, CveId, ProjectName, From = tostring(Details.change.from), Url
  • Nothing is lost at the first incident: events are queued together with the decision that produces them, then sent in batches. A SIEM outage (network, 5xx, 429) is retried later, with a growing delay, honoring the delay requested by the SIEM. Even a settings refusal (revoked token, unknown index) is retried: fix the configuration and pending events will go out.
  • Cap: after several hours of failures, an event is dropped and counted as Dropped on the destination page. Each destination’s queue is also bounded.
  • Visible status: the page shows the last send, the events sent, pending and dropped, the failures in a row and the cause of the last failure, without technical details.
  • Syslog has no acknowledgment: a batch is considered sent once the collector has accepted all its frames on the TLS connection.
  • Outside the plan, nothing is sent: pending events are discarded and the page says so. Destinations stay listed and can be deleted; they resume as they are if the plan comes back.
  • The token, secret or key is encrypted at rest, never shown again, never written to a log. Changing the address or the application requires entering it again.
  • Encrypted connection, verified certificate, no redirects. The address is checked at every send.
  • The address must be public: internal network addresses are refused. For an internal SIEM, expose a collector on a filtered public address (for example a TLS syslog open to TechWatchAlert’s addresses only); relaying through the agent is not available for SIEM yet.
  • Every creation, change and deletion of a destination goes into the organization’s audit log.