How the sensor works
The whole pipeline on one page: seven layers and one thread. A routable /128 identity at the anchor, a forward-first sensor above it, a calm brain with two schedulers, on-host detection engines, an internet-scale graph verdict, policy expressed against the identity, and two response levers. Running through all seven: everything is checkable from outside. This is the map. Each layer links to its own guide.
The shape of it: seven layers, one thread
Most EDR runs its brain and its response on the very box it is trying to protect. Whisper is built the other way around, and the reason it can be is unusual: Whisper is also the DNS and the network the endpoint lives on. The host sensor collects and does only cheap, local, observe-only deciding; the expensive analytic work happens off-host against the Whisper graph, which has usually already scored the destination because it served the DNS query; and the control that matters at incident time, ending a compromised host, lives on our infrastructure rather than on the host. That split is why the sensor runs at about 2.6% of one core, and why containment survives a fully owned box.
/128. Layer 7 has a lever in both places, and the one that survives a compromised box is the off-host one. The green thread is the part nobody else has: each layer's claim can be checked from outside, keyless.Layer 1: identity, the anchor
Every host and every agent is issued a real, routable IPv6 /128 from our own space (2a04:2a01::/32, announced by AS219419), with DNSSEC-anchored reverse DNS, a DANE-EE key pin and a public RDAP object. It is not an opaque vendor sensor ID; it is an internet identity a stranger can check with dig, delv and openssl, with Whisper's API nowhere in the trust decision.
That identity is what the other six layers hang off. Attribution keys to it (reverse DNS answers "which agent made this connection"), egress sources from it, policy is written against it, and containment revokes it. The sensor itself is optional: a device that will never run a kernel agent (a PLC, a printer, a contractor laptop, an ephemeral AI agent) still enrolls a /128, still verifies keyless, and can still be contained from the network. The seven-proof keyless verify chain, persistence across upgrades, and the connectivity tiers are in The /128 identity.
Layer 2: the sensor, forward-first by construction
The default build is pure Go and GPL-free: an exec collector on the kernel NETLINK process-connector, a file collector on fanotify, a both-directions socket collector on NETLINK_SOCK_DIAG, and a DNS-question tap on AF_PACKET. A lower-latency eBPF exec and per-connect tap is opt-in behind a -tags ebpf build. Everything the sensor sees rides one telemetry stream in four vocabularies: exec, file, conn, dns, plus a fifth detection kind that findings ride back on.
The architectural rule that shapes the whole layer: the hot path always forwards telemetry downstream before any detector looks at it. Detectors attach as taps that fold a judgement on the side, or as observers that side-consume copies; by construction, detection can never delay, drop or alter telemetry. The sensor is also kernel-graceful and fail-open: a tap that cannot attach on a given kernel is dropped and the rest keep running. The package behind this carries 2,112 test functions and 93 fuzz targets across 216 test files. Mechanism by mechanism, with each tap's blind spot, in Telemetry collectors and The Linux sensor.
Layer 3: calm, two schedulers and a measured 1%
Scheduling is the key to any telemetry system, and Whisper runs two of them. The on-host governor is an autonomous, cgroup-bounded scheduler whose only job is to be invisible: the hot path (the taps and the local verdict) never rides it at all; only deferrable work does. When the host is idle it leans in; when the network is also demonstrably quiet it opens a burst window of up to 10 parallel workers; when the host is busy it collapses to urgent-only. A self-meter reads the sensor's own cgroup so calm is a measured property, a graded circuit breaker sheds work before the host ever feels it, a coalescer folds churn storms (a package manager touching thousands of files) into one submission, and every heavy worker runs at nice 19 with idle I/O priority. A starvation floor guarantees past-deadline work still lands, so calm never becomes blind.
The fleet planner is the second scheduler, computed off-host where compute is free: per-/128 advisory hints derived from the graph's behavioral history. A clean history deepens deferral; a suspicious one holds bursts; a critical finding requests immediate attention. It is advisory by construction: the host pulls hints, a missing or dead planner leaves the host on its standalone baseline, and no hint can touch the hot path or exceed the cgroup ceiling. Strike the entire backend column and the host is still calm.
Above the levers sits a disposition system: the sensor's temperament is a point on a two-axis plane (how hard it hunts, how much it tells you), with ten named presets from "barely there" to the silent-and-relentless SOC preset, and one move on that plane deterministically re-projects all 18 tuning levers. A safety floor no preset or override can cross keeps CPU at or under the 25% cgroup quota, caps memory, and pins autonomous response to observe.
25% of a core is the ceiling we promise never to need; a live capture today, root-privileged in a cgroup scope matching the production SLA, settled at 2.61% of one core and 16 MB, inside a 150 MB soft budget and a 250 MB hard cap. The full scheduler, the enforced floor and the persona plane are in Calm footprint & SLA.
Layer 4: the on-host brain, observe-only
On top of the stream sits the local verdict layer: twelve behavioral engines (ransomware behavior, process injection, the write-exec-connect event chain, a critical-config integrity watch, hash verdicts, the per-process trust tier) plus two real, industry-standard rule engines running natively on the host: a Sigma evaluator built on the SigmaHQ ecosystem's rule format, matching all four event vocabularies, and a YARA-X byte-signature scanner (VirusTotal's engine) over settled executables and anomalous memory. Together they name 91 on-host ATT&CK techniques with 79 bundled Sigma rules; the default build ships zero YARA rules, since that engine is a build-time opt-in. Both engines accept operator-supplied rules.
Every engine is observe-only: it emits a detection event onto the stream, it never blocks, kills or quarantines on its own. And every engine deliberately tops out below certainty, leaving the final word to the graph layer beneath it: a local confidence of 0.90 with a graph verdict on the destination beats a local 1.0 with no context. Engine by engine, with real rule names and false-positive screens, in Detection engines.
Layer 5: the graph, three graphs and one join key
The reason detection is better here, not just different, is that the brain runs against an internet-scale graph the host could never hold, and the join into that graph exists because Whisper serves the DNS. Three graphs are in play.
Graph one is on the host. The sensor folds its stream into a bounded per-endpoint graph: processes, files, sockets, domains, executables, with edges for spawn, exec, connect and resolve. Its rarest edge is process to the DNS name it looked up, drawn by attributing the port-53 question to the querying PID, with a blind spot: DoT and DoH bypass the tap and are simply not observed. Graph two is the internet. The Whisper security graph, 7.52B nodes and 38.6B relationships, scores every destination for ownership, ASN, prevalence and threat band, off the host. Graph three is the join. Both sides key the same canonical, lowercased host name, so the on-host evil.example node and the internet-graph evil.example node are the same string by design, and the verdict pins straight onto the local picture.
The join runs in both directions. At resolve time, the resolver scores the name against the graph and the verdict band rides back with the DNS answer. At read time, the per-endpoint view collects the host's destination names and pins the graph's band / owner / country / asn / prevalence columns onto them verbatim, in one batched, absolutely fail-open call. And in the exfiltration correlator, a connect is joined to the nearest preceding resolve across different processes, strongest key first: name equality, then the shared source-port flow key (the same ephemeral port on the resolve and the connect, even when a shared system resolver did the lookup), then same-process timing. The fused chain is scored 0 to 200: temporal proximity plus graph-verdict severity, so a chain to a newly-registered, rarely-seen destination outranks a chain to a popular benign host at the same lag. No graph signal simply means a pure temporal score, never a claim of malice.
The verdict itself is a re-runnable Cypher with a provenance receipt, and it is keyless to check:
# a keyless graph verdict, no account, no API key
$ curl -s https://graph.whisper.online/api/query \
-H 'content-type: application/json' \
-d '{"query":"CALL whisper.assess(\"google.com\")"}'
{"columns":["host","label","band","sub_labels","signals","coverage","evidence",
"verdictScore","isThreat","threatSources"],
"rows":[{"host":"google.com","label":"benign-allowlisted","band":"NONE",
"sub_labels":[],"signals":[],"coverage":"known-clean",
"evidence":["coverage:known-clean","band:NONE","host-class:unknown","popularity-rank:1"],
"verdictScore":0.0,"isThreat":false,"threatSources":0}]}
Graph-first means the graph gets the first opinion; where it has none, resolution falls through to real DNS. Fail-open is the load-bearing promise: if the graph is slow or unreachable, the sensor and the resolver keep serving and lose visibility, never availability. No graph call sits in a blocking hot path, so a bad day at the backend can reduce what you see but cannot take the host down. That is the opposite trade from an EDR whose brain is a kernel driver on the box.
Layer 6: policy, written against the identity
Because the identity is an address we allocated and the egress is a plane we run, governance is expressed against the /128 and enforced off the agent's host. A compromised agent cannot disable its own firewall, because the firewall is not on its box. Five policy shapes, all riding one control verb (whisper.agents) with the caller's API key:
- Firewall. A per-
/128allow/deny rule-set the egress plane consults once per connection: destination IP, CIDR, host (exact or any-subdomain) or port, first match wins, up to 1,000 rules. Every write lands in the durable containment audit trail. Live. - Graded egress. Every process is bucketed into a trust tier, T0 known-bad up to T4 verified, and each tier maps to an egress freedom on an ordered ladder:
none < dns-only < mediated < direct < unrestricted. The endpoint's worst observed process tier drives the decision, so a confirmed-bad process drags its host's egress down to DNS-only, decided in the network. Tier refusals, per-/128byte caps, budget caps with an immediate kill, and windowed per-run allowlists are all live-enforced; the policy read-back labels every namespace asenforcement=liveorenforcement=stored, and a stored token is never presented as live policy. - Geography. Two planes. Resolution-time geo bundles (
geo:deny:…/geo:allow:…, deny wins on conflict) are evaluated live per resolution against the graph. Jurisdiction-tagged allocation, where the address itself encodes its country and publishes it via RDAP and a geofeed, is opt-in and disabled by default; until a tenant enables it, allocation is untagged and byte-identical to before. - Per-device policy. The same policy verb takes an optional device selector, so one call governs a whole tenant or a single
/128. Per-device overrides can only escalate, never downgrade a graph-critical block, and a revoked address drops its override so a recycled/128inherits nothing. Live. - Nested identities. Agents nest: a parent agent spawns sub-agents, each getting its own governed
/128, and the fleet topology reports the tree. Enforcement composes down the measured transit chain (who is actually egressing through whom, not who claims to be): a child's effective firewall is its own rules intersected with every live ancestor's, most restrictive wins, and a kill-switched ancestor cuts every descendant behind it. Revoking the parent severs the subtree's transit in one move. Depth is bounded and the walk fails closed past the bound. Live.
/128; enforcement walks the measured transit chain, so killing or revoking the parent denies every descendant behind it at their next connection. Nobody chases the children individually.The calm personas of layer 3 are themselves a policy shape: the same per-device selector that scopes a firewall can scope a disposition, clamped quieter-only against the tenant floor.
Layer 7: two levers, near and far
Response is two layers, and you want both.
The near lever is an on-host respond tier: armed and opt-in, it can stop a process, quarantine a file, restart a service or patch a package over a poll-only channel, with per-action audit, an allowlist and no shell. It defaults off. A host that opted into observe telemetry has not opted into action; you arm it deliberately. Where it acts it is reversible where reversal makes sense (the process freeze is a reversible SIGSTOP).
The far lever is the off-host kill-switch. One control-plane call revokes the /128: reverse DNS and forward resolution go to authenticated NXDOMAIN, the RDAP record shows no assignment, the DANE pin drops, and traffic that sources from that /128 stops. Because the lever lives on our infrastructure, not on the host, it holds even when the host is fully compromised and the local sensor is dead: a host-only agent's off-switch lives on the machine it has just lost. The two levers, the safety posture, and the reproducible revoke walkthrough are in Containment.
The boundary. On-host action is opt-in, not the default. The C2 anomaly auto-contain ladder is gated and observe-first today; we say held, not blocked, while a decision runs in observe. The adversary-proof lever is the off-host revoke, and it is live.
The thread: verify it yourself
Running through all seven layers is the property that makes the rest believable: the claims are checkable from outside, keyless. The identity chain (PTR, DNSSEC, DANE, RDAP) verifies with stock tools. The graph verdict re-runs as the Cypher above. Revocation verifies as an authenticated NXDOMAIN a stranger can fetch. And the evidence trail is anchored in a signed, append-only log with an independent witness cosignature and a Bitcoin timestamp. We call that trail tamper-evident, deliberately not "publicly verifiable", while the witness set is still small; the receipts and their limits are in Compliance evidence.
/128, the keyless identity chain (four checks), copyable evidence, and the who-resolved feed. Real capture, demo fleet, host web-edge-01.