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.
How it works
Section titled “How it works”Configuration source
Section titled “Configuration source”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 }}Batch buffer
Section titled “Batch buffer”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.
Retry behaviour
Section titled “Retry behaviour”If a flush attempt fails (network error, non-2xx response), the sink retries up to 3 times with exponential backoff:
| Attempt | Delay before retry |
|---|---|
| 1st retry | 1 second |
| 2nd retry | 2 seconds |
| 3rd retry | 4 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.
Fail-open
Section titled “Fail-open”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.
Event emission
Section titled “Event emission”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.
Splunk HEC configuration
Section titled “Splunk HEC configuration”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.
Policy bundle schema
Section titled “Policy bundle schema”{ "siem_config": { "type": "splunk", "endpoint": "https://splunk.corp.example.com:8088", "token": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "index": "arbitex_audit", "enabled": true }}| Field | Required | Description |
|---|---|---|
type | Yes | "splunk" |
endpoint | Yes | Splunk HEC base URL. The sink appends /services/collector/event automatically. |
token | Yes | HEC authentication token. Sent as Authorization: Splunk <token>. |
index | No | Target Splunk index. Omit to use the HEC token’s default index. |
enabled | Yes | Set to true to activate the sink. |
HEC payload format
Section titled “HEC payload format”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 prerequisites
Section titled “Splunk prerequisites”- 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).
Microsoft Sentinel configuration
Section titled “Microsoft Sentinel configuration”Events are formatted as a JSON array for the Sentinel Data Collection Rule (DCR) Log Ingestion API.
Policy bundle schema
Section titled “Policy bundle schema”{ "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 }}| Field | Required | Description |
|---|---|---|
type | Yes | "sentinel" |
dce_endpoint | Yes | Data Collection Endpoint URL (from the DCR overview in Azure Portal). |
dcr_id | Yes | Immutable DCR resource ID (begins with dcr-). |
stream_name | Yes | Custom log stream name configured in the DCR (e.g. Custom-arbitex_audit_CL). |
tenant_id | Yes | Azure AD tenant ID for the app registration. |
client_id | Yes | App registration (service principal) client ID. |
client_secret | Yes | App registration client secret. |
enabled | Yes | Set to true to activate the sink. |
Authentication
Section titled “Authentication”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.
DCR setup checklist
Section titled “DCR setup checklist”- Create a Log Analytics workspace (or use an existing one).
- Create a custom table (
arbitex_audit_CL) in the workspace. - Create a DCR with a stream mapping
Custom-arbitex_audit_CL→ your custom table. - Create an app registration with the Monitoring Metrics Publisher role on the DCR.
- Paste the DCE endpoint URL, DCR immutable ID, and stream name into the
siem_configblock.
Elasticsearch configuration
Section titled “Elasticsearch configuration”Events are delivered via the Elasticsearch Bulk API in NDJSON format.
Policy bundle schema
Section titled “Policy bundle schema”{ "siem_config": { "type": "elastic", "endpoint": "https://my-elastic-cluster.example.com:9200", "index": "arbitex-audit", "token": "ApiKey base64encodedapikeyhere==", "enabled": true }}| Field | Required | Description |
|---|---|---|
type | Yes | "elastic" |
endpoint | Yes | Elasticsearch base URL (including port). |
index | Yes | Target index name. |
token | Yes | Encoded API key. Set as Authorization: ApiKey <token>. |
enabled | Yes | Set to true to activate the sink. |
Bulk API payload
Section titled “Bulk API payload”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.
Admin API: SIEM status
Section titled “Admin API: SIEM status”The Outpost exposes a sink status endpoint on the admin API (port 8301, localhost-only):
GET /admin/api/siem/statusAuthorization: Bearer <admin-token>Response fields:
| Field | Type | Description |
|---|---|---|
sink_type | string | splunk, sentinel, elastic, or null if unconfigured |
enabled | bool | Whether the sink is active |
events_sent | int | Cumulative count of successfully delivered events since Outpost start |
events_failed | int | Cumulative count of events dropped after retry exhaustion |
last_error | string|null | Last error message, or null if no recent errors |
last_flush_at | string|null | ISO 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"}SIEM status card — admin UI
Section titled “SIEM status card — admin UI”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.
See also
Section titled “See also”- 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.