Skip to content

Outpost SIEM direct sink

The Outpost SIEM direct sink (SiemDirectSink) forwards audit events from the Outpost process directly to a SIEM endpoint without routing events through the Arbitex Platform relay. Use this feature when:

  • Your security policy prohibits audit data from transiting Arbitex Cloud.
  • You require the lowest possible latency between event generation and SIEM ingestion.
  • You are operating in an air-gapped network segment that cannot reach the Platform.

Three targets are supported: Splunk HTTP Event Collector (HEC), Microsoft Sentinel Data Collection Rule (DCR), and Elasticsearch Bulk API.

If your Outpost has Platform connectivity and no data-residency constraint, the Platform SIEM connectors in SIEM integration are the simpler path — they require no Outpost configuration.


The SIEM direct sink is configured exclusively via the policy bundle siem_config block — not environment variables. This ensures the same configuration reaches all Outposts without per-host overrides.

{
"siem_config": {
"type": "splunk",
"endpoint": "https://splunk.corp.example.com:8088",
"token": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"index": "arbitex_audit",
"enabled": true
}
}

Events are accumulated in a local buffer before being flushed to the SIEM endpoint. A flush is triggered when either condition is met:

  • The buffer reaches 100 events, or
  • 10 seconds have elapsed since the last flush.

This batching reduces per-event network overhead without significantly delaying delivery.

If a flush attempt fails (network error, non-2xx response), the sink retries up to 3 times with exponential backoff:

AttemptDelay before retry
1st retry1 second
2nd retry2 seconds
3rd retry4 seconds

After 3 failed attempts the batch is discarded and the failure is logged. events_failed in the status response increments for each discarded batch.

If the SIEM endpoint is unavailable, the Outpost does not block requests. Audit events that cannot be delivered are dropped after the retry exhaustion. Local audit chain integrity (AUDIT_HMAC_KEY) is unaffected — the HMAC-chained local log continues regardless of sink state.

After each audit event is written to the local HMAC-chained log, logger.py calls SiemDirectSink.buffer_event(). The buffer operation is fail-open — a sink exception does not interrupt the main request path.


Events are formatted as Splunk HEC JSON payloads with sourcetype: "arbitex:ocsf" — events are formatted in OCSF (Open Cybersecurity Schema Framework) rather than raw JSON.

{
"siem_config": {
"type": "splunk",
"endpoint": "https://splunk.corp.example.com:8088",
"token": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"index": "arbitex_audit",
"enabled": true
}
}
FieldRequiredDescription
typeYes"splunk"
endpointYesSplunk HEC base URL. The sink appends /services/collector/event automatically.
tokenYesHEC authentication token. Sent as Authorization: Splunk <token>.
indexNoTarget Splunk index. Omit to use the HEC token’s default index.
enabledYesSet to true to activate the sink.

Events are batched and delivered as a newline-delimited series of HEC JSON objects in a single POST:

{"event": {"class_uid": 4001, "time": 1741478400123, "org": {"uid": "org_abc123"}, "actor": {"user": {"uid": "usr_xyz789"}}, ...}, "sourcetype": "arbitex:ocsf", "source": "arbitex-outpost"}
{"event": {"class_uid": 4001, ...}, "sourcetype": "arbitex:ocsf", "source": "arbitex-outpost"}

The sourcetype is always arbitex:ocsf. Create this sourcetype in your Splunk instance if it does not already exist.

  • Splunk Enterprise 8.x+ or Splunk Cloud.
  • HTTP Event Collector enabled (disabled by default in fresh installs).
  • An HEC token scoped to the target index.
  • Network connectivity from the Outpost host to the Splunk HEC port (default 8088).

Events are formatted as a JSON array for the Sentinel Data Collection Rule (DCR) Log Ingestion API.

