Developer documentation
SIEM forwarding
Last reviewed 31 August 2026
All docs
Send every CAIN decision to the security tools your team already watches: Splunk, Cortex XSIAM, or any HTTPS endpoint that accepts JSON. Each decision is forwarded as it is recorded, with its verdict, its stages and its signed digest, so the event in your SIEM can be checked against the decision record format.
Forwarding is off until a workspace owner turns it on, per destination. It sends your workspace's decisions to a third party, so each destination is opt-in, https only, and authenticated with that collector's own token.
Splunk (HTTP Event Collector)#
Create an HEC token in Splunk, then:
curl -s https://cainstudio.online/fabric/webhooks \
-H "X-API-Key: $CAIN_API_KEY" -H 'content-type: application/json' \
-d '{"url":"https://splunk.example.com:8088/services/collector/event",
"format":"splunk_hec", "auth_token":"<your HEC token>",
"events":["decision.recorded"], "description":"SOC Splunk"}'
Each event arrives as {"event": {...}, "sourcetype": "cain:decision.recorded", "source": "cain42", "time": <epoch>} with Authorization: Splunk <token>.
Cortex XSIAM (HTTP log collector)#
In Cortex XSIAM, create an HTTP log collector with the JSON log format and copy its API key. The collector URL has the form https://api-<your tenant>/logs/v1/event:
curl -s https://cainstudio.online/fabric/webhooks \
-H "X-API-Key: $CAIN_API_KEY" -H 'content-type: application/json' \
-d '{"url":"https://api-<your tenant>/logs/v1/event",
"format":"xsiam", "auth_token":"<collector API key>",
"events":["decision.recorded"], "description":"Cortex XSIAM"}'
Each event is one JSON object followed by a newline, sent with the collector key in the Authorization header.
> Tested against: a local receiver that checks the request shape. Not yet tested against a live > Cortex XSIAM tenant. If your collector shows a different header in its sample request, tell us at > support@cainstudio.online and we will match it.
Any HTTPS endpoint#
Leave out format (it defaults to cain) to receive the signed JSON envelope that all CAIN webhooks use. Verify each delivery with the signing secret returned once at creation: HMAC-SHA256 over <timestamp>.<raw body>, compared with the v1 value of the CAIN-Signature header. Reject deliveries whose timestamp is more than 5 minutes old.
Events#
| Event | Sent when |
decision.recorded | every recorded decision: the SIEM feed |
decision.blocked | a decision that an enforcing stage blocked |
approval.requested / approval.resolved | an action is held for a person, then approved or denied |
killswitch.engaged / killswitch.released | the workspace kill switch changes |
A decision.recorded event carries: decision_id, created_at, verdict, blocked, enforcing, halted, principal_id, agent_id, service, path, chain_id, outcome, the stages (name, verdict, enforcing), and digest, record_key_id and record_signature.
How forwarding behaves#
- Never slows or fails a decision. Delivery runs after the decision is recorded, detached from it.
- Retries up to 4 attempts with backoff, then records the failure. An endpoint that fails 20 times in
a row is paused (not deleted); see GET /fabric/webhooks/deliveries.
- Cannot be aimed inside our network. The hostname is resolved and every address checked before the
destination is accepted and again before each attempt. Private, loopback and cloud-metadata addresses are refused, the connection goes to the address that was checked, and redirects are not followed.
- Secrets stay put. The collector token and the signing secret are never returned by any endpoint
after creation.
Manage destinations#
curl -s https://cainstudio.online/fabric/webhooks -H "X-API-Key: $CAIN_API_KEY" # list curl -s https://cainstudio.online/fabric/webhooks/deliveries -H "X-API-Key: $CAIN_API_KEY" # recent deliveries curl -s -X DELETE https://cainstudio.online/fabric/webhooks/<endpoint_id> -H "X-API-Key: $CAIN_API_KEY"