Skip to content

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:

StreamFields
auditaction, actor (type, id, label), target (type, id), ip, user_agent, metadata, and access_change (reason, severity) when the entry widened access, or null.
signalsEach 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_accesskind, 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-Cursor header, unchanged. Not with since.
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 (true when more events are ready now) and X-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, and audit:read as well when the audit stream 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 with 403.
  • 400 invalid_request for a cursor INFRO did not issue, an unknown stream, cursor and since together, or a since more 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.
Pull the export
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.txt

Push

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.

KindYou giveINFRO sends
splunk_hecurl (your HTTP Event Collector, e.g. https://splunk.example.com:8088/services/collector/event) and tokenPOST with Authorization: Splunk <token>, one HEC event per line: {time, host: "infro", source: "infro", sourcetype: "infro:<stream>", event}.
datadog_logsdatadog_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>}.
httpsurl. 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.
kindstringrequired
splunk_hec, datadog_logs or https.
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-destinations returns 201 with destination and signing_secret (the HTTPS secret, shown this once; null for the other kinds). A sixth destination is refused with 400 invalid_request, code siem_destination_limit.
  • PATCH /console/security/siem-destinations/{id} takes name, enabled, streams, url, token, api_key, datadog_site, or rotate_secret: true (HTTPS only, which returns the new signing_secret). Changing a Splunk destination's url needs its token in the same request (400 credential_required otherwise), so a stored token is never sent to a new address. DELETE removes it. An unknown id is 404 resource_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_at and updated_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.

↑ ↓ navigate↵ open/ anywhere in docs