Skip to main content
Version: 1.8.0

SIEM & Webhooks

Enterprise only

Not included in DVARA Open Source.

The Enterprise platform writes security-relevant events to an append-only, HMAC-signed, hash-chained audit log. Use its managed exporters and webhooks to send that evidence to the systems where your security and compliance teams already work.


SIEM export​

DVARA ships three SIEM exporters out of the box: Splunk HEC, AWS CloudWatch Logs, and Apache Kafka. Each exporter receives persisted audit envelopes through its own bounded queue, so a slow SIEM does not delay the request that produced the event. Any combination can be enabled simultaneously, and failure on one exporter never blocks the others or primary audit persistence.

Splunk HEC​

Splunk's HTTP Event Collector receives audit events as JSON over HTTPS. DVARA POSTs to the HEC endpoint using the configured token and index.

dvara:
llm-gateway:
siem:
splunk:
enabled: true
hec-url: https://splunk.example.com:8088/services/collector
token: ${SPLUNK_HEC_TOKEN}
index: dvara-audit # blank = default index
source: dvara-gateway
source-type: _json
timeout-seconds: 10
PropertyDefaultDescription
enabledfalseEnable Splunk export
hec-url—Splunk HEC endpoint
token—HEC authentication token
indexblankTarget Splunk index (blank = HEC default)
sourcedvara-gatewaySplunk source field
source-type_jsonSplunk sourcetype field
timeout-seconds10HTTP timeout

The source-type: _json default tells Splunk to parse events as structured JSON, so every DVARA audit field becomes a searchable attribute. No Splunk-side field extraction required.

AWS CloudWatch Logs​

CloudWatch Logs batches events and flushes them to a log group and stream. DVARA signs the HTTP request directly; it does not use the AWS SDK credential chain. Set access-key, secret-key, and, for temporary credentials, session-token. If those properties are blank, DVARA reads AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN. IRSA and EC2 instance-profile credentials are not read in 1.8.0.

dvara:
llm-gateway:
siem:
cloudwatch:
enabled: true
log-group: /dvara/audit
log-stream: dvara-audit
region: us-east-1
access-key: ${AWS_ACCESS_KEY_ID}
secret-key: ${AWS_SECRET_ACCESS_KEY}
session-token: ${AWS_SESSION_TOKEN:}
endpoint: # blank = default regional endpoint
batch-size: 25
timeout-seconds: 10
flush-interval-seconds: 5
max-buffered-events: 10000
export-queue-capacity: 10000
PropertyDefaultDescription
enabledfalseEnable CloudWatch export
log-group—CloudWatch Logs group name (must exist)
log-streamdvara-auditLog stream name
regionus-east-1AWS region
endpointblankCustom endpoint URL (for GovCloud, etc.)
access-keyAWS_ACCESS_KEY_IDAccess key used for SigV4 signing
secret-keyAWS_SECRET_ACCESS_KEYSecret key used for SigV4 signing
session-tokenAWS_SESSION_TOKENSession token for temporary credentials
batch-size25Events per PutLogEvents call
timeout-seconds10HTTP request timeout
flush-interval-seconds5Maximum wait before a partial batch is sent
max-buffered-events10000Maximum events retained by the CloudWatch exporter buffer
export-queue-capacity10000SIEM-wide maximum queued export jobs; events are dropped when the queue cannot accept more work

The supplied IAM principal needs logs:CreateLogStream and logs:PutLogEvents on the target log group. CloudWatch sends a full batch immediately, sends a partial batch every five seconds by default, and flushes at shutdown. A failed send remains buffered for a later attempt. When max-buffered-events is reached, the oldest buffered event is dropped and logged.

Apache Kafka​

Kafka is the highest-throughput option — use it when your SIEM is a Kafka consumer (Fluentd, Logstash, Vector) or when you need a durable buffer in front of your SIEM. DVARA publishes to Kafka with SASL and SSL authentication support.

