SIEM Integration
MITRITY forwards governance events to your existing security information and event management (SIEM) infrastructure. Every policy decision, behavioral anomaly, and drift alert can be delivered to your SIEM in real-time, giving your security team a single pane of glass across agent governance and traditional security operations. This includes activity imported from SaaS-embedded agents — GitHub Copilot, Microsoft 365 Copilot, and Salesforce Agentforce events land in the same feed as runtime governance events.
Supported Destinations
Splunk HTTP Event Collector (HEC)
MITRITY sends events to Splunk via the HTTP Event Collector. Events are formatted as structured JSON and indexed into the source type you configure.
Configuration:
| Field | Value |
|---|---|
| Destination URL | https://your-splunk-instance:8088/services/collector/event |
| Auth token | Your Splunk HEC token |
| Source type | mitrity:governance (recommended) |
| Index | Your designated security index |
Events include all governance context: agent ID, action type, policy decision, drift score, behavioral hash delta, and timestamps. Splunk dashboards and saved searches can correlate MITRITY events with your existing security data.
Syslog CEF (QRadar, ArcSight)
For SIEM platforms that consume Common Event Format (CEF) over syslog, MITRITY formats events as CEF messages and delivers them via TCP or UDP syslog.
Configuration:
| Field | Value |
|---|---|
| Destination | syslog://your-siem:514 (TCP) or syslog+udp://your-siem:514 (UDP) |
| Format | CEF (Common Event Format) |
| Facility | local0 - local7 (configurable) |
| Severity mapping | Deny/Block = High, Alert = Medium, Allow = Low |
CEF field mapping:
| CEF Field | MITRITY Value |
|---|---|
deviceVendor | MITRITY |
deviceProduct | MITRITY Platform |
name | Policy name or behavioral_anomaly |
severity | Mapped from policy type |
src | Agent ID |
act | Action type |
outcome | allow, deny, alert, hold |
cs1 | Drift score |
cs2 | Behavioral hash |
Generic Webhook
For any SIEM or log aggregation platform that accepts HTTP webhooks, MITRITY can POST events as structured JSON to a URL you configure.
Configuration:
| Field | Value |
|---|---|
| Destination URL | https://your-endpoint/webhook |
| Auth | Bearer token, API key header, or no auth |
| Method | POST |
| Content-Type | application/json |
The webhook payload includes the full event object with all governance context. You can configure retry behavior (up to 3 retries with exponential backoff) and choose which decisions are forwarded.
Event Types
The governance events forwarded to a SIEM destination include:
| Event Type | Description |
|---|---|
policy.deny | An action was blocked by a deny policy |
policy.alert | An action triggered an alert policy |
policy.hold | An action was held for human approval |
policy.allow | An action was permitted (opt-in, high volume) |
drift.warning | Drift score exceeded the warning threshold |
drift.critical | Drift score exceeded the critical threshold |
agent.connected | An agent connected to the control plane |
agent.disconnected | An agent lost connection to the control plane |
hold.approved | A held action was approved by a human |
hold.denied | A held action was denied by a human |
hold.expired | A held action expired without a decision |
dlp.match | A DLP pattern or classifier matched on tool I/O |
Each destination chooses which decisions it receives with three switches: forward_blocked, forward_alerted and forward_allowed (see Setup). Allowed actions are high volume — turn on forward_allowed only if you need complete audit coverage.
Notification events
The same destinations also receive notification events — what the platform tells your team about, delivered to a system instead of a person. Each notification kind is switched on or off per destination type in Settings → Notifications, in the same matrix that routes Slack and email; the Webhook column sends that kind to every enabled webhook destination. There is no account-wide switch beside the destinations themselves: an enabled destination is where events go, and disabling it is how they stop. Syslog destinations receive the forwarding stream only — notification events are HTTP.
Kinds that reach webhooks by default:
| Kind | When it fires |
|---|---|
redteam.finding | An adversarial testing run found that a guardrail did not stop something it is configured to stop |
governance.review_resolved | A governance review of an agent was approved, attested, sent back for changes or denied. Withdrawing a review sends none |
report.ready | A compliance report finished generating and is on file. The payload carries the report id, type, period, hash and how many records it cites |
Any other kind can be enabled for webhooks in the matrix. Model risk findings and AIBOM drift advisories reach your destinations through their own richer payloads and are not repeated through this channel.
Envelope
Every notification event is one POST with Content-Type: application/json, your destination's stored authorization header, and two request headers: X-Mitrity-Event (the kind) and X-Mitrity-Event-ID. A Splunk HEC destination receives the envelope wrapped as {"event": …, "sourcetype": "mitrity:notification"}.
{
"type": "governance.review_resolved",
"version": "1.0",
"event_id": "7b1c9a7e-8f2d-4a31-9c77-1d2e3f4a5b6c",
"tenant": { "id": "b2c3d4e5-6f70-4812-9a3b-4c5d6e7f8091" },
"severity": "info",
"title": "Governance review attested",
"body": "The onboarding review of Billing assistant was attested.",
"link_url": "/app/governance/9d8c7b6a-5f4e-4d3c-2b1a-0f9e8d7c6b5a",
"generated_at": "2026-09-24T08:00:00Z",
"payload": {
"review_id": "9d8c7b6a-5f4e-4d3c-2b1a-0f9e8d7c6b5a",
"kind": "onboarding",
"status": "attested",
"subject_name": "Billing assistant",
"dedup_key": "9d8c7b6a-5f4e-4d3c-2b1a-0f9e8d7c6b5a"
}
}
For governance.review_resolved the title and body name the decision: approved, attested, sent back for changes or denied, as in Governance review sent back for changes and The risk assessment review of Billing assistant was sent back for changes. The payload's status is the decision as the API names it (approved, attested, changes_requested or denied) and kind the kind of review (onboarding, risk_assessment, periodic_review, change or incident). subject_name is the agent's name, and is left out when the agent could not be read; dedup_key repeats the review id.
event_idis the same for every destination that received the event — use it to deduplicate.title,bodyandlink_urlare what a person would have read in the dashboard, so a receiver that knows nothing about a kind can still file it.payloadis the kind's own data; it never carries a credential, a prompt or a matched value.versionstays1.0when a field is added and changes when one is removed or renamed.- A delivery that fails is recorded on the destination (Settings → SIEM shows the last error), and does not stop delivery to your other destinations.
DLP Event Schema
DLP events are emitted whenever a configured DLP pattern (built-in or tenant-authored) or a legacy classifier fires on an inbound or outbound tool payload. The structural fields below describe the match (which pattern fired, where in the payload, and what the engine did about it) without ever carrying the raw matched bytes — see GDPR-Safe Audit Contract below.
JSON event shape
{
"id": "e1c4...-...",
"tenant_id": "t1...-...",
"agent_id": "a1...-...",
"policy_id": "p1...-...",
"event_type": "dlp.match",
"direction": "outbound",
"action_taken": "blocked",
"detection_reason": "pattern_match",
"pattern_id": "f1c2...-...",
"pattern_name": "SSN (US)",
"position": 247,
"length": 11,
"redaction_count": null,
"tool_pattern_matched": "drive:create",
"destination_domain": "files.example.com",
"sensitivity_tags": ["pii"],
"payload_size_bytes": 4096,
"occurred_at": "2026-05-26T10:14:00Z"
}
Field reference
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique event identifier. Use for SIEM deduplication. |
tenant_id | string (UUID) | MITRITY tenant the event belongs to. |
agent_id | string (UUID) | Agent that produced the tool call. |
policy_id | string (UUID) | Policy whose binding triggered the match (nullable for legacy classifier events). |
direction | enum | inbound or outbound — direction of the tool payload at the moment of the match. |
action_taken | enum | What the engine did. See enum values. |
detection_reason | enum | Why the engine fired. See enum values. |
pattern_id | string (UUID), nullable | The dlp_patterns row that fired. NULL for legacy classifier-driven events (sensitive_exfil, volume_anomaly, accumulation, unauthorized_destination). |
pattern_name | string | Denormalised pattern name at event-creation time. Survives later pattern delete; lets the SIEM render the event without an API call back to MITRITY. |
position | integer | UTF-8 byte offset of the match within the payload. |
length | integer | UTF-8 byte length of the match. |
redaction_count | integer, nullable | Distinct matches replaced when action_taken=redacted. NULL for blocked / flagged. |
tool_pattern_matched | string | Denormalised action type that triggered the call, e.g. drive:create, s3:put, slack:post. Lets SOC teams pivot from "which pattern fired" to "on which tool". |
destination_domain | string, nullable | Outbound destination domain when known. |
sensitivity_tags | string array | Tags attached to the matched pattern (pii, credentials, competitor, internal, legal, custom). |
payload_size_bytes | integer, nullable | Size of the tool payload at the time of the match. |
occurred_at | RFC 3339 timestamp | When the match occurred at the edge node. |
action_taken values
| Value | Meaning |
|---|---|
blocked | Engine denied the tool call. Caller saw a classified JSON-RPC error. Pattern binding action was block. |
redacted | Engine replaced the match with [REDACTED-<pattern_name>] before the payload reached the downstream tool. Pattern binding action was redact. redaction_count is set. |
flagged | Engine let the call through unchanged but recorded the match for review. Pattern binding action was flag. |
alerted | Legacy v1 vocabulary — classifier-driven alert with no enforcement. |
logged | Legacy v1 vocabulary — engine recorded the match without blocking, alerting, or modifying. |
Pattern-driven binding actions map deterministically: block→blocked, redact→redacted, flag→flagged. The legacy alerted and logged values continue to flow for classifier-driven events so v1 correlation rules keep working.
detection_reason values
| Value | Meaning |
|---|---|
pattern_match | A dlp_patterns row bound to a policy fired. Distinguishes v2 binding-driven matches from the v1 classifier reasons below. Implies pattern_id is set. |
sensitive_exfil | v1 classifier judged the payload as sensitive exfiltration. |
volume_anomaly | v1 classifier judged the cumulative outbound volume anomalous. |
accumulation | v1 classifier detected slow accumulation of reads suggesting a future bulk write. |
unauthorized_destination | Outbound destination was not on the agent's destination allowlist. |
Splunk HEC field mapping
When the SIEM destination is Splunk HEC, every field above is indexed under the configured source type (default mitrity:governance; DLP events also tag mitrity:dlp for narrower searches). Field names match the JSON shape verbatim, so SPL searches like sourcetype=mitrity:governance event_type=dlp.match pattern_name="SSN (US)" work out of the box.
The following rows extend the base Splunk field set with the DLP-specific fields shipped in v2:
| Splunk field | Source | Type |
|---|---|---|
pattern_id | DLP event | string (UUID, may be null) |
pattern_name | DLP event | string |
position | DLP event | integer |
length | DLP event | integer |
redaction_count | DLP event | integer (may be null) |
tool_pattern_matched | DLP event | string |
CEF extension fields
When the SIEM destination is syslog CEF, DLP events extend the base CEF mapping with the following extension fields. Names follow CEF conventions (csN for arbitrary strings, cnN for arbitrary numbers, with a csNLabel/cnNLabel companion so the SIEM knows what each slot means):
| CEF extension | MITRITY field | Notes |
|---|---|---|
cs1Label=PatternName cs1=<pattern_name> | pattern_name | Empty for legacy classifier events. |
cs2Label=PatternId cs2=<pattern_id> | pattern_id | Empty for legacy classifier events. |
cs3Label=ToolPattern cs3=<tool_pattern_matched> | tool_pattern_matched | e.g. drive:create. |
cs4Label=DetectionReason cs4=<detection_reason> | detection_reason | pattern_match for v2 binding events. |
cn1Label=MatchPosition cn1=<position> | position | UTF-8 byte offset. |
cn2Label=MatchLength cn2=<length> | length | UTF-8 byte length. |
cn3Label=RedactionCount cn3=<redaction_count> | redaction_count | Omitted when null. |
act | action_taken | One of blocked, redacted, flagged, alerted, logged. |
These slots compose with the base CEF mapping in Syslog CEF above (src=<agent_id>, outcome=<action_taken>, etc.). The cs1–cs4 and cn1–cn3 slots used for DLP events are documented here so QRadar / ArcSight reference sets and ArcSight active channels can be tuned to the right column.
Worked correlation rules
The following are real-world rules SOC teams have written against the v2 schema. They are intentionally written in vendor-neutral pseudo-code so they translate cleanly to SPL, AQL, or ArcSight rule syntax.
Rule 1 — Repeated credential-pattern blocks from one agent. Alert when an agent triggers pattern_match on a credentials-category pattern with action_taken=blocked at least 5 times in 1 hour. This catches an agent that is consistently trying to push API keys, GitHub tokens, or other credentials and is being blocked — a strong signal of either a compromised agent or a mis-scoped mission.
sourcetype=mitrity:governance event_type=dlp.match
detection_reason=pattern_match
action_taken=blocked
sensitivity_tags=credentials
| stats count by agent_id, pattern_name, tool_pattern_matched
| where count >= 5
| eval window="1h"
Rule 2 — SOC dashboard panel: pattern × tool heatmap. Show pattern_name and tool_pattern_matched side-by-side so the SOC can see at a glance which patterns are firing on which tools. Useful for tuning binding direction and action.
sourcetype=mitrity:governance event_type=dlp.match
detection_reason=pattern_match
earliest=-24h
| stats count by pattern_name, tool_pattern_matched, action_taken
| sort -count
Rule 3 — Redaction-volume drift on a specific binding. Alert when total redaction_count for a given pattern_name exceeds the rolling 7-day mean by 3 standard deviations. Detects a tool starting to leak materially more matched content than usual — often a sign of an upstream prompt template change.
sourcetype=mitrity:governance event_type=dlp.match
action_taken=redacted
| timechart span=1h sum(redaction_count) by pattern_name
| stats avg(*) as mean stdev(*) as sd
| ... // your SIEM's anomaly-detection primitive
GDPR-Safe Audit Contract
DLP events never include the raw matched content. The engine only persists structural metadata:
pattern_nametells you which pattern firedpositionandlengthtell you where in the payload the match was, expressed as UTF-8 byte offsetstool_pattern_matchedtells you which tool call it was on
There is no value, matched_text, or other field carrying raw bytes from the payload — and the boundary between the edge node and the audit reporter strips any such field defensively as defense-in-depth. SOC teams who need the actual matched text correlate position + length + occurred_at + agent_id against customer-controlled application logs (the systems your agents call into) to retrieve the raw context. MITRITY's side stays GDPR-safe by design: no controller-of-record obligations on matched content, no DSAR exposure on substrings, no incident-response leakage from MITRITY's audit store.
This contract holds for all three forwarders — Splunk HEC, syslog CEF, and generic webhook — without exception.
Setup
Configure SIEM integration in the dashboard at Settings > Integrations or via the API:
# Create a Splunk HEC destination
curl -X POST https://api.mitrity.com/api/v1/siem-destinations \
-H "Authorization: Bearer mk_your-api-key" \
-H "Content-Type: application/json" \
-d '{
"name": "Splunk production",
"destination_type": "splunk_hec",
"endpoint_url": "https://your-splunk:8088/services/collector/event",
"auth_header": "Splunk your-hec-token",
"forward_blocked": true,
"forward_alerted": true,
"forward_allowed": false,
"enabled": true
}'
| Field | Description |
|---|---|
name | A name for the destination (up to 255 characters) |
destination_type | splunk_hec, syslog_cef, webhook or custom |
endpoint_url | The HTTPS URL events are posted to. A syslog_cef destination receives CEF-formatted events over HTTPS. |
auth_header | Optional. Sent as the Authorization header on every delivery and stored encrypted; responses only say has_auth_header |
forward_blocked / forward_alerted / forward_allowed | Which decisions the destination receives. A decision that is neither blocked nor allowed follows forward_alerted. |
enabled | Whether the destination receives events |
Owners and Managers manage destinations. Each one reports its latest delivery as last_sent_at and last_error. GET /api/v1/siem-destinations lists them, and PUT or DELETE on /api/v1/siem-destinations/{id} updates or removes one.
A PUT replaces the destination's settings, so send every field: a flag left out is read as false. The auth_header is the exception. Leave it out and the stored header is kept, send an empty string to remove it, or send a new value to replace it. A stored header is never sent to a new endpoint: a PUT that changes endpoint_url must send auth_header again, or an empty string if the new endpoint needs none, and is refused with 400 otherwise. The dashboard asks for the same when you change a destination's endpoint.
You can configure multiple SIEM destinations. For example, send blocked and alerted decisions to your primary SIEM and every decision to a long-term log archive.
Troubleshooting
- Events not arriving: Verify the destination URL is reachable from the MITRITY control plane. Check the integration status in Settings > Integrations — failed deliveries show error details.
- Duplicate events: MITRITY uses at-least-once delivery. Your SIEM should deduplicate on the event
idfield. - High volume: Leave
forward_allowedoff unless you need every allowed action for compliance. - DLP events missing
pattern_id/pattern_name: Expected for legacy classifier-driven events (detection_reasonis one ofsensitive_exfil,volume_anomaly,accumulation,unauthorized_destination). Only v2 pattern-bound matches (detection_reason=pattern_match) carry a non-nullpattern_id.