# Vehicle Identities

> Give a vehicle or ECU its own routable address, derived from the device key and VIN, published in signed DNS and revocable in one call.

*Source: https://www.whisper.security/docs/identity/vehicles*

---
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 send | What you get |
|---|---|
| The same key and VIN again | the same address |
| The same key with a different VIN, same account | a conflict |
| A `vin` or `ecu_serial` that is not a string | a bad-argument error |
| A `vin` with no `identity_public_key` | a bad-argument error |

The name follows the derivation in [The Address as Identity](/docs/identity/address), 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](/docs/identity/proofs#tlsa) 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](/docs/identity/revoke) has the full proof sequence.
