SIEM integration
MaestroHub audits every action — every role grant, every denied access, every ownership change, every impersonation. UC36 (GET /audit/export) streams that audit trail into your SIEM in a format your existing collectors already parse.
Which format?
Point your SIEM at the format its ingest pipeline is already built for. No custom parsers, no schema mapping — the connector setup on your side collapses to "poll this URL."
| Your SIEM | Format | Doc |
|---|---|---|
| Splunk, Splunk Cloud, QRadar, ArcSight, Sentinel, LogRhythm | CEF | Splunk HEC setup |
| Elastic Stack, Elastic Security, OpenSearch, Chronicle, Wazuh | ECS | Elastic Agent setup |
| Datadog, Sumo Logic, New Relic, Grafana Loki, Cribl Stream | NDJSON | Datadog HTTP setup |
| Compliance auditor with Excel | CSV | Ad-hoc CSV export |
The three things every setup needs
- An OAuth2 client credentials pair. The collector authenticates as itself — no user session. The client's granted scopes must include
audit_log:export. - A base URL.
https://<your-maestro>/api/v1/audit/export. - A poll cadence. 60 seconds is our recommendation — freshness within one minute, negligible load. Every documented SIEM connector supports this.
The endpoint at a glance
GET /api/v1/audit/export
?from=2026-07-21T00:00:00Z
&to=2026-07-21T01:00:00Z
&format=cef | ecs | ndjson | csv
&cursor=<opaque token from previous response>
&limit=1000
Authorization: Bearer <access_token>
Required. from and to — the export endpoint refuses to open a body without a time window. This is deliberate: an unbounded export would let a compromised token siphon the entire audit history in a single call. A window every collector renews on each poll matches how every SIEM pipeline is built anyway.
Response headers.
| Header | Meaning |
|---|---|
Content-Type | application/x-ndjson · text/csv · text/x-cef |
X-Audit-Next-Cursor | Present if more records follow — feed on next poll. Absent = end of window. |
X-Audit-Records-Exported | Records committed to this page, resolved before the body streams. On a rare mid-stream failure the body can be shorter than this count — the authoritative per-call count is on the recursive audit_log.exported event. |
Content-Disposition | Attachment header for ndjson/csv (browser download). Absent for cef/ecs — SIEM collectors treat attachments as file downloads. |
Rate limits
The endpoint token-buckets requests per caller. A well-configured collector (60-second poll, 1000-record batches) never hits the limit. A runaway collector — a config-drift accident polling at 1 Hz — is throttled with 429 Too Many Requests before reaching the DB. Retry with backoff.
Correlation IDs
Every record carries a correlation_id — the same value you'd see on the OpenTelemetry trace for the request that produced the action. If you ship traces and audits into the same SIEM, one search reconstructs "what did request req_9f3a7c2b do?" across audit events, HTTP logs, and traces.
Recursive audit
Every call to /audit/export produces an audit record of its own — action audit_log.exported, actor set to the caller, resource type audit_log, detail carrying the format and record count. "Who pulled our logs?" is answerable inside the tamper chain, not just in web-server access logs.
Which admin can grant this?
Per UC35 permissions boundary — only a caller whose own permission set covers audit_log:export can grant it onward. In the built-in catalog:
- Organization.Admin — grants it inside the org.
- Security.Admin — grants it inside the org (their governance mandate covers it).
- Compliance.Auditor — bundle it in with
audit_log:readfor the "SOC 2 evidence" workflow. - System.Admin — grants it anywhere (holds
*).