The console

wakeweb is where an operator meets the mesh. It receives scored entities from every edge and gives an analyst the three things a decision needs: what fired, what the entity has been doing, and what this asset is supposed to be doing. There is a free-form log explorer too, but the index it searches lives on each edge: the console fans a query out across per-edge DuckDB stores rather than holding a central lake.

The loop, not the dashboard

A dashboard ends at the screen. Some of what an analyst decides here travels back down to the edges and changes what they do next. Not all of it, and the difference matters: see what actually travels below.

analyst loop decisions are pushed back to the edges
The five-step analyst loop in the WAKE console A cycle: a scored entity arrives as a signal, the analyst triages it, reads its context, and records a verdict. Some verdicts become policy that is pushed to the edges, changing the signals that arrive next; triage state itself stays in the console. wakeweb operator console 01 Signal scored entity 02 Triage ack or dismiss 03 Context what is this asset 04 Verdict real or noise 05 Policy whitelist / suppress applied on every edge closed loop Triage changes what fires next. Whitelist and suppression reach every edge. Triage state stays in the console.
Step 05 is what separates the console from a viewer, but only three actions actually reach an edge: whitelist, context tag, and profile suppression. Acknowledge, dismiss and watchlist are console-local.

Triage

The queue is chronological, newest first, with sortable columns. It is the entities view, not this one, that is ordered by threat score. What does encode agreement is structural rather than cosmetic: an entity's source count is only incremented by remote reinforcement, never by its own edge's deposit, and an alert requires at least two sources. An alert therefore cannot fire from a single edge's evidence, whatever that edge saw.

Triage queuetenant: north · last 24h
EntityWhat firedScoreEdgesState
203.0.113.66 credential pivot + slow scan 8.75 new
198.51.100.23 beaconing, 300s period 6.43 new
user:svc-backup off-hours auth, role incongruence 4.92 acked
192.0.2.140 first-seen destination 3.22 acked
host:edge-04 volume deviation vs EMA 1.81 dismissed
Illustrative layout, not a screenshot of a shipped table: the columns and rows here are for explanation. EDGES is the independent reporter count. Representative data, RFC 5737 documentation IPs.

What the analyst gets

The verdict, with its lineage
Which Sigma rules matched and their MITRE ATT&CK technique, which behavioral detectors fired, and what CTI said. One caveat worth stating: mmsigma does set a remote flag on a correlation fire built from a peer's partial, but nothing reads it back, so it is not surfaced here today.
The entity profile
EMA classification per protocol and port against a weekly seasonal profile: 168 hour-of-week slots, so 09:00 Monday is compared with other Monday mornings rather than with a rolling average. Per-entity baselining is a separate mechanism (rolling 1h windows with mean plus k·sigma, and Welford population thresholds). See the profile panel on the pipeline page.
Context, not just telemetry
What the asset is for, who owns it, what it is expected to talk to. A backup account authenticating at 03:00 is either the whole finding or entirely uninteresting, and only context decides which.
Threat intelligence
CTI channels and their IOC coverage, so an analyst can see whether a hit came from a feed they trust. Enrichment happens on the edge in mmenrich; the console is where the sourcing is auditable.
Who is actually reporting
SWIM liveness and per-node signal rates. An edge that stopped reporting is a detection gap, and it should be as visible as an alert.

Detection health

A ruleset degrades quietly. A rule that fires on everything trains analysts to ignore it, and a rule that never fires looks exactly like coverage you never had. Neither condition raises an alert, because neither is an attack. So waked profiles its own Sigma layer on a timer and writes the verdict where both an operator and ordinary log-based alerting will find it.

That headline is the honest state of a detection layer: nothing is currently producing signal, and one rule is producing noise. It is the kind of thing a SOC usually discovers a quarter later, during a review.

How a rule gets called noisy

