n8n

In obserae: create a Webhook output with a signing secret. There is no n8n output type — the n8n node runs inside n8n, and its trigger listens to that webhook.

That sentence is the one people miss. Looking for “n8n” in the obserae output list will not find anything, and nothing is wrong.

Where to get itnpm: n8n-nodes-obserae
Alert contractobserae.alert/2
SOAR profile1.0.0
Requiresn8n 1.x

The node is versioned against those two contracts, never against an obserae release: adding a field to the alert is not a breaking change and does not need a new node.

Install

Community nodes (self-hosted n8n): Settings → Community Nodes → Install → n8n-nodes-obserae. Restart n8n.

Credential

obserae API takes your instance’s base URL and an API token. Mint the token in obserae under Identity & Access → Users → + New token, on a user whose group holds sessions:read, alerts:read, alerts:ack, cartography:read and rules:read — see a token for a playbook. Click Test: it calls GET /api/status and must go green.

The trigger — receiving alerts

  1. Add the obserae Trigger node and copy its production URL.
  2. In obserae, Connectors → Outputs → + New output, type Webhook, URL = that address, and set a signing secret.
  3. Paste the same secret into the node.

The node recomputes the HMAC over "<timestamp>.<rawBody>", compares it in constant time, and answers 401 with no detail when it does not match — an error naming which part was wrong tells a prober how close they are. It reads the raw body before parsing: re-serialising JSON changes the bytes and the signature would never match again.

It refuses to run at all with no secret configured. A trigger that accepts an unverified body is an endpoint anyone on the internet can start your incident response with.

What reaches the workflow is the alert document plus five fields lifted from the headers, so a branch can route without parsing:

signatureVerified: true
eventType:         alert.fired | alert.resolved | alert.acknowledged | test
deliveryId:        unique per delivery — deduplicate on it
schemaVersion:     obserae.alert/2
instanceId:        which obserae sent it

The node — asking obserae questions

Eight actions, covering the inbound half of the SOAR profile:

ResourceOperationCalls
EnrichmentLookupGET /api/enrichment/lookup — one address or up to 50
ContextGet Host ContextGET /api/context/host
ContextGet PeersPOST /api/context/peers
PolicyCheckPOST /api/policy/check
AlertGet ManyGET /api/alerts
AlertGetGET /api/alerts/{id}
AlertSet StatusPOST /api/alerts/{id}/status
IndicatorExportGET /api/indicators

Three details are worth knowing before building on them.

Enrichment takes a batch. Put several addresses in the field, separated by commas, and they go out as one call. Above 50 obserae refuses the request rather than truncating it — a workflow handed part of its batch would decide on part of its evidence.

As Of is how you look at the past. Every window (1h, 24h, 7d) is a closed vocabulary, because it is what bounds the scan on the server. To ask what a host was doing when an alert fired, keep the window and set As Of to the alert’s fired_at. To compare against a baseline, move As Of back a week and keep everything else identical.

The Indicator action carries If-None-Match. Store the ETag you got, send it back on the next poll, and act only on a 200.