dvara:
llm-gateway:
siem:
kafka:
enabled: true
bootstrap-servers: broker1.example.com:9092,broker2.example.com:9092
topic: dvara-audit
dead-letter-topic: dvara-audit-dlq
acks: all
security-protocol: SASL_SSL
sasl-mechanism: SCRAM-SHA-512
sasl-jaas-config: >-
org.apache.kafka.common.security.scram.ScramLoginModule required
username="dvara" password="${KAFKA_PASSWORD}";
PropertyDefaultDescription
enabledfalseEnable Kafka export
bootstrap-servers—Comma-separated broker list
topicdvara-auditPrimary target topic
dead-letter-topicblankDLQ for delivery failures (blank = DLQ disabled)
acksallProducer acks — all waits for ISR replication, protecting audit events from broker failures
security-protocol—e.g. SASL_SSL, PLAINTEXT
sasl-mechanism—e.g. PLAIN, SCRAM-SHA-256, SCRAM-SHA-512
sasl-jaas-config—Full JAAS config string

The default acks=all is deliberate: audit events must survive broker failures. Dropping this to acks=1 or acks=0 improves throughput but risks silent data loss — don't do it for compliance use cases.

Multi-destination export​

Every exporter runs independently. Enabling all three ships each event to Splunk, CloudWatch, and Kafka in parallel — useful for migration scenarios or when different teams own different pipelines.

Verify delivery and chain fields​

Every exported record includes the event data plus hmac, previous_hash, pod_instance_id, chain_epoch, and chain_sequence. Group records by pod_instance_id and chain_epoch, order by chain_sequence, verify each previous_hash against the preceding hmac, and then recompute the HMAC with the protected audit secret. sequence_number is arrival order, not the position within a chain.

gateway_siem_export_total{exporter,outcome} records success, failure, and dropped. A non-2xx Splunk response is a failure. A dropped event means the export queue could not keep up; the primary audit record remains stored. Alert on any increase in failure or dropped, and update strict SIEM schemas to accept the chain fields added in 1.8.

A2A events​

The A2A plane writes to its own tamper-evident audit chain, separate from the shared LLM/MCP chain. Those A2A_* events (hop intent/result/denied, delegation records, per-hop PII and loop detections, approval decisions) are fanned out to the same three exporters — Splunk, CloudWatch, Kafka — with no separate configuration, inheriting the same source / sourcetype / index. So a single SIEM pipeline sees governance events from all three planes. A2A events likewise appear in the SOC 2 / HIPAA / GDPR / RBI / SEBI compliance reports.


Webhooks​

Webhooks are the outbound side of DVARA's event system — HTTPS callbacks fired when specific events occur (policy decisions, budget breaches, approval gates, MCP tool calls, etc.). They're per-workspace and managed from the DVARA Flightdeck.

Each webhook has:

  • URL — target HTTPS endpoint

  • Event types — which DVARA event types to subscribe to. Webhook fan-out is selective, not general: it covers a fixed set of 12 operational and security events, not every audit event the gateway writes. Subscription uses the WebhookEventType enum names; ten of the twelve are identical to the audit event string and the underlying header value, two are not. The full set:

    Subscription name (the WebhookEventType enum)Underlying audit event / X-Gateway-Event header value
    POLICY_DENIALPOLICY_DENIED
    BUDGET_WARNINGBUDGET_CAP_WARNING
    PII_DETECTEDPII_DETECTED
    IP_ACCESS_DENIEDIP_ACCESS_DENIED
    BUDGET_CAP_SOFTBUDGET_CAP_SOFT
    BUDGET_CAP_HARDBUDGET_CAP_HARD
    INJECTION_DETECTEDINJECTION_DETECTED
    GUARDRAIL_BLOCKEDGUARDRAIL_BLOCKED
    AGENT_LOOP_DETECTEDAGENT_LOOP_DETECTED
    MCP_APPROVAL_REQUESTEDMCP_APPROVAL_REQUESTED
    MCP_APPROVAL_TIMEOUTMCP_APPROVAL_TIMEOUT
    COST_ANOMALYCOST_ANOMALY

    Subscribe with the left-column names — that's what the eventTypes array in the create payload expects, what the DVARA Flightdeck UI lists, and what gets stored. Route receivers on the right-column header value (X-Gateway-Event), or on eventType inside the JSON body — both forms are the audit-event string, not the enum name. The two-name relationship for the first two rows is a deliberate carry-over from the audit-event taxonomy; the table above and the audit and compliance guide are the source of truth for the audit-event-string form. If you need a fan-out for events outside this set (WORKSPACE_CREATED, GATEWAY_RESPONSE, etc.), use SIEM export instead — SIEM ships every audit event the gateway writes.

  • Secret — HMAC-SHA256 signing secret, sent as the X-Gateway-Signature: sha256=<hex> header

  • Status — ACTIVE or DISABLED

