DocsSecurity
SIEM export
Your audit log, security signals and staff access log as one ordered stream: pulled as NDJSON with a cursor, or pushed to Splunk, Datadog or your own HTTPS endpoint.
On the roadmap — not available yet. The SIEM export is built and in testing, and not deployed. This page describes what it will ship with.
The SIEM export sends your organization's security record to your own logging or SIEM tooling, as one ordered stream of events from three sources: the audit log, the security signals, and the staff access log. You can pull it with a management token (the management API is on the Startup plan and up), or have INFRO push it to Splunk, Datadog or an HTTPS endpoint of yours (every plan).
Events
Every event carries id (<stream>:<id>, stable, for de-duplication), stream (audit, signals or staff_access), organization_id and occurred_at (UTC, to the microsecond). Then, by stream:
| Stream | Fields |
|---|---|
audit | action, actor (type, id, label), target (type, id), ip, user_agent, metadata, and access_change (reason, severity) when the entry widened access, or null. |
signals | Each security.* signal: event_type, severity, status, scope (kind, id), title, sentence, figures and console_path. Sent once, as it was first raised, with its status at the time of export: a later acknowledgement, or a warning upgraded to critical, is not sent again. |
staff_access | kind, method, route, description, operator_role, operator_ref, status, count and last_at, as the staff access log shows them. |
Events are ordered by time, then by stream, then by id, so a page never repeats or skips one. An event is exported once it is 60 seconds old: a record written at one instant can be saved a moment after one written later, and waiting keeps the stream from stepping past it. The stream is append-only, like the audit log.
Pull
GET /manage/v1/security/export returns application/x-ndjson: one event per line.
streamsstring- Comma-separated:
audit,signals,staff_access. Default all three. cursorstring- Resume after the last event of a previous page: the value of its
X-INFRO-Next-Cursorheader, unchanged. Not withsince. sincestring- Without a cursor, start at this ISO 8601 time, at most 400 days ago. Default 24 hours ago.
limitinteger- Events per page, 1 to 1,000. Default 500.
- Headers:
X-INFRO-Next-Cursor(where the next page starts; keep it even when a page is empty),X-INFRO-Has-More(truewhen more events are ready now) andX-INFRO-Export-Events(the events in this page). - Poll with the last cursor you were given. A cursor names a position, not a time, so polling with it never loses an event.
- The token needs
security:read, andaudit:readas well when theauditstream is included, which it is by default; its creator needs the roles that read the Security screen and, for the audit stream, the audit log. A project-restricted token is refused with403. 400invalid_requestfor a cursor INFRO did not issue, an unknown stream,cursorandsincetogether, or asincemore than 400 days ago.- Each stream reaches back as far as its own records are kept: staff access 400 days, signals and the audit log as their own pages say.
curl -sD headers.txt https://api.infro.io/manage/v1/security/export?streams=audit,signals \
-H "Authorization: Bearer $INFRO_MANAGEMENT_TOKEN" > events.ndjson
grep -i x-infro-next-cursor headers.txtPush
A destination is where INFRO sends the stream itself. Every five minutes, INFRO sends each enabled destination what is new since it last succeeded: up to three batches of 500 events a run. An organization can have up to five.
| Kind | You give | INFRO sends |
|---|---|---|
splunk_hec | url (your HTTP Event Collector, e.g. https://splunk.example.com:8088/services/collector/event) and token | POST with Authorization: Splunk <token>, one HEC event per line: {time, host: "infro", source: "infro", sourcetype: "infro:<stream>", event}. |
datadog_logs | datadog_site (datadoghq.com, us3.datadoghq.com, us5.datadoghq.com, datadoghq.eu, ap1.datadoghq.com, ap2.datadoghq.com or ddog-gov.com) and api_key (a 32-character Datadog API key, not an application key) | POST https://http-intake.logs.<site>/api/v2/logs with DD-API-KEY, a JSON array of {ddsource: "infro", service: "infro", hostname: "infro", ddtags: "stream:<stream>,organization_id:<id>", date, message, infro: <event>}. |
https | url. INFRO issues the signing secret (whsec_…) and shows it once. | POST of NDJSON (application/x-ndjson) with INFRO-Signature and INFRO-Event-Count. |
- Every request carries
User-Agent: INFRO-SIEM/1. An HTTPS batch is signed like INFRO's webhooks:INFRO-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<body>">with the destination's secret; verify it as the webhooks page shows, over the raw body. Rotating the secret replaces it at once. - A destination starts from the moment it is created; use the pull export for anything earlier.
- The URL must be a public HTTPS address. It is checked when you save it and again before each send. INFRO never follows a redirect and waits 10 seconds for an answer.
- The position moves on only when the destination answers 2xx. A failed batch is sent again on the next run, so a receiver can see an event twice: de-duplicate on
id. - Each failure is recorded with a reason you can act on ("refused the credential (status 401)", "no answer within 10 seconds"), never the receiver's response. After 20 failures in a row the destination is turned off; turning it on again resumes from where it stopped.
- The token, API key or signing secret is encrypted at rest, bound to the destination, and never shown again: the console shows its last four characters.
Destinations API
Through the console session. Everyone who opens the Security screen lists destinations with GET /console/security/siem-destinations; owners, admins and Security members add, change and remove them. Members limited to projects are refused, and changes are refused while the organization is held or locked for a lapsed plan.
namestringrequired- 1 to 80 characters.
kindstringrequiredsplunk_hec,datadog_logsorhttps.streamsstring[]- Any of
audit,signals,staff_access. Default all three. urlstring- Splunk and HTTPS only.
tokenstring- Splunk only: the HTTP Event Collector token.
api_keystring- Datadog only.
datadog_sitestring- Datadog only.
POST /console/security/siem-destinationsreturns201withdestinationandsigning_secret(the HTTPS secret, shown this once;nullfor the other kinds). A sixth destination is refused with400invalid_request, codesiem_destination_limit.PATCH /console/security/siem-destinations/{id}takesname,enabled,streams,url,token,api_key,datadog_site, orrotate_secret: true(HTTPS only, which returns the newsigning_secret). Changing a Splunk destination'surlneeds itstokenin the same request (400credential_requiredotherwise), so a stored token is never sent to a new address.DELETEremoves it. An unknown id is404resource_not_found.- A destination shows
id,name,kind,enabled,streams,url,datadog_site,credential_last4,delivered_through(the newest event delivered),last_delivered_at,last_attempt_at,last_error,consecutive_failures,created_atandupdated_at. - Each change is in the audit log (
siem_destination.created,siem_destination.updated,siem_destination.deleted). Adding a destination, or pointing one at a new URL or site, is listed as an access change on the Security screen: your security record now goes somewhere new.
A destination is your own tool, chosen and contracted by you, like your AI providers: INFRO sends it what you configured and nothing else.