# Embedded

**A secret extracted from one flash dump shouldn't be able to speak for every device you ship, and a fleet's identity shouldn't die with a vendor console.**

A device backend authenticates a *claim*: a password, an API key, a certificate chain. It never authenticates the silicon on the other end. Whisper closes that gap with one primitive: the device's address *is* its identity. This page is the embedded front door to the Whisper docs. The full technical library (DNSSEC, DANE, RDAP, the control-plane API) sits one click down the sidebar, shared verbatim with [whisper.online](https://whisper.online/docs).

## The problem: copyable credentials, and the console behind them

Embedded fleets authenticate with what manufacturing could afford. Generation zero was the default password, and Mirai showed at 600k-device scale what that costs; ETSI EN 303 645 and the UK PSTI Act have since outlawed it. Generation one is the shared secret in firmware: an API key or a line-wide certificate, where one flash dump (UART, JTAG/SWD, or a desoldered SPI part) yields a genuine credential for the whole product line. Generation two is per-device X.509 into a cloud provisioning service: genuinely better, and still verifiable only *inside that tenant*, revoked through CRL/OCSP machinery verifiers soft-fail past, and anchored to a console whose lifetime is shorter than the hardware's; when Google Cloud IoT Core retired in August 2023, console-anchored fleets had to re-home their identity mid-life. The root cause is constant across all three: [OWASP broken authentication / BOLA](https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/). The credential authenticates a claim, never the *device*.

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

## The cure: the address is the device

> **Shipped & live.** Deriving a device `/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 a routable IPv6 `/128` out of `2a04:2a01::/32` (announced by **AS219419**), derived *deterministically* from the device's **public key**: its `SubjectPublicKeyInfo`, from the IEEE 802.1AR IDevID key in its secure element (a Microchip ATECC608, an NXP EdgeLock SE050, an Infineon OPTIGA Trust M) or on-chip OTP/PUF storage, with the **device serial or EUI-64** as the domain separator. The private key never leaves the chip; only its public SPKI is an input. The result is [DNSSEC](/docs/dnssec)-anchored, [DANE-EE `3 1 1`](/docs/dane) pinned, and [RDAP](/docs/rdap)-registered. Anyone with `dig` can verify it, and the device proves control by signing with the key, the one operation a flash dump can never counterfeit.

```
device public key (SPKI)      ──derive · domain-sep = serial──▶   /128                  ──DNSSEC + DANE-EE 3 1 1──▶   a name anyone verifies
the 802.1AR IDevID key in                                        2a04:2a01:1c0::e51d          RDAP-registered           whisper verify --trustless
the secure element / OTP                                         routable, tenant-bound                                 op:'revoke' → owner-thrown, public
(private key stays on-chip)
```

Because the derivation is **tenant-bound**, the same key under two different fleets yields two unrelated `/128`s: an outsider cannot link a device across fleets. And because the domain separator is the serial, **a serial alone yields nothing**: there is no enumerable directory, and RDAP and reverse-DNS return the registry object, never the device's location.

What becomes true the moment a device holds one:

- **"One dump → a whole fleet" becomes physically impossible.** You cannot present device-identities whose keys you don't hold; every forgery is a DNSSEC/DANE inconsistency any verifier catches.
- **IP rotation becomes irrelevant.** Identity is not the source IP.
- **Extracted firmware fails.** A byte-perfect copy of the flash, minus the secure element, authenticates to nothing.
- **One `revoke`, thrown by the owner, retires a device's identity worldwide** at DNS-TTL speed, publicly checkable in DNS.

**Additive, never a replacement.** Whisper complements the 802.1AR IDevID, BRSKI (RFC 8995) onboarding, Matter's DAC where you run it, secure boot, and the X.509 mTLS the device cloud already speaks. And the standards story runs deeper: the IETF **DANCE** work (draft-ietf-dance-client-auth) makes a device's DNS name + DANE-TLSA record its TLS *client* credential, exactly the model Whisper's identity plane deploys; the lineage before that is CGA (RFC 3972). See [Passwordless device auth](/docs/industries/embed/device-secret-cure).

## Provision a device 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 device's base64 SPKI; optionally bind a device identifier as the domain separator. Today that identifier rides the live `device_id` argument, held to a **17-character** canonical form (the same shipped derivation the automotive vertical uses), plus an optional free-form `ecu_serial` component separator; a variable-length device-native `serial`/EUI-64 argument is on the roadmap.

```
CALL whisper.agents({op:'connect', args:{
  tier:'wireguard',
  identity_public_key:'<base64 SPKI of the device key>',
  device_id:'GW00427A310B55EF2'   // optional: a 17-character device identifier rides here today
}}) YIELD op, ok, status, result, error
RETURN op, ok, status, result, error
```

```sh
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:'GW00427A310B55EF2'}}) YIELD op, ok, status, result, error RETURN op, ok, status, result, error"}
JSON
```

```
# response
{ "op": "connect", "ok": true, "status": "created",
  "result": {
    "address": "2a04:2a01:1c0::e51d",
    "fqdn":    "sn-gw00427a310b55ef2.fleet.<tenant>.agents.whisper.online",
    "wireguard": { /* peer, keys, allowed-ips */ }
  } }
