# Whisper NIC: the complete registry record.

> Everything a registry is expected to publish, kept current: the resources, the
> access endpoints, bring-your-own-domain proof, issuance under your own domain,
> the verification recipes, and the transparency-log policy. Conservative in what
> we state; clear about what is live versus on its way.

Every command below is run against
the live service and pasted exactly as it answers. The examples use a live resident,
`2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478`; swap in any agent's `/128` or its name.

## 1. Registry identity and resources

The registry is operated by **Whisper Security (viaGraph B.V.)**, Amsterdam, NL,
on infrastructure we hold ourselves. No third party sits in the trust path.

- **Autonomous system:** `AS219419`, IPv6-only, announced from <https://as219419.net/>.
- **Agent identity block:** `2a04:2a01::/32` — one `/128` per agent identity,
  within RIPE allocation `2a04:2a00::/31`.
- **Assignment model:** `inet6num`, `AGGREGATED-BY-LIR`, **assignment-size 128** —
  every agent is a normally-allocated, individually-recorded `/128`.
- **Resolver / DNS service:** authoritative `ns1.whisper.online` +
  `ns2.whisper.online`; the recursive upstream is the unbound resolver at
  `2a04:2a00::53`.
- **Routing posture:** RPKI ROA-covered origin, MANRS-compliant, dual-homed (two
  independent transits) for redundancy.

Every agent record refers up to RIPE's own record for `2a04:2a01::/32`, so the
ground under it is independently confirmable. Live counts: <https://nic.whisper.online/stats>.

## 2. Access endpoints

All read-only, all keyless.

- **RDAP, by address:** `https://rdap.whisper.online/ip/<addr>` (RFC 9083) — the
  canonical machine-readable object.
- **RDAP, by domain:** `https://rdap.whisper.online/domain/<apex-or-fqdn>`
  (RFC 9082/9083) — the served-zone object, with `secureDNS` and the parent referral.
- **WHOIS:** `whois.whisper.online`, port 43 (RFC 3912) — the same record in
  `inet6num` form.
- **Finger, by identity:** `finger.whisper.online`, port 79 (RFC 1288) — the same
  record in plain-text identity form, answerable by a `/128` or an agent FQDN.
- **FTP archive, anonymous:** `ftp.whisper.online`, port 21 (RFC 959) — anonymous
  read-only archive of the NIC registry documents (the same content served over
  RDAP / WHOIS / HTTP).
- **DNSSEC trust anchors:** the served zones are signed and chained; the parent
  carries a `DS` for `agents.whisper.online` and `whisper.online` (ECDSA P-256,
  algorithm 13).
- **Keyless verification:** `https://rdap.whisper.online/verify-identity/<addr>` —
  one call that checks the whole chain and returns a plain verdict.

Confirm the DNSSEC trust anchors yourself (the `DS` values rotate with the keys,
so read your own live answer):

```sh
$ dig +short DS agents.whisper.online @1.1.1.1
54705 13 2 99B88E7C1FD2A815F3DA0374D9FED2C4735F7EFDDB864CB1A79F9D55 43DFE06D
$ dig +short DS whisper.online @1.1.1.1
50855 13 2 3B33E9998425C1F43FCC3B8D4696DB587DB7CEA3F2A235E1556C4C4F 47E247D3
```

Add `+dnssec` to any forward query and require the `ad` flag (validated).

## 3. Verify any identity with stock tools

Eight independent checks, each run against the live service and pasted verbatim.