SSRF protection on workspace-supplied URLs

A webhook URL is fetched server-side by DVARA. When a workspace registers a webhook through workspace self-service, the URL is validated at save time: it must be an http/https endpoint that does not resolve to a loopback, private, link-local, or cloud-metadata address (e.g. 127.0.0.1, 10.0.0.0/8, 192.168.0.0/16, 169.254.169.254). This blocks server-side request forgery — a workspace cannot turn webhook delivery into a probe of your internal network or cloud metadata. As defense-in-depth, operators should also run a network egress policy so the gateway can only reach intended destinations.

Scope: this validation runs on the workspace portal registration path only. The platform-wide Flightdeck page (/webhooks, owner role) deliberately does not validate — it's a privileged path used for operator tooling like internal monitoring webhooks. Scripts that accept arbitrary URLs and call the admin endpoint should add their own URL allowlist; otherwise an owner-scoped PAT can register a webhook to any address the gateway can reach.

Retry and delivery​

Webhook delivery uses exponential backoff with a bounded retry count. Global config under dvara.llm-gateway.webhooks.*:

PropertyDefaultDescription
enabledtrueMaster switch
max-retries3Max delivery retry attempts
base-retry-delay-ms1000Initial retry delay
retry-multiplier4Exponential backoff multiplier (1s → 4s → 16s → 64s)
delivery-timeout-ms5000HTTP timeout per attempt
approval-base-urlblankBase URL used to build approval action links in MCP webhook payloads
approval-ttl-minutes15TTL for HMAC-signed approval tokens

Every delivery attempt (success or failure) is recorded in the delivery log. The DVARA Flightdeck surfaces this log per webhook so you can debug 502s, timeouts, and signature mismatches.

Flightdeck rereads the active webhook list at most once every five seconds. Delivery uses 16 workers and a queue of 1,000 waiting jobs. When that queue is full, DVARA drops the oldest waiting delivery and increments gateway_webhook_deliveries_dropped_total; alert on any increase because the dropped delivery is not retried.

Payload headers and signing​

Every POST carries three headers:

HeaderPurpose
X-Gateway-Signature: sha256=<hex>HMAC_SHA256(secret, rawBody). Your receiver must verify this before trusting the payload.
X-Gateway-Event: <event-type>The DVARA event type (one of the 12 above). Use this to route on the receiver side without parsing the body.
X-Gateway-Delivery: <uuid>Stable delivery ID. Same value across every retry of the same event, so it doubles as a natural idempotency key.

A reference signature-verification implementation in Python:

import hashlib, hmac

def verify(request, secret):
signature = request.headers.get("X-Gateway-Signature", "")
if not signature.startswith("sha256="):
return False
expected = hmac.new(
secret.encode(),
request.body, # raw bytes — must be pre-parse
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature[len("sha256="):], expected)

The signature is over the raw request body bytes as sent on the wire. If your receiver framework parses and re-serializes JSON before handing it to your code (common in some middleware stacks), capture the raw body upstream — re-serialized JSON will not byte-match and signature verification will fail.

Approval webhooks (MCP)​

When an MCP tool call hits an approval gate, DVARA fires an approval webhook with signed action links so a human approver can click "Approve" or "Deny" directly from a Slack / email message. The links are HMAC-signed bearer tokens with a TTL of approval-ttl-minutes (default 15) and resolve via POST /v1/webhooks/actions/{action}?token=<signed-token>.

Configure approval-base-url to your public gateway URL so the links are clickable from outside your cluster.

Where to manage them​

ActionWhere
Create, list, edit, deleteWebhooks; Flightdeck applies the signed-in user's role and workspace scope
Send a synthetic test eventTest on the webhook's row
Per-webhook delivery logopen the webhook — the delivery log is on its detail view

Use the test endpoint when onboarding a new webhook to validate signature verification on the receiver side before going live.

Error codes​

  • webhook_not_found → HTTP 404, type: not_found_error

  • Observability — Prometheus metrics and the audit event system overview
  • Compliance Reports — SOC2 / HIPAA / GDPR / India RBI / SEBI report generation, which consumes the same audit chain
  • Configuration — full property reference