{
"siem_config": {
"type": "sentinel",
"dce_endpoint": "https://myworkspace-XXXX.eastus-1.ingest.monitor.azure.com",
"dcr_id": "dcr-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"stream_name": "Custom-arbitex_audit_CL",
"tenant_id": "00000000-0000-0000-0000-000000000000",
"client_id": "00000000-0000-0000-0000-000000000000",
"client_secret": "your-app-secret",
"enabled": true
}
}
FieldRequiredDescription
typeYes"sentinel"
dce_endpointYesData Collection Endpoint URL (from the DCR overview in Azure Portal).
dcr_idYesImmutable DCR resource ID (begins with dcr-).
stream_nameYesCustom log stream name configured in the DCR (e.g. Custom-arbitex_audit_CL).
tenant_idYesAzure AD tenant ID for the app registration.
client_idYesApp registration (service principal) client ID.
client_secretYesApp registration client secret.
enabledYesSet to true to activate the sink.

The sink authenticates to the DCR ingestion API using the OAuth 2.0 client credentials flow (tenant_id, client_id, client_secret). Tokens are fetched from https://login.microsoftonline.com/{tenant_id}/oauth2/token.

The app registration must have the Monitoring Metrics Publisher role on the DCR resource.

  1. Create a Log Analytics workspace (or use an existing one).
  2. Create a custom table (arbitex_audit_CL) in the workspace.
  3. Create a DCR with a stream mapping Custom-arbitex_audit_CL → your custom table.
  4. Create an app registration with the Monitoring Metrics Publisher role on the DCR.
  5. Paste the DCE endpoint URL, DCR immutable ID, and stream name into the siem_config block.

Events are delivered via the Elasticsearch Bulk API in NDJSON format.

{
"siem_config": {
"type": "elastic",
"endpoint": "https://my-elastic-cluster.example.com:9200",
"index": "arbitex-audit",
"token": "ApiKey base64encodedapikeyhere==",
"enabled": true
}
}
FieldRequiredDescription
typeYes"elastic"
endpointYesElasticsearch base URL (including port).
indexYesTarget index name.
tokenYesEncoded API key. Set as Authorization: ApiKey <token>.
enabledYesSet to true to activate the sink.

Events are delivered as NDJSON Bulk API requests:

{"index": {"_index": "arbitex-audit"}}
{"class_uid": 4001, "time": 1741478400123, "org": {"uid": "org_abc123"}, ...}
{"index": {"_index": "arbitex-audit"}}
{"class_uid": 4001, ...}

A single POST to {endpoint}/_bulk delivers the accumulated batch. The sink checks the errors field in the Bulk API response; any shard-level errors increment events_failed.


The Outpost exposes a sink status endpoint on the admin API (port 8301, localhost-only):

GET /admin/api/siem/status
Authorization: Bearer <admin-token>

Response fields:

FieldTypeDescription
sink_typestringsplunk, sentinel, elastic, or null if unconfigured
enabledboolWhether the sink is active
events_sentintCumulative count of successfully delivered events since Outpost start
events_failedintCumulative count of events dropped after retry exhaustion
last_errorstring|nullLast error message, or null if no recent errors
last_flush_atstring|nullISO 8601 UTC timestamp of the last successful flush

Example response:

{
"sink_type": "splunk",
"enabled": true,
"events_sent": 14821,
"events_failed": 3,
"last_error": null,
"last_flush_at": "2026-03-12T14:31:05Z"
}

The Outpost admin UI (http://localhost:8301) includes a SIEM status card in the main Dashboard panel. It displays:

  • Sink type and enabled state
  • Events sent and events failed counters
  • Last flush timestamp
  • Last error message (if any)

Parallel operation with Platform audit sync

Section titled “Parallel operation with Platform audit sync”

The direct sink runs as an independent background task. It does not replace the audit sync worker that forwards events to the Arbitex Platform — both pipelines receive the same events and operate concurrently.

When both paths are active:

  • Each event is delivered once to your SIEM directly and once through the Platform relay (which may forward to Platform-configured SIEM connectors).
  • In air-gapped mode (PLATFORM_SYNC_ENABLED=false), only the direct sink path is active.

  • SIEM integration — Platform-managed SIEM connectors (Splunk, Sentinel, Elastic, Datadog, Sumo Logic).
  • SIEM admin API — Manage per-org SIEM connector config via the Platform admin API.
  • Audit log — Audit event fields, tamper-evident chain, and retention policy.