The sample
The profiler reads the tail of the enriched event stream, 50 MB by default, and counts hits per rule id. It does not re-run the matcher: the verdicts are already stamped on each event by mmsigma, so this is aggregation over a file rather than a second detection pass. That is what makes it cheap enough to run on an edge.
The ratio
The denominator is every event in that window, matched or not. A rule matching more than 2% of everything the collector saw is classed FP-suspect and reported as noisy. The guidance text calls that traffic benign, which is an assumption: the sample is live production traffic, not a curated clean corpus. On a host actually under attack, read the number accordingly.
Silent rules
Reported separately, as a coverage question rather than a noise problem: either the log source is not flowing, or the rule should be retired. Two qualifiers: the test is "produced no promoted signal", not "matched nothing", and it only covers rules that could promote (correlations, and single-event rules whose verdict is escalate). An ordinary alert-tier rule that never escalates is expected to be quiet here and is deliberately not listed.
Active detections
The headline count is the number of distinct Sigma rules and correlations that produced at least one promoted signal in the last 24 hours, excluding the noisy ones. It counts rules, not alerts, so a single loud rule cannot inflate it.
Advisory, never automatic. Nothing in this path disables, rescopes, or recompiles a rule. The only thing it automates is the measurement. Deciding that a rule is wrong stays an engineering judgement, and it lands through the same policy step as any other triage decision.

The check runs on edge nodes with the behavioral engine enabled, first a few minutes after startup and then every six hours. The console surfaces the same data on demand as a Detection Health panel on the rules page, grouped into noisy, active, and silent, with an edge selector; waked also exposes it as a sigma.health call so a collector can ask any edge directly.

Decisions that travel

Three console actions change what an edge does. They do not go through fleet: wakeweb never dials out, collectors connect to it on port 7949, and policy rides WAKE's own asset distribution channel over TLS, landing with a SIGHUP to rsyslog.

  analyst action  (console)
       |
       +-- whitelist entity  ---+
       +-- context tag       ---+--> custom_cti -> binary overlay
       |                        |
       |                        v
       |                  collector RPC :7949  (edge dials in)
       |                        |
       |                        v
       |                  asset distribution (TLS) -> SIGHUP rsyslog
       |                        |
       |                        +-- mmenrich  overlay checked BEFORE the
       |                        |             .thrt DB: whitelist skips CTI
       |                        |             and GeoIP; a tag sets $!tags
       |                        +-- mmwake    score clamped to 0.01, below
       |                                      the 0.3 OCSF projection floor
       |
       +-- profile suppression --> self.configure RPC -> CONFIG_PUSH
                                    -> waked behavioral engine rewrites
                                       the signal to severity=info

What does not travel

Acknowledge, dismiss and watchlist are console state. Dismiss deletes one signal row on the one edge that owns it, because signal ids are edge-local; it does not recompute any score, there or anywhere else. Triage state lives in the console's own SQLite table and no edge reads it. The watchlist is a display list in the same database.

A whitelist does not silence the mesh, and that is deliberate. A whitelist is an assertion about threat intelligence: this indicator is not a hit. It clamps the entity's score at the source, so the entity stops becoming a verdict. The behavioral deposits in the C path (scan, brute force, credential, exfil, C2) are not gated on it, so they still fire and still gossip. Otherwise whitelisting a host would mute the mesh for it, which is exactly wrong if that host is later compromised.

So there are two levers, and picking the wrong one is the common mistake:

Whitelist
The CTI lever. Stops an indicator being treated as a threat-intel hit. Behaviour is still observed, still scored behaviourally, and still gossiped.
Profile suppression
The behavioural lever. Pushed to every edge over the same channel, it rewrites matching signals to informational severity with suppressed_by: profile_matrix. This is the one to reach for when a signal type is simply not interesting for a class of asset.

Access

The console does not hold its own user database. It delegates authentication to fleet over the local fleetd broker socket, so operator accounts are managed in exactly one place and there are no per-app service tokens to rotate. That socket carries login and tenant topology only; it is not how policy reaches an edge. A broker outage fails closed.

Authorization today is tenant scoping, not a read/write split: a session is clamped to its tenant, and within that scope any authenticated session can whitelist, suppress or dismiss. A viewer-style role exists in the UI but is not yet enforced as read-only, so treat console access as operator access. Mutations are recorded in the console's own audit table.

An analyst workbench over the same token-gated API is built and not yet in production. emerging

Where it runs

The soc-console platform is the reference deployment: a Linux host running rsyslog with the WAKE modules, two waked instances (an edge on 7948 and a collector on 7949), wakeweb, and fleetd. It aggregates from every edge in the fleet.

For an existing SOC, the alternative is no console at all: have your SIEM pull waked's /ocsf feed, a token-gated NDJSON endpoint served over GET. Note the direction, since it is the opposite of most integrations: waked ships nothing outbound and the collector does not dial your SIEM. It binds to loopback by default, so exposing it is a deliberate act.