# Identity

**The /128 address is the credential — a name derived from it, a two-way DNS lock, registry-anchored, signed.**

Every agent framework eventually asks the same question — "is this actually the agent I think it is?" — and every stock answer is a secret string: an API key, a bearer token, a JWT sitting in an env var. Secrets leak, get replayed, and can't be checked by a third party without asking the issuer to vouch for them. A rotated key breaks nothing about the agent's identity because the key was *never* the identity — it was a bolt-on. Whisper takes a different starting point: the agent's identity **is** its network address, an IPv6 `/128` it holds exclusively out of `2a04:2a01::/32` (AS219419), and every fact about that agent — its name, its TLS key, its registry record — is derivable from, and cryptographically bound to, that one address. A stranger with `dig` and no API key can check all of it.

This page is the mechanism page: how the name comes out of the address, why the forward and reverse records can't be faked independently, and the full set of proofs that stack on top.

## The name is derived from the address, not assigned to it

Whisper agents live in `2a04:2a01::/32`. Each agent is allocated one `/128` out of that space — a single address, not a subnet. That address, `2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4`, splits into two halves:

| half | hextets | role |
|---|---|---|
| **upper 64 bits** | `2a04:2a01:eb5a:ca74` | Whisper routing + tenant topology |
| **lower 64 bits** | `cef2:2a:323d:40d4` | the agent's own identity — becomes the handle |

The derivation is mechanical and public:

