Skip to main content
Version: 3.0 (next)

Splunk HEC — CEF ingest from MaestroHub

Poll /audit/export from Splunk's HTTP Event Collector or the Modular HTTP Input. Records arrive as CEF and land in your existing CEF sourcetype without a custom parser.

1. Create an OAuth2 client for the collector​

In MaestroHub:

  1. Settings → Identity & Access → OAuth2 clients → New client.
  2. Grant type: Client Credentials.
  3. Scopes: audit_log:export (nothing else — the SIEM collector is a machine and needs nothing else).
  4. Copy the client ID and client secret. Store the secret in Splunk's credential vault.

2. Fetch an access token​

curl -s -X POST https://<your-maestro>/api/v1/oauth2/token \
-d grant_type=client_credentials \
-d client_id=$MAESTRO_CLIENT_ID \
-d client_secret=$MAESTRO_CLIENT_SECRET \
-d scope=audit_log:export \
| jq -r .access_token

Splunk's HEC integrations refresh the token on their own cadence. See Splunk docs — Modular Input token refresh for the reference config.

3. Configure the modular HTTP input​

inputs.conf:

[maestrohub_audit://main]
endpoint = https://<your-maestro>/api/v1/audit/export
params = format=cef&from=${last_cursor_timestamp}&to=now&cursor=${last_cursor}&limit=1000
method = GET
auth_type = bearer
token = ${maestrohub_access_token}
interval = 60
sourcetype = cef
index = security_audit

${last_cursor} is Splunk's checkpoint variable — the modular input persists it across polls. On the first poll, it's empty; subsequent polls send the previous response's X-Audit-Next-Cursor.

4. Set the sourcetype extractor​

props.conf:

[cef]
SHOULD_LINEMERGE = false
LINE_BREAKER = ([\r\n]+)CEF:
TRUNCATE = 10000
KV_MODE = auto

Splunk's out-of-the-box CEF extractor handles the header + extension parsing. The KV_MODE=auto line applies to the extension section.

5. Validate​

Search:

sourcetype=cef | head 20

You should see recent audit events with signature=<action>, suser=<actor>, duser=<subject>, cs1=<correlation_id>, cs2=<org_id>, cat=iam|authentication|configuration.

Field reference​

CEF fieldMaestro sourceNote
actActione.g. role.assigned
suserActor.Email (falls back to Actor.ID)The actor identity
duserSubjectThe user acted upon
srcActor.IPAddressOrigin IP
requestClientApplicationActor.UserAgentTruncated at 1024 chars
catCategoryECS-aligned: iam, authentication, configuration, process
outcomeResultsuccess · failure · denied
cs1 (label correlationId)CorrelationIDOpenTelemetry trace id
cs2 (label orgId)OrgIDMulti-tenancy pivot
cs3 (label impersonator)ImpersonatorIDWhen set — admin impersonating a user
cs4 (label resource)ResourceType/ResourceIDThe resource operated on

Troubleshooting​

Splunk shows cef events but the extractor didn't split fields. Check props.conf — the extractor stanza name must match the sourcetype in inputs.conf (both cef).

429 in Splunk's modular-input log. The collector polled faster than the rate limit. Extend interval to 60 (from a lower value) and — for large windows — set limit=1000 explicitly.

Response body is empty but X-Audit-Records-Exported: 0. No records in the requested window. The endpoint response is well-formed; this just means the poll caught an empty window. Splunk skips the batch and re-polls on the next interval.

Bearer token returned 401. The access token expired. Splunk's HEC refresh cycle is typically 30 minutes; check that the token-refresh script is running.