```sh
# 1. Reverse DNS names the address (signed):
$ dig -x 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478 +short
ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online

# 2. The forward name points back to the same address (the loop closes):
$ dig +short AAAA ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online
2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478

# 3. The agent's key is pinned in DNS itself (DANE-EE 3 1 1, no CA in the path):
$ dig +short TLSA _443._tcp.ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online
3 1 1 9EC1EF18A1F15E5480A0FC3C8D6E9690B2CCF1A7FA7146201940F28C 422BB47D

# 4. The TLS leaf on the wire matches that pin (a DANE-aware client validates it):
$ openssl s_client -dane_tlsa_domain ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online \
    -dane_tlsa_rrdata "3 1 1 9EC1EF18A1F15E5480A0FC3C8D6E9690B2CCF1A7FA7146201940F28C 422BB47D" \
    -connect [2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478]:443 </dev/null 2>/dev/null | grep "DANE TLSA"
# -> DANE TLSA 3 1 1 ... matched EE certificate

# 5. One keyless call checks the whole chain and returns a plain verdict:
$ curl -s https://rdap.whisper.online/verify-identity/2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478 | jq '{is_whisper_agent,dane_ok,jws_ok}'
# -> {"is_whisper_agent": true, "dane_ok": true, "jws_ok": true}

# 6. The registry knows it by address and by name (RDAP canonical; WHOIS mirrors):
$ curl -s https://rdap.whisper.online/ip/2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478 | jq -r .name
scout
$ whois -h whois.whisper.online 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478
# -> inet6num / netname / origin AS219419 / aggregate 2a04:2a01::/32 / ...
$ curl -s https://rdap.whisper.online/domain/ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online
# -> the signed-DNS / referral view of the same identity

# 7. The signed identity document and the did:web record live at the agent's name
#    (DANE-anchored, so fetch with a DANE-aware client; step 5 verifies the JWS for you):
$ curl -s https://ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online/.well-known/whisper-identity   # signed JWS identity statement
$ curl -s https://ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online/did.json                        # W3C did:web document (same key)

# 8. The agent's SSH host-key fingerprint is in DNS too (SSHFP):
$ dig +short SSHFP ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online
3 2 9335418b3b03a5180ada334724917ca2a5d529066305f8a404a139f6 fa1370c8
```

The agent's certificate is anchored by the TLSA record in signed DNS, **not** by a
public CA, so a plain `curl` that only trusts public CAs will reject it — that is
the point. Use a DANE-aware client, or the keyless gateway check in step 5, which
validates the chain for you. Every check depends on signed DNS and your own tools,
not on trusting us.

## 4. Bring your own domain — onboarding and proof (coming)

You can put the registry under a domain you already own. You bring the domain; we
run the network and the registry that vouch for the identities inside it. Publish
the delegation and the DS at your parent (apex or a subdomain):

```
example.com.   NS   ns1.whisper.online.
example.com.   NS   ns2.whisper.online.
example.com.   DS   <digest 2 (SHA-256) and 4 (SHA-384)>
```

**Proof = delegation + DS, observed live in the wild. No TXT challenge.** We poll
your own authoritative servers, then public resolvers from several vantage points,
until the delegation and a matching `DS` are seen. Verification is **fail-closed**:
an unproven domain is never authorized. A daily continuity sweep re-checks every
delegated domain; if the chain moves away from us, the domain goes out of order on
its own. Keep your zone signed end to end; add no glue for our out-of-bailiwick
nameservers. This onboarding flow is being rolled out under this campaign; until it
lands for your account, your agents live under `agents.whisper.online`.

## 5. Issuance under a custom domain (coming)

Once a domain is onboarded and proven, new agents are minted directly under it, as
`a<hex>.<yourdomain>`, instead of under `agents.whisper.online`. The whole record —
reverse DNS, RDAP, WHOIS, DANE, and the signed identity document — follows the name
into your domain.

- **DANE-EE trust by your DNS:** each agent's per-agent leaf has a `TLSA` record
  under your now-signed zone; because your zone chains to the public root through
  your own `DS`, a DANE-aware peer trusts the agent with no Whisper CA and no public
  CA.
- **Coexistence:** identities already issued under `agents.whisper.online` keep
  resolving for good; the custom domain takes over only for new mints. The IPv6
  `/128` stays ours (AS219419, `2a04:2a01::/32`) — only the name moves.
- **Capacity:** a configurable per-operator cap keeps signing and replication load
  bounded, failing closed with a clear message rather than a surprise.

The multi-zone serving engine that makes this possible is live; the per-account
onboarding and full RDAP/WHOIS/reverse coverage for custom domains are rolling out
under this campaign.

## 6. The transparency log

Each identity carries an append-only, hash-chained record of its events —
issuance, rotation, revocation — signed by a dedicated log key with a published key
id. You can read it today, per `/128`:

