Skip to content
Agent Identity
Skip navigation

Vehicle Identities

A deterministic allocation derived from a hardware key plus the VIN, checkable by a stranger and cut in one call.

Published

On this page (4)

Vehicle Identities Documentation

A vehicle already holds a key it never gives up: an 802.1AR IDevID, a TPM, or a secure element fitted at the line. A vehicle identity turns that key into a routable address, so the backend authorises an address rather than a token that works from anywhere.

How the address is derived

The derivation produces a sixty-four-bit interface identifier, which joins the account's own /64 to form the address.

The device's public key, as SPKI, is the anchor. The private half stays inside the device and is never sent.

The VIN identifies the vehicle: seventeen characters per ISO 3779, with no I, O or Q. Whitespace is stripped and case folded first, so a loosely typed VIN still lands on the same address.

An ECU serial is optional, and it separates identities inside one vehicle: the telematics unit and the gateway can each hold an address under the same VIN.

A Whisper-held secret completes the derivation, which is why the address is account-bound: the same key and VIN under a different account derive a different address, so knowing a VIN does not link a fleet.

The result is deterministic. Present the same key and VIN again and you get the same address, so a factory step and a field replacement need no coordination.

Provisioning

One call mints the identity and returns the connectivity material with it. The address, the name, the forward and reverse records, the DANE pin and the registry object all go out at once.

whisper-call
CALL whisper.agents({op: 'connect', args: {
  tier: 'wireguard',
  identity_public_key: '<base64 SPKI of the device key>',
  vin: '<the VIN>',
  ecu_serial: '<the ECU serial>'
}})

The result carries the tier, the address, the name, and what the device needs to bring its tunnel up. The CLI does the same with whisper create --name <name> --vin <VIN>, plus --ecu-serial for one identity per unit.

Four answers to handle explicitly:

What you sendWhat you get
The same key and VIN againthe same address
The same key with a different VIN, same accounta conflict
A vin or ecu_serial that is not a stringa bad-argument error
A vin with no identity_public_keya bad-argument error

The name follows the derivation in The Address as Identity, so it carries no VIN and discloses nothing about the vehicle.

Keyless verification

Anyone receiving traffic checks a vehicle the way they check any identity: nothing installed, no account.

bash
dig -x <the vehicle address> +short
curl -s "https://rdap.whisper.online/verify-identity?ip=<the vehicle address>" | jq .

Because the pin binds the address to the key the device holds, a TLS handshake against the name also proves the party answering holds the private half. The Proof Chain has the pin check.

Cutting a vehicle off

A stolen unit, a decommissioned ECU or a replaced module is one call.

whisper-call
CALL whisper.agents({op: 'revoke', args: {agent: '<the vehicle address>'}})

Once the record lifetime has passed, the reverse lookup returns nothing and the keyless verdict reads false, so every relying party reaches the same conclusion. Revoke an Identity has the full proof sequence.