SIEM & SOAR integration
EvalGuard is bidirectional with your SIEM. It exports security events to Splunk, Microsoft Sentinel, and generic webhooks, and it accepts signed inbound SOAR triggers that quarantine a key or open an incident straight from your detection playbook.
Every outbound delivery is SSRF-guarded and every inbound trigger is HMAC-verified. Connector credentials are sealed at rest; inbound HMAC secrets are shown exactly once.
What ships today
Export connectors for Splunk HEC, Microsoft Sentinel, and a generic CEF/JSON webhook ship today — full config CRUD, encrypted credentials, JSON and CEF formats, and the SSRF-guarded delivery engine. Actual outbound delivery (including the connector self-test) is gated behind AIDR_SIEM_EXPORT_ENABLED (default off) so nothing is pushed to a customer SIEM until an operator opts in. The inbound SOAR path — token minting, signature verification, and the quarantine / escalate actions — ships and runs today. STIX 2.1, MISP, and TAXII formatters exist in core and are next on the roadmap for the config API.
Two directions
The integration is a loop, not a one-way drain:
- Export (outbound)— EvalGuard's AIDR detect→respond pipeline pushes a canonical security event to your SIEM over
/api/v1/siem/export/connectors. - Inbound (SOAR)— your SIEM's playbook posts a signed trigger back to
/api/v1/siem/inbound/{source}to quarantine a leaked API key, force-rotate, block a user, or open a security incident — with no human in the loop.
Configure an export connector
Connectors are org-scoped and admin-only to create. Credentials are sealed with the server's BYOK_SECRET (AES-GCM) before insert and are never returned — list responses expose only a hasCredentials boolean. The three delivery providers are splunk, sentinel, and webhook; formats are json or cef.
# Splunk HTTP Event Collector (HEC)
curl -X POST https://api.evalguard.ai/api/v1/siem/export/connectors \
-H "Authorization: Bearer $EVALGUARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"orgId": "org-uuid",
"name": "Prod Splunk",
"provider": "splunk",
"endpoint": "https://splunk.example:8088/services/collector",
"format": "json",
"credentials": {
"hecToken": "••••••",
"sourceType": "evalguard:aidr",
"index": "main"
},
"minSeverity": "medium",
"enabled": true,
"test": true
}'
# → 201 { id, name, provider, endpoint, format, enabled,
# minSeverity, hasCredentials: true, ... }
# If "test": true and AIDR_SIEM_EXPORT_ENABLED is off, the response
# carries: test: { ok: false, featureDisabled: true }Sentinel derives its endpoint from the workspace id (you leave endpoint empty); the webhook provider can optionally sign the body.
# Microsoft Sentinel (Log Analytics HTTP Data Collector)
# endpoint derived → https://<workspaceId>.ods.opinsights.azure.com/api/logs
# request is SharedKey HMAC-SHA256 signed
{ "provider": "sentinel", "endpoint": "", "credentials": {
"workspaceId": "<guid>", "sharedKey": "<base64>", "logType": "EvalGuardAIDR" } }
# Generic CEF/JSON webhook (any SOAR/SIEM that ingests an HTTP POST)
# optional HMAC body signature → X-EvalGuard-Signature: sha256=<hex>
# + X-EvalGuard-Timestamp (scheme: HMAC(timestamp.body, secret))
{ "provider": "webhook", "endpoint": "https://soar.example/hook",
"format": "cef", "credentials": { "webhookSecret": "••••••" } }Full CRUD is available: GET (list, org-scoped), PATCH (update — including enabled and minSeverity), and DELETE. Every mutation is role-gated (admin) and written to the audit log; connectors can be pre-staged while the feature flag is off.
The event / export format
Every export is the canonical SIEMEvent emitted by the AIDR detect→respond pipeline. json delivers the structured event; cef renders a CEF:0 line (byte-compatible with the in-package CEF formatter, so a parser reads either the same way).
{
"id": "evt-...",
"timestamp": "2026-07-15T12:00:00.000Z",
"eventType": "firewall.blocked", // auth.* | firewall.* | redteam.* |
// compliance.* | data.* | model.* | mcp.*
"severity": "high", // low | medium | high | critical
"source": "firewall",
"sourceIp": "203.0.113.10",
"userId": "user-uuid",
"orgId": "org-uuid",
"action": "flag",
"outcome": "failure", // success | failure | unknown
"description": "Prompt-injection attempt blocked",
"metadata": { "score": 0.94, "rule": "pi-heuristic" }
}The same event in CEF. Severity maps low=3, medium=5, high=8, critical=10; Splunk wraps the JSON event as { event, sourcetype, index, host, time }.
CEF:0|EvalGuard|AISecPlatform|1.0|firewall.blocked|flag|8|src=203.0.113.10 duser=user-uuid msg=Prompt-injection attempt blocked outcome=failure cs1Label=orgId cs1=org-uuid cs_score=0.94
Inbound SOAR — quarantine on trigger
When your SIEM detects a leaked credential or an active attack, its playbook can act on EvalGuard directly. First an admin mints an inbound token; the 32-byte HMAC secret is returned exactly once and stored encrypted thereafter — lose it and you rotate. Sources are splunk, sentinel, qradar, and generic_webhook.
curl -X POST https://api.evalguard.ai/api/v1/siem/inbound/tokens \
-H "Authorization: Bearer $EVALGUARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"projectId": "proj-uuid",
"source": "splunk",
"label": "prod-soar-playbook",
"allowedActions": ["quarantine_key", "escalate_review"],
"rateLimitPerMin": 30
}'
# → 201 { token: { id, source, label, allowedActions, hmacSecret },
# note: "store hmacSecret in your SIEM; it won't be shown again" }The playbook then POSTs a signed trigger. Auth is the shared secret (not an eg_key), carried in the vendor's signature header. Each source verifies differently but funnels into one check: X-Splunk-Signature: sha256=<hex>(HMAC over the raw body), Sentinel's Authorization: SharedKey <token>, X-QRadar-Signature, or the generic X-EvalGuard-Signature + X-EvalGuard-Timestamp (5-min skew window).
curl -X POST https://api.evalguard.ai/api/v1/siem/inbound/splunk \
-H "X-EvalGuard-Project: proj-uuid" \
-H "X-EvalGuard-Token-Id: token-uuid" \
-H "X-Splunk-Signature: sha256=<hmac-of-raw-body>" \
-H "Content-Type: application/json" \
-d '{
"action": "quarantine_key",
"target": "api_key:key-uuid",
"reason": "Leaked key seen in public paste",
"idempotency_key": "incident-4821"
}'
# → 200 { action, target, status: "executed" }
# 401 signature/auth failure 403 action not in token allowlist
# 404 token not found 429 rate limit exceededSupported actions (each gated by the token's allowedActions allowlist):
quarantine_key/unquarantine_key— stamp/clearquarantined_aton the target API keyforce_rotate— revoke the key so the operator mints a fresh oneblock_user— revoke every API key the target user created in the projectescalate_review— open asecurity_incidentand alert the SOCcustom— audit-only; drives your own downstream workflow
Triggers are idempotent (via idempotency_key), rate-limited per-token, and every attempt — executed, skipped, or failed — lands in the siem_inbound_actionsaudit trail. The target is always verified to belong to the token's project before any mutation.
Manage tokens from the CLI
# List inbound tokens (secrets are masked) evalguard siem tokens list --project proj-uuid # Mint a token — prints the HMAC secret exactly once evalguard siem tokens create \ --source splunk --label prod-soar \ --actions quarantine_key,escalate_review \ --project proj-uuid # Revoke (cuts the inbound webhook — guarded by --dry-run / --yes) evalguard siem tokens revoke <tokenId> --project proj-uuid --dry-run evalguard siem tokens revoke <tokenId> --project proj-uuid --yes
Safe by construction
Outbound delivery runs through the shared SSRF guard: the target is validated before every POST, and delivery uses a redirect-revalidating fetch that pins DNS against rebinding and strips credential headers on cross-origin redirects — so a connector can never be pointed at an internal host to exfiltrate its own Splunk/Sentinel token. Inbound signatures are compared in constant time, and the broader connector catalog surfaced by GET /api/v1/siem (Chronicle, Elastic, Datadog, QRadar, and others) advertises the config registry — Splunk, Sentinel, and the generic webhook are the providers with a live, SSRF-guarded delivery path today.