# The Proof Chain

> The eight checks behind a Whisper agent identity: PTR, AAAA, CNAME, DANE TLSA, RDAP, WHOIS, the keyless verdict and client-side re-derivation.

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

---
Eight checks stand behind an identity. The first six read one record each with a stock tool. The seventh runs all of them server-side and returns one answer. The eighth re-runs the chain on your own machine. Every one of them is keyless.

Examples below use the documentation address `2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478`, whose derived name is `ae3b051ff3bf7f478.t<tenant>.agents.whisper.online`. Substitute your own target.

## 1. Reverse DNS {#ptr}

`PTR` under `ip6.arpa` says which name the address answers to. The zone is delegated to Whisper and signed, so a validating resolver sets `AD` on the answer.

```bash
dig -x 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478 +short
```

## 2. Forward DNS {#aaaa}

`AAAA` under the identity zone says which address the name resolves to. It sits in a different delegation from the `PTR`, populated independently, and the pair agreeing is forward-confirmed reverse DNS. A mismatch is the fraud signal.

```bash
dig +short AAAA ae3b051ff3bf7f478.t<tenant>.agents.whisper.online
```

## 3. The friendly alias {#cname}

An identity may publish a short label as a `CNAME` pointing at the canonical name. It resolves the human-readable name to the derived one, so a label cannot be pointed at an address it was not allocated.

```bash
dig +short CNAME shipping-bot.t<tenant>.agents.whisper.online
```

## 4. The DANE pin {#tlsa}

`TLSA` at `_443._tcp.<name>` with parameters `3 1 1` binds the name to one public key: DANE-EE usage, SPKI selector, SHA-256 match. Compare the record to a digest of the key the server actually serves.

```bash
dig +dnssec TLSA _443._tcp.ae3b051ff3bf7f478.t<tenant>.agents.whisper.online

openssl s_client -connect ae3b051ff3bf7f478.t<tenant>.agents.whisper.online:443 \
  -servername ae3b051ff3bf7f478.t<tenant>.agents.whisper.online </dev/null 2>/dev/null \
  | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256
```

The two hex strings must be identical. [Keys, Signing and Encryption](/docs/identity/keys) covers what else that key signs.

## 5. The registry object {#rdap}

RDAP answers for the single `/128` in RFC 9083 JSON: the handle, the object name, the type, the status and a referral up to the RIR that holds the covering block.

```bash
curl -s https://rdap.whisper.online/ip/2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478 | jq '.handle, .name'
```

## 6. The WHOIS record {#whois}

The same allocation on port 43, in RFC 3912 key-and-value lines, for tooling and abuse desks that speak WHOIS and nothing else.

```bash
whois -h whois.whisper.online 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478
```

[RDAP and WHOIS](/docs/identity/registry) documents both records field by field.

## 7. The keyless verdict {#verdict}

One call runs checks one through six server-side and returns a single boolean with the evidence it used, so a gateway does not have to speak DNS.

```bash
curl -s "https://rdap.whisper.online/verify-identity?ip=2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478" | jq .
```

`is_whisper_agent`, `dane_ok` and `jws_ok` are the three booleans to branch on. [Verify an Identity](/docs/identity/verify) reads the full response.

## 8. Client-side re-derivation {#trustless}

The CLI walks the chain itself from the IANA DNSSEC root, with the Whisper API out of the trust path, and prints a trust level per row.

```bash
whisper verify --trustless 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478
```

[Verify Without Trusting Us](/docs/identity/trustless) explains the rows and the levels.

## The signed identity document {#identity-document}

Behind `jws_ok` sits a compact ES256 JWS served on the identity's own name at `/.well-known/whisper-identity`, binding the address, the name, the account and the issue time. It is signed by the key the `TLSA` record pins, and the zone's signing keys are published in a `TXT` record under `_whisper-identity.whisper.online`.

```bash
curl -s --cacert whisper-ca.pem \
  https://ae3b051ff3bf7f478.t<tenant>.agents.whisper.online/.well-known/whisper-identity
```

A plain `curl` fails here, because the certificate is issued by the per-identity authority rather than a browser root. Pass the root from [Keys, Signing and Encryption](/docs/identity/keys), or check the pin first and then fetch.

## What the chain proves

The chain proves that one address, one name and one key were issued together by the operator of `2a04:2a01::/32` and still are. It says nothing about intent, and nothing about permission. Keep authorisation as its own step.
