Skip to content

Event streams

An event stream posts each event a tenant records to an HTTPS endpoint as it happens, so a security team can collect them in a SIEM. Streams are managed in /manage under Settings → Streams, or through the manage API.

A stream has a key, a name, an address, a signing secret, an optional list of actions, and an optional organization. An empty list streams every action. A stream for one organization sends only that organization’s events, so a customer’s activity can go to that customer’s SIEM. createEventStream and rotateEventStreamSecret return the secret once, and it cannot be read again.

Terminal window
curl -s "$MASKS/manage/graphql" -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"mutation { createEventStream(key: \"siem\", name: \"SIEM\", url: \"https://siem.example.com/masks\", actions: [\"session.started\", \"actor.deleted\"]) { secret } }"}'

testEventStream sends a stream.tested event and reports what the receiver answered. archiveEventStream stops delivery and restoreEventStream resumes it.

Each event is a POST with a JSON body.

Field Meaning
id The event’s id, also sent as the Masks-Delivery header.
tenant The tenant’s subdomain.
action The action, such as session.started, also sent as the Masks-Event header.
created_at When it happened, in UTC.
actor The uuid of the account it happened to, or null.
by The uuid of the account that did it, or null.
client The client_id involved, or null.
organization The key of the organization the event belongs to, or null.
ip_address, user_agent Where it came from.
details Fields specific to the action.

Any 2xx response counts as delivered. Events are delivered at least once and may arrive out of order. Use id to discard a repeat.

The Masks-Signature header reads t=<unix time>,v1=<hex>. The value is the HMAC-SHA256, keyed with the stream’s secret, of the timestamp, a period, and the raw request body. Recompute it, compare in constant time, and reject a request whose timestamp is more than five minutes from the current time.

A delivery that gets no 2xx response is attempted up to eight times, with growing delays. After the last attempt, masks records a stream.failed event, which is never streamed. The stream’s lastFailure shows the latest error, and lastDeliveredAt the latest success.

  • An address that is not HTTPS, or that carries a username or password.
  • An address that resolves to a private, loopback, or link-local address. masks checks when the stream is saved and again on every delivery.
  • An action masks does not record.