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
- Resolve the
TLSArecord 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). - Open the TLS connection, receive the server's certificate in the handshake.
- Extract the SPKI (the DER-encoded public-key structure, not the raw key bytes and not the whole cert — selector
1). - SHA-256 it (matching type
1). - Compare against the association data in the TLSA record, byte for byte.
- Proceed only on an exact match. No hostname-vs-SAN fallback, no CA path, no revocation check needed — usage
3says 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:
- Per-agent CA — each agent's leaf certificate is issued under its own dedicated authority, and this TLSA record pins that leaf's key directly (SPKI/SHA-256, usage
3). Because the profile is DANE-EE, a client matches the served leaf against the pin and needs the per-agent CA only if it also wants to walk a PKIX path — the DNS pin alone is sufficient. - mTLS & DPoP — when an agent authenticates outbound via mutual TLS, the gateway checks the presented client cert against this same DANE pin rather than a shared CA list.
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
- Verify an agent — the full seven-proof keyless identity check TLSA is one piece of
- Per-agent CA — how the DANE pin anchors a dedicated certificate authority per identity