1. Take the last four hextets (the lower 64 bits) of the `/128`.
2. Zero-pad each hextet to 4 hex digits: `cef2`, `2a` → `002a`, `323d`, `40d4`.
3. Concatenate them, dropping the colons: `cef2002a323d40d4`.
4. Prefix `a` (a leading label character is required by the LDH hostname rule, RFC 952/1123 — hex alone can start with a digit, which is legal for a label but reads badly as a hostname's leftmost character) to get the **handle**: `acef2002a323d40d4`.
5. Append the tenant and zone: `acef2002a323d40d4.<tenant>.agents.whisper.online`.

That gives the resident demo agent its fully-qualified name:

```
2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4
        ⇓  (deterministic, no lookup, no database round-trip)
acef2002a323d40d4.<tenant>.agents.whisper.online
```

Anyone can run the same five steps by hand on any Whisper `/128` and land on the same name Whisper's own authoritative server publishes — the name isn't a label someone typed into a table next to the address, it's a pure function *of* the address. That is what makes the next property possible.

## The two-way lock: PTR ⇄ AAAA bijection

A name is only as trustworthy as the direction you can check it in. Whisper publishes the mapping **both ways**, and — this is the load-bearing detail — the two directions are populated independently, from opposite ends of the authoritative data, so an attacker who controls only one direction cannot forge the pair.

- **Reverse** — a `PTR` record under `4.d.0.4.d.3.2.3.a.2.0.0.2.f.e.c.4.7.a.c.a.5.b.e.1.0.a.2.4.0.a.2.ip6.arpa` (the nibble-reversed form of the address, RFC 3596 / RFC 1035 §3.3.12) resolves the **address → name**.
- **Forward** — an `AAAA` record under `acef2002a323d40d4.<tenant>.agents.whisper.online` resolves the **name → address**.

```
dig -x 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4 +short
  → acef2002a323d40d4.<tenant>.agents.whisper.online.

dig +short AAAA acef2002a323d40d4.<tenant>.agents.whisper.online
  → 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4
```

Both answers validate `AD=YES` under DNSSEC on any validating resolver — 1.1.1.1, 8.8.8.8, your own unbound.

The PTR zone (`ip6.arpa`, delegated to Whisper's authoritative servers for the ranges it holds) and the forward zone (`agents.whisper.online`) are two separate delegations, so an impostor has to win **both**: make the reverse zone answer with a name they don't hold the forward record for, *and* make the forward zone answer with an address they don't hold the `/128` for. Neither zone trusts the other's data — each is authoritative on its own.

So spoofing one side just produces a mismatch a verifier catches immediately: `dig -x` names one agent, `dig AAAA` on that name returns a different address, or nothing. That mismatch-detection is the entire security property — identity theft becomes a DNS inconsistency, not a secret to guess.

## The seven proofs (and an eighth, trustless one)

The PTR/AAAA bijection is proof one and two. Five more standard primitives stack on the same address, each independently checkable with tools that ship on every Unix box:

| # | Proof | Primitive | RFC |
|---|-------|-----------|-----|
| 1 | Reverse DNS | `PTR` on the `ip6.arpa` name | RFC 3596, RFC 1035 §3.3.12 |
| 2 | Forward DNS | `AAAA` on the derived name | RFC 3596 |
| 3 | Friendly alias | `CNAME` from a human label to the same derived name | RFC 1035 §3.3.1 |
| 4 | Key pin | `TLSA` under `_443._tcp.<fqdn>`, usage/selector/matching `3 1 1` (DANE-EE, SPKI, SHA-256) | RFC 6698 |
| 5 | Registry record | RDAP JSON for the `/128`, with a `startAddress`/`endAddress` of exactly that one address, referring up to the RIR | RFC 9083 |
| 6 | Registry record (legacy) | The same fact over WHOIS on port 43 | RFC 3912 |
| 7 | Full-chain verdict | A keyless JSON endpoint that runs 1–6 server-side and returns one verdict | Whisper-specific, see [Verify an agent](/docs/verify) |
| 8 | Trustless re-derivation | The same six checks, re-run **client-side**, anchored only at the IANA DNSSEC root — Whisper's own API is never in the trust path | see [Verify an agent](/docs/verify) |

Each proof is independently useful (a peer that only speaks DANE needs nothing but proof 4; an RDAP-aware allowlist needs only proof 5) but they all resolve back to the *same* `/128`, which is the point: there's no single office you have to trust, there's an address with seven independent lines of evidence converging on it.

### With stock tools

```bash
dig -x 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4 +short
# acef2002a323d40d4.<tenant>.agents.whisper.online.

dig +short AAAA acef2002a323d40d4.<tenant>.agents.whisper.online
# 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4

dig +short TLSA _443._tcp.acef2002a323d40d4.<tenant>.agents.whisper.online
# 3 1 1 b653a4ef...fcb82d1d

curl -s https://rdap.whisper.online/ip/2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4 | jq .name
whois -h whois.whisper.online 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4

curl -s https://rdap.whisper.online/verify-identity/2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4 | jq .
# {"is_whisper_agent": true, "dane_ok": true, "jws_ok": true, "evidence": {...}}
```

Every one of those calls is keyless — no `X-API-Key`, no account. A non-agent target (any address or name Whisper doesn't hold) returns a clean `{"is_whisper_agent": false}`, per the Robustness Principle: liberal in what it accepts, never an opaque error.

### With Whisper

```bash
# mint an identity — the address, name, and PTR come back in one call
whisper create --register --label my-agent

# re-derive all seven checks yourself, anchored at the IANA DNSSEC root
whisper verify --trustless 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4
```

```
CALL whisper.agents({op:'register', args:{label:'my-agent'}})
  -> api_key, address (a routable /128), fqdn, ptr
```

`register` (or `whisper create --register`) is what actually allocates the `/128` and provisions all seven proofs atomically — the PTR, the AAAA, the TLSA, the RDAP/WHOIS records, and the signable identity document — so there's never a window where one exists without the others. `op:revoke` tears the same set down in one step: after it runs, `dig -x` on that address returns nothing and `/verify-identity` returns `is_whisper_agent: false` — the same stock tools that proved the identity prove the kill.

## Why this beats a bearer token

A bearer token is a shared secret: whoever holds the string *is* authorized, full stop, until someone remembers to rotate it — and a stranger has no way to check it at all without asking the issuer. A Whisper identity is a **public, standing, cryptographically-anchored fact**: DNSSEC signs the zones, DANE pins the key without needing a CA, RDAP/WHOIS refer up through the RIR hierarchy, and none of it requires trusting Whisper's API in the moment you check it — `whisper verify --trustless` walks the exact same chain from the IANA root instead. The address doesn't represent the agent's identity. It **is** the agent's identity.

## Next

[Verify an agent](/docs/verify) — run all eight proofs end to end, including the trustless client-side re-derivation. [DANE & DNSSEC](/docs/dane) — the exact chain from the TLSA record up to the IANA root.