```sh
$ curl -s https://rdap.whisper.online/ip/2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478/transparency | jq '{count,root_hash,root_signature_alg}'
# -> {"count": 1, "root_hash": "...", "root_signature_alg": "ES256"}
```

A revocation cannot be quietly erased from an identity's history. As of the
transparency-log rollout (live since `0.112.0`), this per-identity feed is anchored
in a single append-only **Merkle log of all identity commitments**, with the public
proof surface below.

### The public proof surface (live)

The whole log is published, keyless, on the same gateway:

- **Signed checkpoint:** `GET https://rdap.whisper.online/checkpoint` — the C2SP
  signed note (origin `whisper.online/ledger`, `tree_size`, base64 root, Ed25519
  signature line).
- **Published log key:** `GET https://rdap.whisper.online/checkpoint/key` — key id
  `8a3a5df0`, the Ed25519 public key and its SPKI form.
- **Merkle tiles:** `GET https://rdap.whisper.online/tile/<level>/<index>` — the
  immutable raw 32-byte node hashes.
- **Consistency proof:** `GET https://rdap.whisper.online/consistency?from=<a>&to=<b>`
  — the append-only-extension proof (tree `a` is a prefix of tree `b`).
- **Inclusion (per identity):** `GET https://rdap.whisper.online/ip/<addr>/transparency`
  now carries a `ledger` arm: `{tree_size, checkpoint, leaves:[{index, leaf_hash,
  inclusion_proof[]}]}` — opaque commitments only.

```sh
# The published key + the signed checkpoint (the checkpoint Link header points at the key):
$ curl -s https://rdap.whisper.online/checkpoint/key
# -> {"object":"whisper-ledger-key","origin":"whisper.online/ledger","alg":"Ed25519",
#     "key_id":"8a3a5df0","public_key":"pyTBKL3bSJO7kBbdw4FqJsjREW23jNP07HybKByIabg="}
$ curl -s https://rdap.whisper.online/checkpoint
# -> whisper.online/ledger
#    1
#    Ux6ZqO3+QDdWjTWSnyLJAeAu0WlkD70+AcJWSuJURIM=
#
#    — whisper.online/ledger ijpd8L311mCaWM1DkXyS8P0NgPH5F+YZmftiifaUoYbMq680avzBKRe6wI1yCNTakRWvK8ha1C5d6OaPXLoO43Vn3Qg=
```

The signature line is `— <origin> <base64(key-id || Ed25519 sig)>`; its first four
bytes are the key id `8a3a5df0`, re-derivable as `SHA-256(origin || 0x0A || 0x01 ||
pubkey)[:4]` — so the signing key is the one at `/checkpoint/key`, nothing to trust
in between.

### A worked example, from the tree

`ae3b051ff3bf7f478.tdc38e7c55bad3306a92b830f9bb1e4f9.agents.whisper.online` at
`2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478` is a
real resident, at **leaf index 0**. The tree currently holds a single leaf, so the
inclusion proof is empty and the leaf hash is the root:

```sh
$ curl -s https://rdap.whisper.online/ip/2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478/transparency | jq '.ledger'
# -> {
#      "object": "ledger-inclusion", "origin": "whisper.online/ledger", "tree_size": 1,
#      "leaves": [{"index": 0,
#        "leaf_hash": "531e99a8edfe4037568d35929f22c901e02ed169640fbd3e01c2564ae2544483",
#        "inclusion_proof": []}]
#    }
```

Identities minted before the log do not yet carry a leaf — their `ledger.leaves` is
`[]` until a genesis back-fill folds them in. An empty `leaves` means "no Merkle leaf
yet," not "not an agent"; the per-`/128` hash-chained feed still covers them.

### Verify it yourself, with stock tools

The leaf commitment is `sha256(salt || event)`; the Merkle leaf is `sha256(0x00 ||
commitment)`; interior nodes are `sha256(0x01 || left || right)`. Fold the published
`inclusion_proof` to the checkpoint root, then verify the Ed25519 signature with the
published key. For the single-leaf tree the proof is empty, so the check reduces to
"leaf == root" — which the published bytes prove outright:

