The decentralized SOC

A SOC is usually built around one assumption: every log line reaches a central place, and that place decides what is an attack. Everything downstream inherits that assumption, including the bandwidth bill, the detection latency, and the blast radius when the correlator is unreachable.

MarlinOS starts from the opposite end. The host that produced the log parses it, enriches it, matches it, and scores the entity behind it, before the line is written to disk. Edges then compare notes with their peers. What travels is a verdict, and what makes a detection is quorum across the mesh rather than one machine's view of everything.

// locality

Decide where the evidence is

Parse, CTI, Sigma, and entity scoring run in the rsyslog hot path on the collector. The parsed event is already in memory, so the verdict costs a match, not a round trip.

// quorum

Agree without a correlator

Edges gossip evidence about scored entities into a shared counter. An alert needs at least two independent sources, so it cannot fire from one node's view however strong that view is.

// autonomy

Survive the link

An offshore vessel, a DMZ collector, an air-gapped floor. The uplink is how verdicts are delivered, not how they are produced.

Two shapes for the same job

The difference is not the detection content. Both shapes can run the same Sigma corpus. The difference is where the decision happens, and therefore what has to be true for detection to work at all.

where the decision happens raw lines vs scored verdicts
Centralized log shipping compared with decentralized edge scoring On the left, four collectors forward every raw line to a single SIEM correlator, which must see everything for detection to work. On the right, four edges each score locally, gossip signals to their peers, and forward verdicts to an operator console. 01 / centralized Ship every line. One correlator decides, so it must receive everything. every line, all the time 1 2 3 4 forwarders SIEM correlator must see everything Detection latency is pipeline latency. The WAN link is a prerequisite, not a convenience. Cost scales with log volume, not with risk. 02 / decentralized Score at the source. Each edge decides locally, then peers agree by quorum. SOC console verdicts only 1 2 3 4 peer gossip no broker each edge scores locally The verdict exists before the line is written. Link down: detection and correlation continue. No single box has to see everything.
Both sides can run the same Sigma corpus. What changes is the precondition: the left needs the link and the central box, the right needs neither to keep detecting.

Quorum: weak signals, one detection

The interesting adversary does not trip a rule on one host. They leave a small trace on several: a handful of failed logins here, one port touch there, an odd DNS pattern somewhere else. Each is under any sane threshold on its own. Raise the sensitivity and you drown in false positives; leave it alone and nothing fires.

Each edge deposits what it scored, and peers accumulate those deposits into a shared per-entity counter. The composite score is a property of the mesh: it can cross the detection threshold even though no participant ever saw enough to fire on its own. The requirement is structural, not a heuristic. An alert needs the accumulated confidence, a minimum number of hits, and at least two distinct sources, and an entity's source count is only raised by a remote peer's reinforcement, never by the local deposit.

pheromone quorum entity 203.0.113.66 · tenant: north
Four edges contributing to one composite entity score Four edges each observe a weak signal about the same IP address. Each deposit raises the entity's shared composite score. No single contribution reaches the detection threshold on its own, but the accumulated score crosses it. composite score One entity, four partial views. score threshold 7.0 0 10 detected 1 edge-01 3 failed logins +1.8 2 edge-02 one port touch +1.6 3 edge-03 periodic DNS +1.9 4 edge-04 off-hours auth +2.3 sum 7.6 / thr 7.0
No contribution reaches 7.0 on its own; the highest is 2.3. The detection belongs to the mesh, not to any node in it. Signals decay, so a score that stops being fed falls back under the line. Illustrative, RFC 5737 documentation IPs.

When the link dies

Every deployment we care about has a link that is not always there. Offshore racing means days without satellite. A DMZ collector may be firewalled to a one-way path. An industrial floor may be air-gapped by policy. In the centralized shape those are outages of detection. Here they are outages of delivery.

degraded uplink local detection continues, verdicts spool
Site behaviour while the uplink to the SOC console is down Three edges at a site gossip continuously among themselves. The uplink to the off-site SOC console goes down: verdict delivery stops and the local retry buffer grows, while local detection and gossip continue unaffected. When the link returns, the buffer flushes and normal delivery resumes. availability Delivery is not detection. SOC console off site verdict uplink link down site · dmz · vessel 1 edge-01 2 edge-02 3 edge-03 local gossip never stops buffer retained
While the uplink is down the site keeps parsing, matching, scoring and reaching quorum. Only delivery is deferred. Be precise about the buffer, though: retry is an in-memory bounded queue that drops oldest under a long outage, so what always survives is the durable OCSF copy each edge writes locally, not the delivery queue.

What actually leaves the edge

Forwarding raw logs becomes a policy choice rather than a requirement. That is the practical consequence of the whole design, and it is where the bandwidth and storage numbers come from.

PlanePayloadScope
Verdicts Scored entity, detector output, and OCSF 1.8.0 projection. Sigma rule identity rides along for promoted signals: correlations, and single-event rules at high or critical severity. Edge to console, or edge to an existing SIEM.
Sigma partials $!sigma_contribution: a JSON array, one entry per matching correlation rule. Each carries corr_id, event time, group values and its partial (count, numeric, seen_mask or value). Hashed onto one owner in a configured peer ring. See mmsigma.
Pheromone Evidence about a scored entity, added into a shared per-entity counter, plus liveness. Gossip across tenant peers over SWIM and PlumTree, run by the immesh rsyslog module.
Raw lines The original log, unchanged. Optional. Kept local, or forwarded when policy or retention says so.

What this is not

The design buys locality and availability. It does not buy a global view for free, and pretending otherwise is how these architectures get a bad name.

// and the boring part

Something still has to manage the nodes

A mesh of edges is only as good as your ability to configure and observe them. We built Fleet for that: enroll, apply, drift, WireGuard, one YAML platform per host role. It is a control plane, not the product, and it is deliberately small.

How Fleet works →