```

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

> A dedicated `--serial` CLI flag is on the roadmap; today, device provisioning is the control-plane call above (which is live). The shipped CLI verbs are `whisper verify --trustless`, `whisper create --register`, `whisper kill --revoke`, `whisper policy`, and `whisper logs`. See [CLI & one-command](/docs/cli).

## Verify it yourself: no account needed

```sh
whisper verify --trustless sn-gw00427a310b55ef2.fleet.<tenant>.agents.whisper.online

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

Or reach for the raw records directly:

```sh
# the public verify endpoint: evidence chain in JSON
curl -s https://whisper.online/verify-identity/2a04:2a01:1c0::e51d | jq

# the address is the device: forward-confirmed reverse DNS names it
dig -x 2a04:2a01:1c0::e51d +short

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

None of these calls Whisper as an authority: `--trustless` re-derives the proof against the public DNSSEC root. See [Verify an agent](/docs/verify) and [DANE & TLSA](/docs/dane).

## Revoke, worldwide, owner-thrown

```
CALL whisper.agents({op:'revoke', args:{agent:'2a04:2a01:1c0::e51d'}})

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

Contrast the alternative: rotating a leaked shared credential across a fielded fleet is a recall-grade OTA campaign, and a cloud registry flag reaches only the verifiers inside that cloud. Whisper's revoke reaches every verifier on the internet at once, and the blast radius is one leaf key, never a shared root.

## Attribution: name whoever is wearing your devices' faces

```sh
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 JA4
```

The read-only verbs (`identify`, `origins`, `walk`, `variants`, `history`) each return a reproducible, replayable JSON evidence chain. More in [Graph & cognition](/docs/graph-api).

## What ships today, and what's on the roadmap

| Shipped & live | On the roadmap |
|---|---|
| Device `/128` from the device key (+ optional 17-char `device_id` binding): DNSSEC + DANE-EE + RDAP | A variable-length device-native `serial`/EUI-64 argument and a `--serial` CLI flag |
| Control-plane provision, verify, revoke; WireGuard /128 egress on embedded Linux; the attribution graph over the public API | The C SDK, ESP-IDF component, Arduino library, Zephyr module, Yocto layer, OpenWrt/Buildroot packages, pico-sdk library |
| The **Splunk**, **Microsoft Sentinel** and **OpenCTI** connectors (signed, replayable JSON → CEF / ECS fields) | **STIX 2.1 over TAXII** export; the manufacture-line provisioning recipe and the MQTT-DANCE broker recipe |

The integration guides describe **proposed** integrations at the cloud and IP boundary: designed to complement the stack you already run, not endorsed by any vendor, never presenting an unshipped SDK as installable.

## The five Embedded guides

- [Device & IDevID identity](/docs/industries/embed/device-identity): derive a routable `/128` from the 802.1AR IDevID key a device already holds.
- [Passwordless device auth](/docs/industries/embed/device-secret-cure): the DANCE story; nothing in the firmware image worth stealing.
- [Platform integrations](/docs/industries/embed/embedded-integrations): the honest capability matrix and proposed integrations.
- [Embedded compliance](/docs/industries/embed/embedded-compliance): EU CRA, IEC 62443, EN 303 645/PSTI, FDA 524B, 802.1AR.
- [Embedded recipes](/docs/industries/embed/embedded-recipes): runnable recipes on shipped parts.

## The full technical library

Embedded rides on the same address-is-identity platform as every other agent on the network. Start with [Quickstart](/docs/quickstart), [Verify an agent](/docs/verify), [DANE & TLSA](/docs/dane) and [Control plane](/docs/control-plane); the rest is in the sidebar, and every page has a clean Markdown twin at the same path + `.md`.
