Skip to content
Back to home

§ SIEM

Microsoft Sentinel Integration

Ship every agent trace into a Log Analytics custom table via the Azure Monitor Logs Ingestion API. Sentinel analytics rules turn agent policy violations into incidents in the queue your SOC already works.

§ 01

How it works

Execlave authenticates to Azure AD with client credentials, then POSTs batched trace events to a Data Collection Endpoint (DCE), routed by a Data Collection Rule (DCR) stream into a Log Analytics custom table. Sentinel sits on the workspace, so the table is immediately queryable in KQL and usable in analytics rules.

Export runs post-commit in a dedicated worker — it never adds latency to enforcement. The Azure client secret is envelope-encrypted at rest, and AAD tokens are cached until shortly before expiry to avoid a token round-trip per batch.

§ 02

Azure setup

One-time setup in your Azure tenant: an app registration, a custom table, and a DCR that grants the app ingest rights.

1 · App registration (client credentials)

In Microsoft Entra ID → App registrations → New registration, create an app (e.g. execlave-siem). Under Certificates & secrets, create a client secret. Note the Tenant ID, Client ID, and the secret value.

2 · Custom table + DCR

In your Log Analytics workspace: Tables → Create → New custom log (DCR-based). Name the table ExeclaveTraces_CL, create (or reuse) a Data Collection Endpoint, and define the schema below. Azure creates a DCR with a stream named Custom-ExeclaveTraces_CL.

{  "name": "ExeclaveTraces_CL",  "columns": [    { "name": "TimeGenerated", "type": "datetime" },    { "name": "TraceId", "type": "string" },    { "name": "ParentTraceId", "type": "string" },    { "name": "OrganizationId", "type": "string" },    { "name": "AgentId", "type": "string" },    { "name": "AgentUuid", "type": "string" },    { "name": "Status", "type": "string" },    { "name": "Model", "type": "string" },    { "name": "PromptTokens", "type": "int" },    { "name": "CompletionTokens", "type": "int" },    { "name": "TotalTokens", "type": "int" },    { "name": "CostUsd", "type": "real" },    { "name": "DurationMs", "type": "real" },    { "name": "Environment", "type": "string" },    { "name": "SpanType", "type": "string" },    { "name": "SpanName", "type": "string" },    { "name": "ErrorType", "type": "string" },    { "name": "ErrorMessage", "type": "string" },    { "name": "SessionId", "type": "string" },    { "name": "UserId", "type": "string" },    { "name": "AgentName", "type": "string" },    { "name": "AutonomyLevel", "type": "string" },    { "name": "AgentStatus", "type": "string" },    { "name": "IdpBound", "type": "boolean" }  ]}

3 · Grant ingest rights

On the DCR (not the workspace): Access control (IAM) → Add role assignment → Monitoring Metrics Publisher → select the app registration from step 1. Role assignments can take a few minutes to propagate.

4 · Configure the integration in Execlave

Go to Settings → Integrations and add a Microsoft Sentinel destination:

FieldValue
Tenant IDEntra tenant GUID.
Client IDApp registration client GUID.
Client secretSecret value from step 1 (stored encrypted).
DCE endpointLogs ingestion URI, e.g. https://my-dce-x1y2.westeurope-1.ingest.monitor.azure.com
DCR immutable IDdcr-... value from the DCR overview (JSON view).
Stream nameCustom-ExeclaveTraces_CL (from step 2).

Test connection acquires an AAD token for the Logs Ingestion scope — it validates tenant, client, and secret without writing data.

§ 03

Analytics rules (KQL)

Create these under Sentinel → Analytics → Scheduled query rule. Each one maps a governance signal to a Sentinel incident.

Policy violation burst

Governance outcomes (policy_blocked, flagged_for_review, limit_exceeded) are first-class statuses — alert on them directly rather than parsing error strings.

// Analytics rule: policy violation burst per agent// Schedule: every 15m over a 15m window · severity: MediumExeclaveTraces_CL| where Status in ("policy_blocked", "flagged_for_review", "limit_exceeded")| summarize Violations = count(), Tools = make_set(SpanName, 10)    by AgentId, Status, Environment, bin(TimeGenerated, 15m)| where Violations >= 5

Agent error-rate spike

// Analytics rule: agent error-rate spike vs 24h baseline// Schedule: every 1h over a 24h window · severity: LowExeclaveTraces_CL| where TimeGenerated > ago(24h)| summarize Errors = countif(Status in ("error", "timeout")), Total = count() by AgentId| extend ErrorRate = todouble(Errors) / todouble(Total)| where Total >= 20 and ErrorRate > 0.25

Prompt-injection / abuse hunting

Save as a hunting query: one end-user repeatedly driving agents into blocked tool calls across sessions is the classic injection fingerprint.

// Hunting query: one user driving repeated blocked tool calls// (classic prompt-injection / agent-abuse pattern)ExeclaveTraces_CL| where Status == "policy_blocked" and SpanType == "tool"| summarize BlockedCalls = count(), Agents = make_set(AgentId, 5),    Tools = make_set(SpanName, 10) by UserId, SessionId, bin(TimeGenerated, 1h)| where BlockedCalls >= 5| order by BlockedCalls desc
§ 04

From incident to closure

When a rule fires, the Sentinel incident carries the TraceId and AgentId your analyst needs to pivot into Execlave — full trace timeline, tamper-evident audit chain, and agent passport. The complete triage-to-closure runbook is the incident response workflow.