# Verify Without Trusting Us

> whisper verify --trustless re-derives an agent identity locally from the IANA DNSSEC root, with per-row trust levels and an exit code you can branch on.

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

---
Every other check in [the proof chain](/docs/identity/proofs) ends with something Whisper said. The verdict endpoint is an answer from a Whisper server. Even `dig` against a Whisper name depends on a resolver you did not write. `whisper verify --trustless` closes that gap: it validates the chain in-process, from the IANA DNSSEC root anchor compiled into the binary, and takes the Whisper API out of the trust path entirely.

## What runs locally

The command fetches the records itself and validates the signatures itself. It walks the delegation from the root down to the identity zone, checks the reverse and forward records against each other, reads the `TLSA` record and compares it to the key served on the name, then reads the signed identity document and checks it against the same key.

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

The output is one row per part of the chain: `dnssec`, `dane`, `transparency` and `identity_doc`. Each row carries a result and a trust level.

## The three trust levels

A row's trust level says how much you had to assume to believe it.

`DNSSEC-root` is the strongest. The row was validated by a signature chain that terminates at the IANA root anchor, so nothing between you and the root had to be trusted.

`pin+DNSSEC` means the row was validated against a key that DNSSEC itself vouches for, so the strength is the strength of the delegation that published the pin.

`trust-on-pin` means the row was validated against a key you accepted on first sight. It proves continuity: whoever answered this time holds the same key as last time. It does not by itself prove who that is.

Read the levels rather than assuming them. Which level a given row reaches depends on what is published for that identity and on what your resolver path returns.

## The verdict rule

The overall verdict is `true` only when the `dnssec` row and the `dane` row both pass and no row fails. That is deliberate: those two are the rows that bind a name to a key with no room for interpretation. A row that could not be evaluated leaves the verdict alone; a row that failed sinks it.

The exit code mirrors the verdict, so the command drops straight into a script or a CI gate without any parsing.

```bash
whisper verify --trustless --json 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478 > verdict.json \
  && echo "identity holds" \
  || echo "identity did not verify"
```

`--json` gives you the same rows as machine-readable output. `--resolver <ip>` sends the lookups through a resolver you choose, which is how you check the same identity from two vantage points and compare.

## When to reach for it

Use the [keyless verdict endpoint](/docs/identity/verify) on the hot path, where one HTTP call per inbound connection is the right cost. Use `--trustless` when the answer has to survive scrutiny: an audit, an incident writeup, a compliance control, or the first time you onboard a counterparty and want evidence that does not route through the party you are assessing. The [transparency log](/docs/identity/transparency) is the other half of that story, because it is what lets you show that the identity you verified today is the identity that was issued.