```sh
# 1. the published Merkle leaf hash for index 0 (the tile IS the 32-byte leaf):
$ curl -s https://rdap.whisper.online/tile/0/0 | sha256sum
$ curl -s https://rdap.whisper.online/tile/0/0 | xxd -p -c64
# -> 531e99a8edfe4037568d35929f22c901e02ed169640fbd3e01c2564ae2544483

# 2. the root in the signed checkpoint (base64 line 3), decoded to hex:
$ curl -s https://rdap.whisper.online/checkpoint | sed -n '3p' | base64 -d | xxd -p -c64
# -> 531e99a8edfe4037568d35929f22c901e02ed169640fbd3e01c2564ae2544483

# 3. empty inclusion_proof => leaf == root: the two hex strings match. Done.
#    For a multi-leaf tree, fold each proof step (node = sha256(0x01 || left || right))
#    up to the checkpoint root, then verify the Ed25519 signature with /checkpoint/key.
```

Or one command with the keyless CLI verifier (same stock crypto — Ed25519 +
SHA-256 + RFC 6962 folding):

```sh
$ whisper ledger checkpoint                       # fetch + verify the signed checkpoint
# -> whisper: checkpoint VERIFIED — signed tree of 1 leaves
$ whisper ledger verify 2a04:2a01:b69a:6717:e3b0:51ff:3bf7:f478 --salt <hex> --event-file event.bin
# -> whisper: VERIFIED — the disclosed commitment is in the signed ledger at leaf 0 of 1
```

**The claim.** This is a **tamper-evident, signed transparency log**: every checkpoint
is signed, openly published, and Bitcoin-anchored, so anyone can verify the proofs
today. Want it verifiable without taking our word for it? **Run a witness and we'll
cosign back** — independent co-signers make the log mutually, independently verifiable,
and the invitation is open: every witness strengthens everyone's proofs. Verification is by
**selective disclosure** — the tree holds only opaque salted commitments, so the
public proofs show that a commitment is in the signed tree, not what it attests. See
the policy (<https://nic.whisper.online/policy#transparency>) and the witness-policy
ADR
(<https://github.com/whisper-sec/whisper-ns/blob/main/docs/adr/0018-ledger-witness-policy-and-claim-gate.md>).

- **Live today:** the per-`/128` signed event feed at `/ip/<addr>/transparency`
  (now with a `ledger` inclusion arm), the signed `/checkpoint` and its published
  key (id `8a3a5df0`), the immutable `/tile/<level>/<index>` Merkle tiles, the
  `/consistency` append-only proof, and the keyless `whisper ledger` verifier — all
  stock crypto, no SDK.
- **An open invitation:** **independent witnesses are welcome** — run one against the
  checkpoints and we'll cosign back, so the log is mutually, independently verifiable
  for everyone who takes part (ADR 0018, #151 WB4). The genesis back-fill that folds
  pre-log identities into the tree is also in flight.

## 7. Policies, sources, and contact

- **Registry rulebook:** policy (<https://nic.whisper.online/policy>), naming
  (<https://nic.whisper.online/naming>), reserved & premium names
  (<https://nic.whisper.online/names>), statistics
  (<https://nic.whisper.online/stats>), data licence
  (<https://nic.whisper.online/data-license>).
- **Open decisions (ADRs):** transparency-log witness policy
  (<https://github.com/whisper-sec/whisper-ns/blob/main/docs/adr/0018-ledger-witness-policy-and-claim-gate.md>);
  full set (<https://github.com/whisper-sec/whisper-ns/tree/main/docs/adr>).
- **Network and company:** AS219419 (<https://as219419.net/>), Whisper Security
  (<https://whisper.security>), the home for your agents (<https://whisper.online/>).
- **Abuse / contact:** <abuse@whisper.security>.

---

- **Overview:** <https://nic.whisper.online/>
- **Bring your agent home:** <https://console.whisper.security/sign-up>
- **Verify an agent (the living nest):** <https://agents.whisper.online/>

© viaGraph B.V. (dba Whisper Security)
