Whisper · Docs
Health

Health

A stolen token or a copied endpoint cert shouldn't let anyone speak for every device on a hospital's network.

A hospital runs tens of thousands of networked machines built to be trusted, not to prove who they are. The controllers, EHRs and FHIR APIs above them authenticate a claim (a bearer token, a shared credential, a static key, an IP on the right VLAN), never the machine that presents it. Whisper closes that gap with one primitive: a device's address, or a FHIR endpoint's, is its identity. This page is the health front door to the Whisper docs. The full technical library (DNSSEC, DANE, RDAP, the control-plane API) sits one click down the sidebar, identical to whisper.online/docs.

The problem: a flat network of machines that can't prove who they are

Medical devices live 10–20 years against 3–5 years of OS support, so much of the fleet is stranded on end-of-life software it can't patch and can't run an agent on. Roughly 60% of health systems say they can't protect their unpatchable, agentless devices (HIMSS), the single biggest self-identified gap. Those devices sit on a flat, converged IT/OT/IoMT segment where the legacy clinical protocols (HL7v2, unauthenticated DICOM, Modbus) all assume a trusted LAN, and the data layer above them (FHIR, DICOM) leaks through broken object-level authorization: change the patient ID in the request, receive another patient's record.

Because nothing on that network is machine-bound, a stolen secret simply is the device. The kill chain is boringly repeatable: harvest static trust (a hard-coded key, a long-lived token); move laterally to a pump, a monitor, or a PACS that authenticates a claim, not a machine; exfiltrate through FHIR BOLA or an open DICOM port while the egress rotates across clouds and residential proxies, so all the SOC ever logs is a meaningless last IP; then reuse the loot against the next organization, because a credential burned at hospital A is still good against hospital B. Healthcare has been the costliest industry to breach for 14 consecutive years: the average breach cost $7.42M in 2025 and took about 279 days to detect and contain (IBM). The year a clearinghouse-scale compromise cascaded nationally, it exposed on the order of 190M individuals, roughly a third of US records. It is no longer only a data problem: peer-reviewed work on Medicare claims finds in-hospital mortality rises 35–41% for patients already admitted when a ransomware attack begins.

One stolen secret → any device, and every last IP is disposable Stolen token / BOLA = speaks for the device bearer · shared key · VLAN valid EHR / FHIR API HL7v2 · DICOM · SMART one flat, converged segment claim ✓ · machine ✗ enumerate patient IDs & device records: none machine-bound exfil: FHIR BOLA · open DICOM · lateral → pump / monitor / PACS …phoned home through disposable egress: AWS GCP Azure residential swarm SOC logs a meaningless last IP
The health kill chain leans on one thing: a stolen token or a BOLA-shaped request authorizes a claim against a record or a device, never the machine. The egress is disposable too, so the last IP the SOC records was never the attacker.

Detection will always be a step behind a credential that is genuinely valid. The strictly-stronger move is to change what the backend trusts.

The cure: the address is the device, and the endpoint

Shipped & live. Deriving a device or FHIR-endpoint /128 from the key it already holds is in production today. Provision one with the control-plane call below, then verify it from the DNSSEC root with tools already on your machine.

Whisper gives each device, or each FHIR endpoint, a routable IPv6 /128 out of 2a04:2a01::/32 (announced by AS219419). It's derived deterministically from the device's public key (the SubjectPublicKeyInfo of a UDAP server certificate, an IEEE 802.1AR IDevID, a TPM, or a secure-element key), with the FHIR Endpoint.identifier (or the FDA UDI device identifier) as the domain separator. The private key never leaves the box; only its public SPKI is an input. The result is DNSSEC-anchored, DANE-EE 3 1 1 pinned, and RDAP-registered. Anyone can re-derive and verify it with dig.

