Whisper · Docs
Standards

DANE & TLSA

A certificate alone proves nothing — anyone can mint a valid cert for a name if a CA will sign it, and 100+ CAs in your trust store can.

DANE fixes this by putting the answer to "which key is correct" in the DNS itself, signed all the way to the root — so trust no longer depends on a list of authorities you didn't choose and can't audit.

The problem DANE solves

Every browser and TLS client ships a trust store of a hundred-plus certificate authorities, any one of which can issue a valid certificate for any name. A single mis-issuance, compromised CA, or coerced government CA anywhere in that list can produce a certificate that passes validation for agents.whisper.online or your bank. Certificate Transparency logs help you notice after the fact; they don't stop the connection from succeeding in the moment. For machine-to-machine traffic — an agent egressing through Whisper, or another agent connecting to a Whisper agent — "notice it eventually" isn't good enough. You want the client to be able to say, before it sends a single byte of application data: this is the one specific key that is allowed to speak for this name, and nothing else, full stop.

DANE (DNS-Based Authentication of Named Entities, RFC 6698) does exactly that. It publishes a TLSA record at the service's own name, inside DNSSEC-signed DNS, that pins the exact certificate or public key a client should expect. No CA required, no CA even consulted if you use the strict DANE-EE profile (RFC 7671) that Whisper agents use.

The TLSA record, byte for byte

A TLSA record lives at _<port>._<protocol>.<name> — for a Whisper agent on port 443:

_443._tcp.acef2002a323d40d4.<tenant>.agents.whisper.online. IN TLSA 3 1 1 b653a4ef...fcb82d1d

Four fields, in order, per RFC 6698 §2:

Field Value Meaning
Certificate usage 3 DANE-EE: the record pins the end-entity cert/key directly — no CA path is validated or even needed
Selector 1 SPKI — the pin covers the certificate's SubjectPublicKeyInfo, not the whole certificate
Matching type 1 SHA-256 — the association data is a SHA-256 hash, not a full match
Certificate association data b653a4ef…fcb82d1d the 32-byte SHA-256 hash of the SPKI, hex-encoded

Read as a sentence: "the key presented on :443/tcp for this name must have a SubjectPublicKeyInfo whose SHA-256 hash equals this 32-byte value — no other check required." That's usage/selector/matching 3 1 1, universally shorthanded as DANE-EE(SPKI/SHA-256) and the profile RFC 7671 recommends as the operational baseline: it survives certificate reissuance under the same key, doesn't need re-publishing every renewal, and needs no CA chain validation at all — the CA-usage values 0/1/2 still walk a chain to a trust anchor; 3 skips that entirely.

What a validating client actually does

  1. Resolve the TLSA record for _443._tcp.<name>, and validate it is DNSSEC-signed all the way to the IANA root (see DNSSEC for how every answer Whisper serves chains to that single anchor — the TLSA record is served authoritatively and signed exactly like the rest of the zone).
  2. Open the TLS connection, receive the server's certificate in the handshake.
  3. Extract the SPKI (the DER-encoded public-key structure, not the raw key bytes and not the whole cert — selector 1).
  4. SHA-256 it (matching type 1).
  5. Compare against the association data in the TLSA record, byte for byte.
  6. Proceed only on an exact match. No hostname-vs-SAN fallback, no CA path, no revocation check needed — usage 3 says the DNS is the authority.

If the hashes don't match, the client MUST NOT proceed — RFC 6698 treats this the same as an outright TLS validation failure, and RFC 7671 §5.1 goes further: if usage 3 is present, don't consult PKIX at all.

With stock tools

Everything above is checkable with tools already on your machine — dig for the DNS record, openssl for the live handshake:

# Fetch the TLSA record — note it comes back DNSSEC-authenticated (ad flag)
dig +dnssec TLSA _443._tcp.acef2002a323d40d4.<tenant>.agents.whisper.online

;; ->>HEADER<<- opcode: QUERY, status: NOERROR
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2
;; _443._tcp....agents.whisper.online. 300 IN TLSA 3 1 1 b653a4ef...fcb82d1d
;; _443._tcp....agents.whisper.online. 300 IN RRSIG TLSA 13 7 300 ...

# Pull the SPKI hash the server actually presents, live, and compare by eye
openssl s_client -connect acef2002a323d40d4.<tenant>.agents.whisper.online:443 \
  -servername acef2002a323d40d4.<tenant>.agents.whisper.online </dev/null 2>/dev/null \
  | openssl x509 -pubkey -noout \
  | openssl pkey -pubin -outform der \
  | openssl dgst -sha256
# (stdin)= b653a4ef...fcb82d1d   ← must equal the TLSA pin above

That's the entire trust decision in two commands and zero accounts, subscriptions, or CA bundles. kdig +dnssec from knot-dnsutils gives you the same answer with clearer DNSSEC status lines if you prefer it to dig.

With Whisper

The whisper CLI performs exactly this comparison — plus the DNSSEC chain-of-trust walk to the IANA root and a signed-ledger cross-check — as one call, and tells you which link (if any) failed instead of leaving you to diff two hex strings:

whisper verify --trustless acef2002a323d40d4.<tenant>.agents.whisper.online

dnssec   pass   DNSSEC-root   AAAA, PTR and TLSA(3 1 1) all DNSSEC-validated to the IANA root
dane     pass   DNSSEC-root   served leaf SPKI-SHA256 == TLSA pin
ledger   pass   DNSSEC-root   entry present, signature verifies
CRYPTOGRAPHICALLY PROVEN — trust anchor: DNSSEC root (IANA) + DANE-EE — Whisper API NOT trusted

The --trustless flag is the point: nothing here calls back to Whisper's own API as an authority — the CLI is re-deriving the same proof any resolver could, against the public DNSSEC root, and printing the verdict. See Verify an agent for the full seven-proof keyless check this sits inside of, and the Whisper CLI source for the exact validation code — it's public.

Where the pin comes from, and what else it anchors

The TLSA pin isn't hand-managed: it's published the moment an agent's identity is provisioned, alongside its AAAA and PTR records, and torn down atomically on revocation — the same one Cypher control op that allocates the /128 under 2a04:2a01::/32 (AS219419) also publishes its TLSA. That pin is then the same anchor two other mechanisms build on:

One record, DNSSEC-signed, checked by two commands or one CLI call — that's the entire trust chain, and it's the same chain whether you're auditing us or your own agents.

Next