Skip to contentSkip navigation

Pivoting Examples

Worked cross-layer traversals — from a domain to the network that routes it, an IP to its jurisdiction, an actor to its techniques. Examples, not an exhaustive list.

Graph Schema
On this page (12)

Pivoting Examples Documentation

The point of a pre-joined graph is the chain — walking from one layer to the next in a single query. This page collects the pivots you will reach for most, each with the traversal it encodes and a runnable query. These are examples, not the complete set: any two connected labels can be joined, and the Connection Types page is the full menu of edges you can compose your own chains from.

Every pivot below starts from an anchored {name: "..."} lookup. That is what turns a chain into an instant traversal instead of a scan — see Best Practices for why.

Domain → network owner

Who hosts this domain, and on whose network? Resolve the host to an IP, follow the IP to its announced prefix, and follow the prefix to the AS that routes it.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

This four-hop chain — HOSTNAME → RESOLVES_TO → IPV4 → ANNOUNCED_BY → ANNOUNCED_PREFIX → ROUTES → ASN → HAS_NAME → ASN_NAME — is the single most-run query on the graph. It needs an API key; sign in to run it — there is no card to enter.

IP → jurisdiction

Geolocate an address by chaining its GeoIP city to the city's country.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

Anycast and large-CDN IPs often lack a city. When LOCATED_IN returns nothing, read the owning ASN's country instead: (:ASN)-[:HAS_COUNTRY]->(:COUNTRY).

ASN → physical footprint

Where does a network actually sit? A network is present in facilities directly, and reaches more facilities through the exchanges it joins.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

The direct form is (:ASN)-[:AS_PRESENT_AT]->(:FACILITY). A large network can be present in hundreds of facilities, so anchor the ASN.

Submarine cable → landing → facility

Trace a subsea cable from the sea to the building it terminates in.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

Domain → mail servers

NAMESERVER_FOR and MAIL_FOR point server → domain, so traverse them backwards to answer "what serves this domain".

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

Domain → WHOIS

Who registered this domain? Three registration edges fan out from the hostname: HAS_REGISTRAR to the registrar, HAS_EMAIL to the WHOIS contact email, and REGISTERED_BY to the registrant organization.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

These edges point domain → record — the opposite of MAIL_FOR above — so pivoting from a WHOIS email to every domain it registered traverses HAS_EMAIL backwards: (:EMAIL)<-[:HAS_EMAIL]-(:HOSTNAME). A shared contact can sit behind many domains, so bound it with WITH e LIMIT 3 before expanding. WHOIS contacts are sparse and current records are often redacted, so expect gaps.

Do not anchor on an organization's display name.

ORGANIZATION names are stored normalized and lowercase, so the string you copied out of a WHOIS record is not the key. Measured 2026-08-09 against production: {name: "Cloudflare, Inc."} returns zero rows at HTTP 200 with no error, while {name: "stripe"} — the form the graph actually stores — returns its row in 4 ms.

Reach an organisation through an edge first: anchor on a hostname, IP or ASN and traverse REGISTERED_BY to it, then read the name off that row before you use it as an anchor anywhere else. A zero-row result on an ORGANIZATION name lookup is almost always the casing, not an absence of data.

Read coverage before band. Only known-clean — coverage: known-clean. In coverage, no malicious evidence. licenses the word "clean"; no-data — coverage: no-data. Not in coverage. This is not a verdict — nothing was looked at. means unknown, which is a different thing again; malicious-evidenced — coverage: malicious-evidenced. In coverage, with positive evidence of malice. and ambiguous — coverage: ambiguous. In coverage, and the evidence points both ways. mean there is evidence, whatever the band says. whisper.explain does not return coverage at all. Full contract: Coverage — what we looked at.

IP → threat feeds → categories

Enrich an indicator: which feeds flagged it, and what categories those feeds belong to.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

Bound the feed list with WITH f LIMIT 10 before expanding to categories. The full catalog and taxonomy are on the Threat Feeds & Categories page. For a scored verdict with per-feed evidence in one call, prefer explain() over walking these edges by hand.

Actor → technique → tactic

Map a threat actor to the MITRE ATT&CK techniques it uses, and roll each technique up to its tactic.

WhisperGraph carries the MITRE ATT&CK knowledge base as graph structure — 7,527 USES_TECHNIQUE edges from ACTOR to ATTACK_PATTERN and 872 USES_TACTIC edges, across 1,218 actors and 712 techniques. This is a curated reference layer, not Whisper's own attribution. It reflects what public reporting has mapped, not what Whisper observed. The graph draws no edge from an actor to live infrastructure: ATTRIBUTED_TO holds 4 edges on production. These queries return technique and tactic rollups. They do not attribute anything.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

ACTOR names are case-sensitive. Group a technique under its tactic with (:ATTACK_PATTERN)-[:USES_TACTIC]->(:ATTACK_PATTERN) — a rollup of the same curated mapping, with the same caveat above it. Convergence between two actors is a lead about the reporting, not proof about the infrastructure, and an absent mapping is no-data — coverage: no-data. Not in coverage. This is not a verdict — nothing was looked at., never evidence of absence.

RPKI authorization

Check what a route-origin authorization covers — which AS it authorizes, for which prefix, down to which length, and which trust anchor signed it.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

A ROA carries no name. Read it through asn, prefix, maxLength, trustAnchor, validFrom, and validUntil.

Prefix → cloud region

Place a prefix inside the cloud region that operates it.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

Cloud-region coverage is partial, so swap the seed and this usually returns nothing. The seed above is an AWS range, chosen because it answers. A zero-row result means Whisper has not mapped that prefix to a tracked region — never that the prefix is not in a cloud.

Prefix → MOAS conflict

A prefix announced by more than one origin AS is the fingerprint of a hijack or route leak.

Live · graph.whisper.security
read-only Cypher

Copy as
Open it in the Console

Multi-origin state shifts as routes change, so any specific example prefix may settle. The query shape is what stays useful.

Compose your own

These chains are building blocks. Because the layers are pre-joined, you can splice them — resolve a domain to an IP, geolocate the IP, and pull its threat feeds in one query; or pivot from a WHOIS email to every domain it registered to their shared ASNs. A longer chain needs a key; keep each virtual edge as an explicit single hop and anchor the start. The Connection Types reference lists every edge you can chain, and Best Practices covers the rules that keep a deep traversal fast.