Endpoint / device key UDAP cert · 802.1AR · TPM secure element · EUI-64 device private key stays on the box only the public SPKI is an input public key + device_id /128 2a04:2a01:1f5::fb1e routable · tenant-bound enumeration-resistant DNSSEC + DANE-EE 3 1 1 A name anyone can verify whisper verify --trustless our API not in the trust path Endpoint.address, DANE-pinned RDAP-registered under AS219419 op:'revoke' → gone worldwide at DNS-TTL
The public key derives the address; DNSSEC + DANE-EE 3 1 1 make it a name anyone can verify without trusting us; one revoke tears it down worldwide: the cross-org off-switch UDAP's community CRLs never delivered at the address layer.

Because the derivation is tenant-bound, the same key under two different organizations yields two unrelated /128s. An outsider cannot link a device or endpoint across a QHIN, an HIE, and its manufacturer. And because the domain separator is the Endpoint.identifier (or the UDI), the identifier alone yields nothing: you cannot go identifier → /128 without the key, there is no enumerable directory, and RDAP and reverse-DNS return the registry object, never the device's whereabouts.

What becomes true the moment a device or endpoint holds one:

Additive, never a replacement. Whisper complements the anchors you already run: UDAP endpoint trust, SMART on FHIR, TEFCA/QHIN identity, 802.1AR IDevID, an OEM's build-time device PKI, ISO/IEEE 11073, and DICOM's optional PS3.15 TLS. It is the publicly verifiable, DNSSEC/DANE-anchored layer on top, anchoring the device↔cloud and endpoint↔endpoint boundary. It never reaches into the HL7v2 or unauthenticated-DICOM traffic between two nodes on the same segment (that's a segmentation and protocol-auth problem), and it does not replace the device's own crypto. An identity is only as forge-proof as the key storage behind it, so a device with no TPM or secure element inherits weaker custody, honestly.

The highest-leverage move in health is what this does for UDAP. UDAP already asserts a strong binding: the identifying URI in /.well-known/udap SHALL match a uniformResourceIdentifier entry in the server certificate's SubjectAltName, and SHALL equal the FHIR base URL. But it is trusted only inside a private community anchor (a TEFCA anchor, a state-HIE anchor) you had to be provisioned with out of band. Publish that exact base-URL↔cert binding as a DANE TLSA record under a DNSSEC-signed name, and any relying party can verify it, even one outside the community, with no anchor pre-provisioned.

UDAP endpoint identity cert SAN URI = FHIR base URL https://fhir.example-health.org/r4 trusted via a PRIVATE community CA (TEFCA / state-HIE anchor) verifiable only inside the community Whisper DANE-pins the same binding DANE-EE 3 1 1 in DNSSEC the base-URL ↔ cert binding, in open DNS revocable at DNS-TTL no anchor to pre-provision Any relying party verifies even outside the community whisper verify --trustless no UDAP anchor required
Whisper doesn't replace UDAP. It publishes the same URI↔key binding UDAP asserts privately as a DNSSEC-signed DANE record, so trust stops being community-scoped. The EUI-64 a point-of-care device already carries can even become the interface-ID half of its /128 directly (RFC 4291): a synthesized angle, not a new identifier to mint.

Provision a device or endpoint identity

Provisioning is one control-plane call over the public API: POST https://graph.whisper.security/api/query with your X-API-Key. Hand it the base64 SPKI and the device_id (the FHIR Endpoint.identifier, its UDAP base URL, or the FDA UDI device identifier) and it returns the deterministic /128 and a WireGuard config for source-bound egress:

CALL whisper.agents({op:'connect', args:{
  tier:'wireguard',
  identity_public_key:'<base64 SPKI of the endpoint/device key>',
  device_id:'https://fhir.example-health.org/r4'   // FHIR Endpoint.identifier (its UDAP base URL); or an FDA UDI, e.g. '00889842093360'
}}) YIELD op, ok, status, result, error
RETURN op, ok, status, result, error

Send it with your key. The heredoc keeps the single-quoted Cypher literals intact, so this runs as-is:

curl -s https://graph.whisper.security/api/query \
  -H "X-API-Key: whisper_live_xxx" \
  -H 'content-type: application/json' \
  --data @- <<'JSON'
{"query":"CALL whisper.agents({op:'connect', args:{tier:'wireguard', identity_public_key:'<base64 SPKI>', device_id:'https://fhir.example-health.org/r4'}}) YIELD op, ok, status, result, error RETURN op, ok, status, result, error"}
JSON
# response
{ "op": "connect", "ok": true, "status": "created",
  "result": {
    "address": "2a04:2a01:1f5::fb1e",
    "fqdn":    "ep-a3f19c2e.fhir.<tenant>.agents.whisper.online",
    "wireguard": { /* peer, keys, allowed-ips */ }
  } }

The call is idempotent, liberal in what it accepts, strict in what it returns: re-running with the same key and device_id returns the same /128; a different device_id for a key already registered on your tenant is a clear 409, not a silent overwrite; a non-string device_id is a 400 that tells you exactly what was wrong, never an opaque 500.

i

A first-class typed --endpoint / --udi argument is on the roadmap. Today, health provisioning is the control-plane call above (which is live); pass your Endpoint.identifier or UDI as device_id. The shipped CLI verbs are whisper verify --trustless, whisper create --register, whisper kill --revoke, whisper policy, and whisper logs; see CLI & one-command.

Verify it yourself, no account

Every health identity is checkable with no key and no login, from the internet's own records. The whisper CLI does the full walk in one call:

whisper verify --trustless ep-a3f19c2e.fhir.<tenant>.agents.whisper.online

 DNSSEC chain valid to the IANA root
 DANE-EE (TLSA 3 1 1) leaf matches the endpoint's key
 RDAP: registered under AS219419 · 2a04:2a01::/32
identity: VERIFIED (our own API was never trusted)

Or reach for the raw records directly. It's the same answer, from stock tools:

# the public verify endpoint: evidence chain in JSON
curl -s https://whisper.online/verify-identity/2a04:2a01:1f5::fb1e | jq
{ "is_whisper_agent": true, "dane_ok": true, "jws_ok": true, "evidence": { /* … */ } }

# the address is the endpoint: forward-confirmed reverse DNS names it
dig -x 2a04:2a01:1f5::fb1e +short
ep-a3f19c2e.fhir.<tenant>.agents.whisper.online.

# the registry object: who holds the address, and under which allocation
curl -s https://whisper.online/ip/2a04:2a01:1f5::fb1e | jq

None of these calls Whisper as an authority: --trustless re-derives the proof against the public DNSSEC root, exactly as any resolver could. This is the second, DNS-anchored proof that complements your UDAP certificate chain: a relying party outside your community can confirm the endpoint without joining it. See Verify an agent for the full keyless check and DANE & TLSA for the pin, byte for byte.

Revoke, worldwide, and govern the egress

A compromised infusion pump, a decommissioned imaging modality, an endpoint rotating out of a QHIN: one call tears down the /128, its PTR, and its DANE pin everywhere at DNS-TTL speed. This is the revocation the health stack lacks at the address layer: UDAP/TEFCA revocation is community-scoped CRL/OCSP; a /128 is revoked independently and publicly, a second orthogonal kill-switch.

CALL whisper.agents({op:'revoke', args:{agent:'2a04:2a01:1f5::fb1e'}})

# after the TTL: dig -x returns nothing, verify returns false
whisper kill --revoke 2a04:2a01:1f5::fb1e

Compromise one endpoint and you've compromised that endpoint, not the exchange. The cross-org credential-reuse failure mode is structurally removed. Short of a full revoke, the same control plane governs what each identity may reach: op:policy and op:firewall set a default-deny egress allow-list per device (permit the QHIN peer and the OTA update host, block everything else, by name, CIDR, or port), which is L3 segmentation enforcement even for the agentless device that can't take a NAC agent; op:budget caps a device's traffic with a kill-switch. It constrains who a device can reach and be reached by, choking C2 and exfil, without an inline OT chokepoint.

And nothing is issued or torn down in the dark. Every mint and every revoke lands in a public, append-only RFC 6962 Merkle transparency log, Ed25519-signed and anchored to Bitcoin via OpenTimestamps: a non-repudiable issuance-and-revocation trail for an FDA §524B postmarket record or a HIPAA audit. Honest status: it is tamper-evident, signed, and Bitcoin-anchored today, but not yet independently witnessed. It speaks the C2SP tlog-witness protocol so an external witness can co-sign.

Attribution: name whoever already scraped you

Identity stops the next forgery; the graph names the operator behind the sessions already in your logs. That attribution survives IP rotation because it fingerprints the operator and the tooling, not the ephemeral egress IP. This is the cross-organization layer the IoMT-visibility tools structurally can't see: their vantage stops at one hospital's edge, and roughly 41% of 2024 healthcare breaches originated with a third-party vendor. Run it as read-only Cypher over the same public API with your key (there is no CLI subcommand for this; it's the graph API directly):

curl -s https://graph.whisper.security/api/query \
  -H "X-API-Key: whisper_live_xxx" \
  -H 'content-type: application/json' \
  -d '{"query":"CALL whisper.identify(\"34.90.x.x\")"}'
# operator fingerprinted across AWS / GCP / Azure; residential swarm collapsed by JA3/JA4

The read-only verbs (identify, origins, walk, variants, history) each return a reproducible, replayable JSON evidence chain your VSOC, PSIRT, and an OCR investigator can replay. More in Graph & cognition.

Lookups: see who's checking your device identity

An identity you can prove is also an identity you can watch. Because every device and endpoint resolves through Whisper's own authoritative DNS and RDAP, the owner can ask who looked: the PTR/AAAA/TLSA resolutions and RDAP accesses against an identity's records, an early-warning tripwire the UDAP private registry never gave you. It reads two ways: as a reconnaissance signal (someone enumerating your endpoints before the exploit lands) and as verification analytics (which QHINs and partners are actually checking your endpoint before they exchange).

# who resolved or RDAP-queried this identity: the owner-facing companion to op:logs
curl -s https://whisper.online/ip/2a04:2a01:1f5::fb1e/lookups | jq

# or over the control plane, with your key
CALL whisper.agents({op:'lookups', args:{agent:'2a04:2a01:1f5::fb1e'}})

Where op:logs shows an identity's own outbound activity, op:lookups shows the interest in it: the reverse-observability half most stacks never expose. Pair it with signed outputs to make a device's telemetry itself non-repudiable, so the numbers a payer or registry settles against provably came from the real device.

What ships today, and what's on the roadmap

We label these honestly so you can plan against them.

Shipped & liveOn the roadmap
Device/endpoint /128 from the device key + device_id (FHIR Endpoint.identifier or FDA UDI), with DNSSEC + DANE-EE + RDAP A first-class typed --endpoint / --udi CLI+API argument (provision via the control-plane call today)
Control-plane provision, verify, revoke, lookups, firewall / budget / policy; the attribution graph and the Merkle transparency log over the public API STIX 2.1 over TAXII export
The Splunk, Microsoft Sentinel and OpenCTI connectors (signed, replayable JSON → CEF / ECS fields) Health-ISAC / FDA-aligned machine-readable JSON export

The integration guides below describe proposed integrations at the FHIR/API and IP boundary, designed to complement the stack you already run (UDAP, TEFCA, your IoMT-visibility platform), not endorsed by any vendor, and never named against a specific HDO or device maker as a breach victim.

The five Health guides

The health story, in depth: each page is self-contained and copy-paste runnable.

The full technical library

Health rides on the same address-is-identity platform as every other agent on the network, so the whole shared library applies here unchanged, and every page has a clean Markdown twin at the same path + .md. Start with these; the rest is in the sidebar.