Skip to content

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.

POST /api/v1/siem/export/connectors (admin)
# 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.

Provider credential shapes
# 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).

SIEMEvent (JSON format)
{
  "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 line
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.

POST /api/v1/siem/inbound/tokens (admin)
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).

POST /api/v1/siem/inbound/{source}
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 exceeded

Supported actions (each gated by the token's allowedActions allowlist):

  • quarantine_key / unquarantine_key — stamp/clear quarantined_at on the target API key
  • force_rotate — revoke the key so the operator mints a fresh one
  • block_user — revoke every API key the target user created in the project
  • escalate_review — open a security_incident and alert the SOC
  • custom — 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

evalguard siem tokens
# 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.